Skip to content

Commit

Permalink
Content scripts cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
thetarnav committed Dec 13, 2024
1 parent f40cfa2 commit fa18e24
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 149 deletions.
210 changes: 105 additions & 105 deletions packages/extension/background/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,137 +166,137 @@ let last_disconnected_tab_id: number | undefined

chrome.runtime.onConnect.addListener(async port => {
switch (port.name) {
case bridge.ConnectionName.Content: {
const tab_id = port.sender?.tab?.id
if (typeof tab_id !== 'number') break
case bridge.ConnectionName.Content: {
const tab_id = port.sender?.tab?.id
if (typeof tab_id !== 'number') break

const content_messanger = bridge.createPortMessanger(port)
const content_messanger = bridge.createPortMessanger(port)

let forwardHandler: ((message: bridge.ForwardPayload) => void) | undefined
let data: TabData
let forwardHandler: ((message: bridge.ForwardPayload) => void) | undefined
let data: TabData

const config: TabDataConfig = {
toContent: content_messanger.postPortMessage,
fromContent: content_messanger.onPortMessage,
forwardToDevtools: fn => (forwardHandler = fn),
forwardToClient: message => port.postMessage(message),
}
const config: TabDataConfig = {
toContent: content_messanger.postPortMessage,
fromContent: content_messanger.onPortMessage,
forwardToDevtools: fn => (forwardHandler = fn),
forwardToClient: message => port.postMessage(message),
}

// Page was reloaded, so we need to reinitialize the tab data
if (tab_id === last_disconnected_tab_id) {
data = last_disconnected_tab_data!
data.reconnected(config)
}
// A fresh page
else {
data = new TabData(tab_id, config)
}
// Page was reloaded, so we need to reinitialize the tab data
if (tab_id === last_disconnected_tab_id) {
data = last_disconnected_tab_data!
data.reconnected(config)
}
// A fresh page
else {
data = new TabData(tab_id, config)
}

last_disconnected_tab_id = undefined
last_disconnected_tab_id = undefined
tab_data_map.set(tab_id, data)
last_disconnected_tab_id = undefined
last_disconnected_tab_id = undefined
tab_data_map.set(tab_id, data)

// "Versions" from content-script
bridge.once(content_messanger.onPortMessage, 'Versions', v => {
data.setVersions(v)
// "Versions" from content-script
bridge.once(content_messanger.onPortMessage, 'Versions', v => {
data.setVersions(v)

// Change the popup icon to indicate that Solid is present on the page
chrome.action.setIcon({tabId: tab_id, path: icons.normal})
})

// Change the popup icon to indicate that Solid is present on the page
chrome.action.setIcon({tabId: tab_id, path: icons.normal})
})
// "DetectSolid" from content-script (realWorld)
content_messanger.onPortMessage('Detected', state => data.detected(state))

// "DetectSolid" from content-script (realWorld)
content_messanger.onPortMessage('Detected', state => data.detected(state))
port.onDisconnect.addListener(() => {
data.disconnected()
tab_data_map.delete(tab_id)
last_disconnected_tab_data = data
last_disconnected_tab_id = tab_id
})

port.onDisconnect.addListener(() => {
data.disconnected()
tab_data_map.delete(tab_id)
last_disconnected_tab_data = data
last_disconnected_tab_id = tab_id
})
port.onMessage.addListener((message: bridge.ForwardPayload | any) => {
// HANDLE FORWARDED MESSAGES FROM CLIENT (content-script)
forwardHandler && bridge.isForwardMessage(message) && forwardHandler(message)
})

port.onMessage.addListener((message: bridge.ForwardPayload | any) => {
// HANDLE FORWARDED MESSAGES FROM CLIENT (content-script)
forwardHandler && bridge.isForwardMessage(message) && forwardHandler(message)
})
break
}

case bridge.ConnectionName.Devtools: {
const data = await getActiveTabData()
if (data instanceof Error) {
error(data)
break
}
const devtools_messanger = bridge.createPortMessanger(port)

case bridge.ConnectionName.Devtools: {
const data = await getActiveTabData()
if (data instanceof Error) {
error(data)
break
}
const devtools_messanger = bridge.createPortMessanger(port)
const content_messanger = await data.untilContentScriptConnect()

const content_messanger = await data.untilContentScriptConnect()
// "Versions" means the devtools client is present
data.onVersions(v => devtools_messanger.postPortMessage('Versions', v))

// "Versions" means the devtools client is present
data.onVersions(v => devtools_messanger.postPortMessage('Versions', v))
port.onDisconnect.addListener(() => content_messanger.post('DevtoolsClosed'))

port.onDisconnect.addListener(() => content_messanger.post('DevtoolsClosed'))
break
}

case bridge.ConnectionName.Panel: {
const data = await getActiveTabData()
if (data instanceof Error) {
error(data)
break
}
const panel_messanger = bridge.createPortMessanger(port)

case bridge.ConnectionName.Panel: {
const data = await getActiveTabData()
if (data instanceof Error) {
error(data)
break
}
const panel_messanger = bridge.createPortMessanger(port)

const content_messanger = await data.untilContentScriptConnect()

data.onVersions(v => {
panel_messanger.postPortMessage('Versions', v)
// notify the content script that the devtools panel is ready
content_messanger.post('DevtoolsOpened')
})

content_messanger.on('ResetPanel', () => {
panel_messanger.postPortMessage('ResetPanel')
})
data.onContentScriptDisconnect(() => {
panel_messanger.postPortMessage('ResetPanel')
})

/* Force debugger to send state when panel conects */
data.forwardToClient({
name: 'ResetState',
details: undefined,
forwarding: true, // TODO: this shouldn't be a "forward", but not sure how to typesafe send a post to debugger from here
})

// FORWARD MESSAGES FROM and TO CLIENT
data.forwardToDevtools(message => {
port.postMessage(message)
})
panel_messanger.onForwardMessage(message => {
data.forwardToClient(message)
})
const content_messanger = await data.untilContentScriptConnect()

break
}
data.onVersions(v => {
panel_messanger.postPortMessage('Versions', v)
// notify the content script that the devtools panel is ready
content_messanger.post('DevtoolsOpened')
})

case bridge.ConnectionName.Popup: {
const data = await getActiveTabData()
if (data instanceof Error) {
error(data)
break
}
const popup_messanger = bridge.createPortMessanger(port)
content_messanger.on('ResetPanel', () => {
panel_messanger.postPortMessage('ResetPanel')
})
data.onContentScriptDisconnect(() => {
panel_messanger.postPortMessage('ResetPanel')
})

data.onVersions(v => {
popup_messanger.postPortMessage('Versions', v)
})
data.onDetected(state => {
popup_messanger.postPortMessage('Detected', state)
})
/* Force debugger to send state when panel conects */
data.forwardToClient({
name: 'ResetState',
details: undefined,
forwarding: true, // TODO: this shouldn't be a "forward", but not sure how to typesafe send a post to debugger from here
})

// FORWARD MESSAGES FROM and TO CLIENT
data.forwardToDevtools(message => {
port.postMessage(message)
})
panel_messanger.onForwardMessage(message => {
data.forwardToClient(message)
})

break
}

case bridge.ConnectionName.Popup: {
const data = await getActiveTabData()
if (data instanceof Error) {
error(data)
break
}
const popup_messanger = bridge.createPortMessanger(port)

data.onVersions(v => {
popup_messanger.postPortMessage('Versions', v)
})
data.onDetected(state => {
popup_messanger.postPortMessage('Detected', state)
})

break
}
}
})
25 changes: 19 additions & 6 deletions packages/extension/content/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,31 +38,44 @@ function loadScriptInRealWorld(path: string): Promise<void> {
script.src = chrome.runtime.getURL(path)
script.type = 'module'
script.addEventListener('error', err => reject(err))
document.head.append(script)
script.addEventListener('load', () => resolve())
document.head.append(script)
})
}

loadScriptInRealWorld(detectorPath)
.catch(err => error(`Detector_Real_World (${detectorPath}) failed to load.`, err))

/*
Message from ./detector.ts
Load Detect_Real_World script
↳ Debugger_Setup detected
↳ Load Debugger_Real_World
↳ 'Debugger_Connected' message
*/

loadScriptInRealWorld(detectorPath)
.catch(err => error(`Detector_Real_World (${detectorPath}) failed to load.`, err))

// prevent the script to be added multiple times if detected before solid
let debugger_real_world_added = false

/* from Detector_Real_World */
window.addEventListener('message', e => {
if (!e.data || typeof e.data !== 'object' || e.data.name !== bridge.DETECT_MESSAGE) return

const state = e.data.state as bridge.DetectionState

toBackground('Detected', state)

if (state.Debugger) {
/* Load Debugger_Real_World */
if (state.Debugger && !debugger_real_world_added) {
debugger_real_world_added = true

loadScriptInRealWorld(debuggerPath)
.catch(err => error(`Debugger_Real_World (${debuggerPath}) failed to load.`, err))
}
})

fromClient('ClientConnected', versions => {
fromClient('Debugger_Connected', versions => {

// eslint-disable-next-line no-console
console.log(
'🚧 %csolid-devtools%c is in early development! 🚧\nPlease report any bugs to https://github.com/thetarnav/solid-devtools/issues',
Expand Down
4 changes: 2 additions & 2 deletions packages/extension/content/debugger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function version_from_string(str: string): [Version, boolean] {
v.patch = Number(parts[2])

let ok = !isNaN(v.major) && v.major >= 0 &&
!isNaN(v.minor) && v.minor >= 0 &&
!isNaN(v.minor) && v.minor >= 0 &&
!isNaN(v.patch) && v.patch >= 0

return [v, ok]
Expand Down Expand Up @@ -83,7 +83,7 @@ warn_on_version_mismatch(debug.meta.versions.solid, debug.meta.versions.expected

// in case of navigation/page reload, reset the locator mode state in the extension
toContent('ResetPanel')
toContent('ClientConnected', debug.meta.versions)
toContent('Debugger_Connected', debug.meta.versions)

fromContent('DevtoolsOpened', () => debug.toggleEnabled(true))
fromContent('DevtoolsClosed', () => debug.toggleEnabled(false))
Expand Down
8 changes: 6 additions & 2 deletions packages/extension/content/detector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ and notify the content script
*/

import {detectSolid, onSolidDevDetect, onSolidDevtoolsDetect} from '@solid-devtools/shared/detect'
import {log} from '@solid-devtools/shared/utils'
import {log, warn} from '@solid-devtools/shared/utils'
import * as bridge from '../shared/bridge.ts'

if (import.meta.env.DEV) log('Detector_Real_World loaded.')
Expand All @@ -27,7 +27,11 @@ function postState() {

detectSolid().then(detected => {
if (import.meta.env.DEV) {
log(detected ? 'Solid detected.' : 'Solid NOT detected.')
if (detected) {
log('Solid detected.')
} else {
warn('Solid NOT detected.')
}
}
if (detected && !state.Solid) {
state.Solid = true
Expand Down
51 changes: 18 additions & 33 deletions packages/extension/devtools/devtools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,29 @@ import {error, log} from '@solid-devtools/shared/utils'
import {ConnectionName, createPortMessanger, once} from '../shared/bridge.ts'
import {icons} from '../shared/icons.ts'

log('Devtools-Script working.')
log('Devtools_Script loaded.')

// Create a connection to the background page
const port = chrome.runtime.connect({name: ConnectionName.Devtools})

const {onPortMessage: fromBackground} = createPortMessanger(port)

let panel: chrome.devtools.panels.ExtensionPanel | undefined

// "Versions" mean that devtools client is on the page
once(fromBackground, 'Versions', async () => {
if (panel) return log('Panel already exists.')

log('Solid on page – creating panel...')
try {
panel = await createPanel()
log('Panel created.')
} catch (err) {
error(err)
}
once(fromBackground, 'Versions', () => {

log('Debugger connected -> Creating Devtools_Panel...')

chrome.devtools.panels.create(
'Solid',
// Firefox requires absolute path
(import.meta.env.BROWSER === 'firefox' ? '/' : '') + icons.disabled[32],
'index.html',
() => {
if (chrome.runtime.lastError) {
error('Creating Devtools_Panel Failed', chrome.runtime.lastError)
} else {
log('Devtools_Panel created.')
}
},
)
})

const createPanel = () =>
new Promise<chrome.devtools.panels.ExtensionPanel>((resolve, reject) => {
const onCreate = (newPanel: chrome.devtools.panels.ExtensionPanel) => {
if (chrome.runtime.lastError) reject(chrome.runtime.lastError)
else resolve(newPanel)
}

if (import.meta.env.BROWSER === 'firefox') {
chrome.devtools.panels.create(
'Solid',
/* firefox requires absolute paths */
'/' + icons.disabled[32],
'/index.html',
onCreate,
)
} else {
chrome.devtools.panels.create('Solid', icons.disabled[32], 'index.html', onCreate)
}
})
Loading

0 comments on commit fa18e24

Please sign in to comment.