From c1838240f0ca606b25ce07da759fae1ee00d35c5 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Sat, 3 Aug 2024 10:21:36 -0400 Subject: [PATCH] Start work --- extension/chrome/manifest.json | 2 +- .../src/background/store/apiMiddleware.ts | 22 +++++----- extension/src/devpanel/devpanel.pug | 6 +++ extension/src/devpanel/index.tsx | 28 +++++++++---- .../src/devpanel/store/panelSyncMiddleware.ts | 40 ++++++++++++++++--- extension/src/window/window.pug | 2 +- 6 files changed, 71 insertions(+), 29 deletions(-) diff --git a/extension/chrome/manifest.json b/extension/chrome/manifest.json index 69b3f14a..aedfd674 100644 --- a/extension/chrome/manifest.json +++ b/extension/chrome/manifest.json @@ -7,7 +7,7 @@ "page_action": { "default_icon": "img/logo/gray.png", "default_title": "Redux DevTools", - "default_popup": "window.html#popup" + "default_popup": "devpanel.html#popup" }, "commands": { "devtools-left": { diff --git a/extension/src/background/store/apiMiddleware.ts b/extension/src/background/store/apiMiddleware.ts index e88c841b..78deaceb 100644 --- a/extension/src/background/store/apiMiddleware.ts +++ b/extension/src/background/store/apiMiddleware.ts @@ -261,22 +261,18 @@ type MonitorAction> = // Chrome message limit is 64 MB, but we're using 32 MB to include other object's parts const maxChromeMsgSize = 32 * 1024 * 1024; +// TODO Clean up args function toMonitors>( action: MonitorAction, tabId?: string | number, verbose?: boolean, ) { - for (const monitorPort of Object.values(connections.monitor)) { - monitorPort.postMessage( - verbose || action.type === 'ERROR' || action.type === SET_PERSIST - ? action - : { type: UPDATE_STATE }, - ); - } - - for (const panelPort of Object.values(connections.panel)) { + for (const port of [ + ...Object.values(connections.monitor), + ...Object.values(connections.panel), + ]) { try { - panelPort.postMessage(action); + port.postMessage(action); } catch (err) { if ( action.type !== UPDATE_STATE || @@ -307,11 +303,11 @@ function toMonitors>( value; } - panelPort.postMessage({ ...action, request: splitMessageStart }); + port.postMessage({ ...action, request: splitMessageStart }); for (let i = 0; i < toSplit.length; i++) { for (let j = 0; j < toSplit[i][1].length; j += maxChromeMsgSize) { - panelPort.postMessage({ + port.postMessage({ ...action, request: { split: 'chunk', @@ -324,7 +320,7 @@ function toMonitors>( } } - panelPort.postMessage({ ...action, request: { split: 'end' } }); + port.postMessage({ ...action, request: { split: 'end' } }); } } } diff --git a/extension/src/devpanel/devpanel.pug b/extension/src/devpanel/devpanel.pug index bf5105d3..a4e1a741 100644 --- a/extension/src/devpanel/devpanel.pug +++ b/extension/src/devpanel/devpanel.pug @@ -12,5 +12,11 @@ html body #root + div(style='position: relative') + img( + src='/img/loading.svg', + height=300, width=350, + style='position: absolute; top: 50%; left: 50%; margin-top: -150px; margin-left: -175px;' + ) link(href='/devpanel.bundle.css', rel='stylesheet') script(src='/devpanel.bundle.js') diff --git a/extension/src/devpanel/index.tsx b/extension/src/devpanel/index.tsx index 34271f84..538f4db8 100644 --- a/extension/src/devpanel/index.tsx +++ b/extension/src/devpanel/index.tsx @@ -23,9 +23,10 @@ import { PersistGate } from 'redux-persist/integration/react'; const position = location.hash; const messageStyle: CSSProperties = { - padding: '20px', + paddingTop: '20px', width: '100%', textAlign: 'center', + boxSizing: 'border-box', }; let rendered: boolean | undefined; @@ -72,7 +73,12 @@ function renderNA() { . ); - if (isChrome) { + if ( + isChrome && + chrome && + chrome.devtools && + chrome.devtools.inspectedWindow + ) { chrome.devtools.inspectedWindow.getResources((resources) => { if (resources[0].url.substr(0, 4) === 'file') { message = ( @@ -101,17 +107,20 @@ function renderNA() { let splitMessage: SplitUpdateStateRequest>; -function init(id: number) { +function init() { renderNA(); - bgConnection = chrome.runtime.connect({ - name: id ? id.toString() : undefined, - }); + let name = 'monitor'; + if (chrome && chrome.devtools && chrome.devtools.inspectedWindow) { + name += chrome.devtools.inspectedWindow.tabId; + } + bgConnection = chrome.runtime.connect({ name }); bgConnection.onMessage.addListener( >( message: PanelMessageWithSplitAction, ) => { if (message.type === 'NA') { - if (message.id === id) renderNA(); + // TODO Double-check this now that the name is different + if (message.id === name) renderNA(); else store!.dispatch({ type: REMOVE_INSTANCE, id: message.id }); } else { if (!rendered) renderDevTools(); @@ -157,4 +166,7 @@ function init(id: number) { ); } -init(chrome.devtools.inspectedWindow.tabId); +if (position === '#popup') document.body.style.minWidth = '760px'; +if (position !== '#popup') document.body.style.minHeight = '100%'; + +init(); diff --git a/extension/src/devpanel/store/panelSyncMiddleware.ts b/extension/src/devpanel/store/panelSyncMiddleware.ts index 278aef75..cccb479d 100644 --- a/extension/src/devpanel/store/panelSyncMiddleware.ts +++ b/extension/src/devpanel/store/panelSyncMiddleware.ts @@ -7,23 +7,51 @@ import { TOGGLE_PERSIST, UPDATE_STATE, } from '@redux-devtools/app'; -import { Dispatch, Middleware } from 'redux'; +import { Dispatch, Middleware, MiddlewareAPI } from 'redux'; + +function selectInstance( + tabId: number, + store: MiddlewareAPI, StoreState>, + next: (action: unknown) => unknown, +) { + const instances = store.getState().instances; + if (instances.current === 'default') return; + const connections = instances.connections[tabId]; + if (connections && connections.length === 1) { + next({ type: SELECT_INSTANCE, selected: connections[0] }); + } +} + +function getCurrentTabId(next: (tabId: number) => void) { + chrome.tabs.query( + { + active: true, + lastFocusedWindow: true, + }, + (tabs) => { + const tab = tabs[0]; + if (!tab) return; + next(tab.id!); + }, + ); +} function panelDispatcher( bgConnection: chrome.runtime.Port, ): Middleware<{}, StoreState, Dispatch> { let autoselected = false; - const tabId = chrome.devtools.inspectedWindow.tabId; return (store) => (next) => (untypedAction) => { const action = untypedAction as StoreAction; const result = next(action); - if (!autoselected && action.type === UPDATE_STATE && tabId) { + if (!autoselected && action.type === UPDATE_STATE) { autoselected = true; - const connections = store.getState().instances.connections[tabId]; - if (connections && connections.length === 1) { - next({ type: SELECT_INSTANCE, selected: connections[0] }); + + if (chrome.devtools && chrome.devtools.inspectedWindow) { + selectInstance(chrome.devtools.inspectedWindow.tabId, store, next); + } else { + getCurrentTabId((tabId) => selectInstance(tabId, store, next)); } } if (action.type === LIFTED_ACTION || action.type === TOGGLE_PERSIST) { diff --git a/extension/src/window/window.pug b/extension/src/window/window.pug index efda47db..10f1009c 100644 --- a/extension/src/window/window.pug +++ b/extension/src/window/window.pug @@ -12,7 +12,7 @@ html img( src='/img/loading.svg', height=300, width=350, - style='position: absolute; top: 50%; left: 50%; margin-top: -175px; margin-left: -175px;' + style='position: absolute; top: 50%; left: 50%; margin-top: -150px; margin-left: -175px;' ) link(href='/window.bundle.css', rel='stylesheet') script(src='/window.bundle.js')