# Chrome DevTools 'Sources' Extension Originally articulated here: - https://github.com/j4k0xb/webcrack/issues/29 - > add Chrome DevTools extension that allows the web IDE to be used within DevTools - https://github.com/pionxzh/wakaru/issues/76 - > add Chrome DevTools extension that allows the web IDE to be used within DevTools ## Table of Contents - [Overview](#overview) - [Original Notes](#original-notes) - [Notes from chat with Chris (December 2024)](#notes-from-chat-with-chris-december-2024) ## Overview ### Original Notes The following is as I originally wrote it on the above issues, copied here for posterity: > First off, I LOVE the new [v2.11.0](https://github.com/j4k0xb/webcrack/releases/tag/v2.11.0) update, and the changes to the web IDE to use monaco to support 'references', 'go to declaration', etc. > > This issue is about an idea I've had and wanted to work on myself for a while, but haven't got around to it yet. Often when exploring web apps, I make pretty heavy use of Chrome DevTools' ['Search'](https://developer.chrome.com/docs/devtools/search/) / ['Sources'](https://developer.chrome.com/docs/devtools/sources) / ['Network'](https://developer.chrome.com/docs/devtools/network/) / etc tabs, the [debugger](https://developer.chrome.com/docs/devtools/javascript/reference/), and the [console](https://developer.chrome.com/docs/devtools/console/api) / [utilities](https://developer.chrome.com/docs/devtools/console/utilities) APIs. While there have been some nice improvements to the 'Sources' tab over the years (pretty printing, syntax highlighting, code folding, etc); one area I have really wished it was able to support for a long time now is 'references' / 'go to definition' / similar. > > A thought I had in this space is that, while I obviously can't outright replace the 'Sources' tab (which I believe is based on [CodeMirror](https://codemirror.net/)), it should be possible to create a Chrome DevTools Extension that adds a new tab/panel that does similar to the current 'Sources' tab, but using `monaco` as it's base, and enabling features like 'references' / 'go to definition' / etc within that. > > ### Useful Chrome Extension APIs > > Overview of extending DevTools: > > - https://developer.chrome.com/docs/extensions/how-to/devtools/extend-devtools > - > Extending DevTools > > DevTools extensions add functionality to Chrome DevTools by accessing DevTools-specific extension APIs through a DevTools page added to the extension. > > Some of the Chrome Extension API's that would be useful/enable this: > > - https://developer.chrome.com/docs/extensions/reference/api/devtools/inspectedWindow > - > Use the `chrome.devtools.inspectedWindow` API to interact with the inspected window: obtain the tab ID for the inspected page, evaluate the code in the context of the inspected window, reload the page, or obtain the list of resources within the page. > - > Use the `getResources` call and the `onResourceContent` event to obtain the list of resources (documents, stylesheets, scripts, images etc) within the inspected page. The `getContent` and `setContent` methods of the `Resource` class along with the `onResourceContentCommitted` event may be used to support modification of the resource content, for example, by an external editor. > - https://developer.chrome.com/docs/extensions/reference/api/devtools/inspectedWindow#executing-code > - > The execution context of the code being evaluated includes the [Developer Tools console API](https://developers.google.com/web/tools/chrome-devtools/). For example, the code can use `inspect` and `$0`. > - https://developer.chrome.com/docs/extensions/reference/api/devtools/inspectedWindow#method-eval > - > Evaluates a JavaScript expression in the context of the main frame of the inspected page. > - This can also be used to target different `frameURL`s, different `scriptExecutionContext`s, etc > - https://developer.chrome.com/docs/extensions/reference/api/devtools/inspectedWindow#method-getResources > - > Retrieves the list of resources from the inspected page. > - https://developer.chrome.com/docs/extensions/reference/api/devtools/inspectedWindow#type-Resource > - > A resource within the inspected page, such as a document, a script, or an image. > - > `getContent`: Gets the content of the resource. (potentially encoded, Currently, only base64 is supported.). > - > `setContent`: Sets the content of the resource. Only resources with the text type are currently supported. > - https://developer.chrome.com/docs/extensions/reference/api/devtools/inspectedWindow#method-reload > - > Reloads the inspected page. > - The most interesting part of this API is probably `reloadOptions` -> `injectedScript` (though `userAgent` might be useful sometimes too): > - > `injectedScript`: If specified, the script will be injected into every frame of the inspected page immediately upon load, before any of the frame's scripts. > - > `userAgent`: If specified, the string will override the value of the User-Agent HTTP header that's sent while loading the resources of the inspected page. The string will also override the value of the `navigator.userAgent` property that's returned to any scripts that are running within the inspected page. > - https://developer.chrome.com/docs/extensions/reference/api/devtools/inspectedWindow#event-onResourceAdded > - > Fired when a new resource is added to the inspected page. > - https://developer.chrome.com/docs/extensions/reference/api/devtools/inspectedWindow#event-onResourceContentCommitted > - > Fired when a new revision of the resource is committed (e.g. user saves an edited version of the resource in the Developer Tools). > - https://developer.chrome.com/docs/extensions/reference/api/devtools/panels > - > Use the `chrome.devtools.panels` API to integrate your extension into Developer Tools window UI: create your own panels, access existing panels, and add sidebars. > - https://developer.chrome.com/docs/extensions/reference/api/devtools/panels#type-SourcesPanel > - > Represents the Sources panel > - I hadn't stumbled upon this before, but it sounds like it's possible to access the existing 'Sources' panel; can react to 'when an object is selected in the panel' (not sure what 'object' refers to in this case), can create a sidebar pane, etc > - https://developer.chrome.com/docs/extensions/reference/api/devtools/panels#method-create > - > Creates an extension panel > - This was my main original thought, in creating a new custom panel > - https://developer.chrome.com/docs/extensions/reference/api/devtools/panels#method-openResource > - > Requests DevTools to open a URL in a Developer Tools panel. > - Can seemingly be used to interact with existing panels > - https://developer.chrome.com/docs/extensions/reference/api/devtools/panels#method-setOpenResourceHandler > - > Specifies the function to be called when the user clicks a resource link in the Developer Tools window. To unset the handler, either call the method with no parameters or pass null as the parameter. > - https://developer.chrome.com/docs/extensions/reference/api/devtools/network > - Use the `chrome.devtools.network` API to retrieve the information about network requests displayed by the Developer Tools in the Network panel. > - Probably less specifically relevant to the functionality I was thinking of, but could be some value/crossover there, so figured I'd mention it. `onNavigated` / `onRequestFinished` might be useful in some cases. > - https://developer.chrome.com/docs/extensions/reference/api/devtools/recorder > - > Use the `chrome.devtools.recorder` API to customize the Recorder panel in DevTools. > > `devtools.recorder` API is a preview feature that allows you to extend the [Recorder panel](https://developer.chrome.com/docs/devtools/recorder) in Chrome DevTools. > - Again, probably not as useful, but linking here in case. > - https://developer.chrome.com/docs/extensions/reference/api/debugger > - > The `chrome.debugger` API serves as an alternate transport for Chrome's [remote debugging protocol](https://developer.chrome.com/devtools/docs/debugger-protocol). Use `chrome.debugger` to attach to one or more tabs to instrument network interaction, debug JavaScript, mutate the DOM and CSS, etc. > - > For security reasons, the `chrome.debugger` API does not provide access to all Chrome DevTools Protocol Domains. The available domains are: [Accessibility](https://chromedevtools.github.io/devtools-protocol/tot/Accessibility), [Audits](https://chromedevtools.github.io/devtools-protocol/tot/Audits), [CacheStorage](https://chromedevtools.github.io/devtools-protocol/tot/CacheStorage), [Console](https://chromedevtools.github.io/devtools-protocol/tot/Console), [CSS](https://chromedevtools.github.io/devtools-protocol/tot/css), [Database](https://chromedevtools.github.io/devtools-protocol/tot/Database), [Debugger](https://chromedevtools.github.io/devtools-protocol/tot/Debugger), [DOM](https://chromedevtools.github.io/devtools-protocol/tot/DOM), [DOMDebugger](https://chromedevtools.github.io/devtools-protocol/tot/DOMDebugger), [DOMSnapshot](https://chromedevtools.github.io/devtools-protocol/tot/DOMSnapshot), [Emulation](https://chromedevtools.github.io/devtools-protocol/tot/Emulation), [Fetch](https://chromedevtools.github.io/devtools-protocol/tot/Fetch), [IO](https://chromedevtools.github.io/devtools-protocol/tot/IO), [Input](https://chromedevtools.github.io/devtools-protocol/tot/Input), [Inspector](https://chromedevtools.github.io/devtools-protocol/tot/Inspector), [Log](https://chromedevtools.github.io/devtools-protocol/tot/Log), [Network](https://chromedevtools.github.io/devtools-protocol/tot/Network), [Overlay](https://chromedevtools.github.io/devtools-protocol/tot/Overlay), [Page](https://chromedevtools.github.io/devtools-protocol/tot/Page), [Performance](https://chromedevtools.github.io/devtools-protocol/tot/Performance), [Profiler](https://chromedevtools.github.io/devtools-protocol/tot/Profiler), [Runtime](https://chromedevtools.github.io/devtools-protocol/tot/Runtime), [Storage](https://chromedevtools.github.io/devtools-protocol/tot/Storage), [Target](https://chromedevtools.github.io/devtools-protocol/tot/Target), [Tracing](https://chromedevtools.github.io/devtools-protocol/tot/Tracing), [WebAudio](https://chromedevtools.github.io/devtools-protocol/tot/WebAudio), and [WebAuthn](https://chromedevtools.github.io/devtools-protocol/tot/WebAuthn). > - This can do all sorts of powerful stuff, though some of the original reasons I was thinking of needing to use it (eg. getting access to the page's script contents/etc) are apparently already covered in other more specific APIs (eg. `chrome.devtools.inspectedWindow`). Still worth being aware of it and the features it has though, as there is some pretty cool stuff here! > - https://chromedevtools.github.io/devtools-protocol/ > > Then there are also all of the 'standard' Chrome Extension APIs as well, which can do a lot of cool stuff: > > - https://developer.chrome.com/docs/extensions/reference/api > > A few of which could be useful for this feature: > > - https://developer.chrome.com/docs/extensions/reference/api/runtime > - > Use the `chrome.runtime` API to retrieve the service worker, return details about the manifest, and listen for and respond to events in the app or extension lifecycle. You can also use this API to convert the relative path of URLs to fully-qualified URLs. > - Some more esotetic, but interesting aspects of this, are the ability to communicate with other externsions and/or locally installed programs using `connect` / `onConnectExternal` / `onMessageExternal` / `connectNative` / `sendMessageNative`: > - https://developer.chrome.com/docs/extensions/reference/api/runtime#method-connect > - > Attempts to connect listeners within an extension/app (such as the background page), or other extensions/apps. This is useful for content scripts connecting to their extension processes, inter-app/extension communication, and [web messaging](https://developer.chrome.com/docs/extensions/manifest/externally_connectable). Note that this does not connect to any listeners in a content script. Extensions may connect to content scripts embedded in tabs via [`tabs.connect`](https://developer.chrome.com/docs/extensions/reference/tabs/#method-connect). > - https://developer.chrome.com/docs/extensions/reference/api/runtime#event-onConnectExternal > - > Fired when a connection is made from another extension (by [`runtime.connect`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-connect)). > - https://developer.chrome.com/docs/extensions/reference/api/runtime#event-onMessageExternal > - > Fired when a message is sent from another extension/app (by [`runtime.sendMessage`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-sendMessage)). > - https://developer.chrome.com/docs/extensions/reference/api/runtime#method-connectNative > - > Connects to a native application in the host machine. See [Native Messaging](https://developer.chrome.com/docs/extensions/nativeMessaging) for more information. > - https://developer.chrome.com/docs/extensions/reference/api/runtime#method-sendNativeMessage > - > Send a single message to a native application. > - https://developer.chrome.com/docs/extensions/reference/api/runtime#event-onConnectNative > - > Fired when a connection is made from a native application. Currently only supported on Chrome OS. > - While this is only supported from Chrome OS, I believe the browser can always initiate the connection to a native app. > - https://developer.chrome.com/docs/extensions/reference/api/permissions > - > Use the `chrome.permissions` API to request [declared optional permissions](https://developer.chrome.com/docs/extensions/mv3/declare_permissions/) at run time rather than install time, so users understand why the permissions are needed and grant only those that are necessary. > - https://developer.chrome.com/docs/extensions/reference/api/contextMenus > - > Use the `chrome.contextMenus` API to add items to Google Chrome's context menu. You can choose what types of objects your context menu additions apply to, such as images, hyperlinks, and pages. > - https://developer.chrome.com/docs/extensions/reference/api/sidePanel > - > Use the `chrome.sidePanel` API to host content in the browser's side panel alongside the main content of a webpage. > - https://developer.chrome.com/docs/extensions/reference/api/storage > - > Use the `chrome.storage` API to store, retrieve, and track changes to user data. > > The Storage API provides an extension-specific way to persist user data and state. It's similar to the web platform's storage APIs ([IndexedDB](https://developer.mozilla.org/docs/Web/API/Window/indexeddb), and [Storage](https://developer.mozilla.org/docs/Web/API/Storage)), but was designed to meet the storage needs of extensions. > - https://developer.chrome.com/docs/extensions/reference/api/notifications > - Use the `chrome.notifications` API to create rich notifications using templates and show these notifications to users in the system tray. > > And some that are a little more esoteric, but might still be interesting/useful: > > - https://developer.chrome.com/docs/extensions/reference/api/scripting > - > Use the `chrome.scripting` API to execute script in different contexts. > - https://developer.chrome.com/docs/extensions/reference/api/userScripts > - > Use the `userScripts` API to execute user scripts in the User Scripts context. > - https://developer.chrome.com/docs/extensions/reference/api/webNavigation > - > Use the `chrome.webNavigation` API to receive notifications about the status of navigation requests in-flight. > - https://developer.chrome.com/docs/extensions/reference/api/offscreen > - > Use the `offscreen` API to create and manage offscreen documents. ### Notes from chat with Chris (December 2024) The following are relevant snippets from a Messenger chat with Chris M in December 2024: > **Chris M (11:46AM):** > I wanna build a better debugger for the browser too, but the only way to build it would be to have a deep overall understanding of js and the DOM that no human can hold in their head all at once > **Glenn (11:47AM):** > What sort of ‘better debugger’ features would you be wanting? > **Chris M (11:47AM):** > Not features, just an entirely new way of debugging > **Chris M (11:48AM):** > I had some ways I wanted to implement it before but my memory is all fuzzy now so it's easier just to explain the goal > **Chris M (11:49AM):** > Basically it wouldn't be possible to obfuscate anything in the first place, because everything would be super open and high level in the first place > **Chris M (11:49AM):** > I had some ways I wanted to implement it before but my memory is all fuzzy now so it's easier just to explain the goal > **Chris M (11:50AM):** > So like if you stripped the semantics, it wouldn't do anything, because you can always see a high level interpretation of what's being changed > **Glenn (11:51AM):** > Maybe slightly lower level/more detailed than that description :p > > “Basically stuff with things and therefore magic!” > **Chris M (12:14PM):** > Ok so say youtube makes a request for a video. But the way it does that is through m3u streams chunked up, and then you place a breakpoint on it, you find all the js is chunked too, and then if you trace it you're left with like `f(c,y,u)`, and this splits off into 16 different branches, none of which individually explain what's going on, some of which are. > > What I want is for it to be inherently interpretable based on what it's actually doing, like part of it is that it does this handshake to google auth servers and weird cypher stuff with a thing called sapisidhash in the background. You wouldn't necessarily know looking at the minified code, cos all you see is a bunch of ints being passed around, but on a higher level, the DOM knows, because it has the full context and knows it's calling crypto libraries, so it could be named based on what it's actually doing, and then you can developers can still alias that on top with their own naming schemes. > I wanna see this visually at every step as well. You should be able to literally walk through it and see the information being transferred more intuitively. Maybe like a node graph, but also it should be directly connected to the dom too. > > Like if pressing a button interacts with some other element on the page, I want to see the path connecting them and be able to intercept it on the page itself instead of going in and out of the debugger and trying to make sure I've got a hold of the right thing. > **Chris M (12:14PM):** > It's hard to explain what I mean without just describing a debugger > > Tech bros reinventing the wheel > **Glenn (12:33PM):** > Nah, I def followed some of that at least > **Chris M (12:35PM):** > Like if you take the sapisidhash example, you might say "but how can the interpreter work out that you're building some niche auth system due to the math you're doing", but the thing is, an LLM can work it out even if you remove the semantics, because it can understand the context and how that structure fits into it. If you had autocomplete on, it would probably just name it something like `auth_hash_verifier()` for you. > > So surely you could take extra steps to make that even more robust by specifically designing a js engine for interpretability. > **Glenn (12:36PM):** > Like some bits of this feel a bit ‘high level dream’ and good luck implementing it; but also AI definitely makes to far more likely to be achievable than it would have been in the past. > > But other parts of this are definitely more in the tangible space of things that I have definitely wanted in the past; like particularly getting from button on page -> the _actual_ click handler for it, without just being directed to some convoluted nested layer of react’s internal handlers or similar; or having to know that I can access the react fibre via that DOM nodes properties and then access funky things from it that way; or that I have react devtools installed and it magically does something to make it easier for me to get that. > > I feel like for at least some of what you described there are already tools and methods for it; they aren’t just all in one place but (eg. You’d need react devtools and angular devtools and xyzfoobar devtools, and sometimes there isn’t an appropriate devtools) > **Glenn (12:37PM):** > One thing I’ve wanted and been thinking of building forever is just a mashup of the chrome devtools sources tab with an actual useful IDE implementation (Monaco), so that I can jump around the variable references like I’m in an actual IDE. > > And yeah I can probably just connect to it from my IDE as a debugger; but I never remember how to do that for my own code let alone a random website; so I want it accessible straight from chrome devtools sources all I need to remember is ‘right click on page then hack shit’ > **Glenn (12:39PM):** > And I’ve looked into it, and the chrome extension API’s seem to have everything I need to access that stuff; and can create devtools panels and could embed Monaco in that. So it’s just a case of me actually playing around and doing it > **Glenn (12:39PM):** > Then next step from there is to add wakaru into the mix, so I can go from “right click devtools” to “oh look, pretty deminified” > **Glenn (12:39PM):** > And then my vision gets hazier from there; but I suspect I would add some nice features for easily allowing me to call into the devtools debug hook/monitor functions to more easily/precisely target things; and/or to allow me to add proxies to monitor/override various things on the fly monkey patch style > **Glenn (12:40PM):** > Basically all stuff I can kind of already do based on existing tools + stuff I figured out and documented in gists and such; but I want it all in 1 place relying on code and gui rather than my memory of how to do things > **Glenn (12:42PM):** > Also being able to see module import graph overview (which can already be done with tools like madge/etc) > **Glenn (12:43PM):** > And then go deeper into the module fingerprinting stuff I’ve started exploring on wakaru repo + building a database of open source libraries fingerprints for that so it can basically be like 85% of this bundle is just the following libs/versions, and here is the bit that’s actually unique and interesting > **Chris M (12:43PM):** > Yeah that's basically what I mean > Also it's not like any of these tools talk to each other > It's a whole ass project > **Glenn (12:44PM):** > Yeah; one of my annoyances of security tools and I guess tools in general. > > Everyone reinvents the wheel with a slightly different slice of functionality; or language of implementation or similar > **Glenn (12:45PM):** > > It's a whole ass project > > It is. But it’s one that depending on the nuance of what you wants; you can take standalone steps towards it. > > That’s what I do with my gists and deep dive issues and similar; basically do some of the reverse engineering or research or similar and cache that for others or future me. > > A lot of my issue contributions on wakaru have been minimising the effort they need to go from an idea I want to it being implemented without me having to be the one that wrote the code, etc > **Glenn (12:46PM):** > This + a more generalised and cleaned up/automated version of the tooling I was building out for ChatGPT-source-watch are still 2 projects I want to hack on and make available open source; as while I haven’t looked properly in ages, I feel like this area of tooling is still super shit for no good reason in the web app security space; and I’ve thought it could be done better for years now > **Glenn (12:47PM):** > There’s so much interesting stuff the devtools protocol / debugger gives you access to that we barely scratch the surface of using. > > Hell, even i regularly find ways i can be more effective in using the debugger in devtools just as it is > **Glenn (12:51PM):** > > Like if you take the sapisidhash example, you might say "but how can the interpreter work out that you're building some niche auth system due to the math you're doing", but the thing is, an LLM can work it out > > Mm, maybe. But I guess at least with current codebase sizes and inference speed/cost/etc it would probably be overkill/slow AF to try and figure that out in a global scale. > > If I was approaching it I would more build human in the loop assistance tools. So like, understand the bundle, identify known modules, basically do all the basic normal AST/etc non LLM things to reduce the noise/be able to provide better context; and then provide easy tools to allow the human to be like “wtf is this chunk of weird math stuff, grab all the relevant context and throw it to an LLM and tell me what it is” > **Glenn (12:54PM):** > Then I guess if you wanted to add an open source layer to that; you could take the same concept of ‘source code fingerprinting’ and module identification that I described earlier for open source libs; but allow users to contribute it for arbitrary code as well. Then say one day Chris decides to try and hack YouTube and makes the LLM figure out that chunk of code does some crypto BS; and then he submits that fingerprint + ‘smart prettied naming’ to this open database; and then Glenn decides he wants to hack it one day and the tool is like “oh, that code seems like a close match to this thing Chris already spent time figuring out, do you want to just apply that?” > **Glenn (12:54PM):** > To a basic degree, and manually, that’s what I already do a lot of the time with identifying open source libs by just grabbing keywords from them and using GitHub code search > **Chris M (12:56PM):** > Oh that's a good idea > Anyway yea > All of this is a lot of work > and a lot of stuff to work out on the way > It's a sick idea but realistically I'm probably not gonna do it > Even if o5-mini got me close though it'd be worth the investment > Wouldn't mind waiting a week or a month for it even > **Glenn (12:58PM):** > You’ve got g1988 on it; but it’s an unreliable model with a lot of contention for its compute resources and so it could be anywhere from days to years to see an outcome :p > **Glenn (1:00PM):** > But yeah; it’s the type of project I would probably happily collab on if I trusted the other person to actually stick with it > **Glenn (1:01PM):** > Or like.. not even ‘stick with it’ per se; but just like.. get to some tangible lasting level of something and not just talk about dreams and then never come back to it type vibe > **Chris M (1:02PM):** > I can't even trust myself to stick with things Im heavily invested in but yeah if you find someone before LLMs are this capable feel free to run with it and id probably contrib to some degree > > It was more concrete about a year ago, I think im just making shit up now that was loosely based on it and overwriting stuff that was better originally > **Glenn (1:06PM):** > I mean, eventually I’ll do the things I said above myself. > > And there’s this Canadian kid I’ve been vaguely half mentoring/giving feedback to on twitter occasionally who has been hacking in similar spaces and been playing with building out a lot of the types of tooling/solutions I was hacking on for ChatGPT-source-watch. So hopefully can get him to share back some of what he’s built eventually. > > He’s also similarly hard to consistently motivate on things though; so it’s more of an ‘opportunistic if it happens to align’ type vibe > **Glenn (1:10PM):** > > I can't even trust myself to stick with things Im heavily invested in... > > Like, even if you have cool ideas in that space, and some vague snippets of steps towards how you might implement it; and can be fucked writing that out in some vaguely tangible way; I find even that kind of stuff useful. > > Like I’ll add it to a gist of collected ideas around this sort of thing and then use that as a source of remembering/motivating/etc when I do decide to hack on it > **Chris M (1:10PM):** > I worked with triex on some website he was getting paid for a while back and it was a hard problem, probably would have never been fucked to do it myself > But I was like "oh thats easy, you just" and he was like nah I tried that > And then it became this whole rabbithole I spent ages on and eventually cracked > But like if I dedicated myself to doing that just for it's own sake I would've never done it, prob even less motivating if i was getting paid for it cos then id HAVE to > **Glenn (1:11PM):** > > It was more concrete about a year ago, I think im just making shit up now... > > Well, let it sit in the back of your mind and if you do come up with an idea that seems good; document some measure of it in a way that we can refer back to it later. > > One reason I like the gists is its minimal effort, tracks history, and is public so even if I never get back to it, someone might benefit from the effort I put in. > **Glenn (1:11PM):** > > But I was like "oh thats easy, you just" and he was like nah I tried that > > Honestly that’s the kind of people and situations I enjoy working on the most. > > Solving problems on my own is fine; but being able to bounce ideas between smart people to make cool shit is infinitely better and way easier to stay motivated on > **Glenn (1:25PM):** > For your react click event handler stuff; I would potentially be looking at the react fibre properties on the DOM node; as you can access the props of the components from there and all sorts of fun stuff like that. > > On one of my gists I have some hacky snippets of code for animating the nodes that have react fibres and such > **Glenn (1:29PM):** > > And I’ve looked into it, and the chrome extension API’s seem to have everything I need to access that stuff; and can create devtools panels and could embed Monaco in that. So it’s just a case of me actually playing around and doing it > > A paid contracting project I’ve been hacking in recently uses Monaco; so it’s given me an opportunity to build some knowledge in that space that will make starting this project seem less ‘dauntingly unknown’ when I do get around to it > **Chris M (1:37PM):** > I think I tried that > Basically it needed to save the prior element state > in some react specific way > And then check the last set value before updating it again > Seems like it doesn't always work this way though, it worked for Udio and a few things on facebook reels > Othertimes it does nothing and then react props will do it or a `.click()` will do it > It's kinda dumb that we can't just see what it's doing up front > I miss when you could just look at the onclick property and know everything there was to it > **Glenn (3:49PM):** > > I miss when you could just look at the onclick property... > > Same > > > It's kinda dumb that we can't just see what it's doing up front > > Though tbh this part is probably just a skill/tooling issue. > > I’m sure that once you know how to find that info easily it’ll be pretty straightforward. It’s just that it’s not natively built into the chrome devtools; and it’s not really a supported feature to dig into and hijack react handlers from outside of react. > > Like in theory for manual dev look at things stuff; react devtools does this perfectly fine. > > It’s just that we’re wanting to programmatically hijack stuff that it gets weirder/harder > > Like I can’t remember exactly off the top of my head, but to think even native chrome devtools gives me somewhat useful feedback on this stuff when I remember to filter things appropriately > **Glenn (8:54PM):** > Tangent: here’s the section of one of my gists with some of the snippets/etc related to reading react fibers/etc: > > https://gist.github.com/0xdevalias/8c621c5d09d780b1d321bfdb86d67cdd#react-internals > > (Also some vaguely similar bits for other frameworks on that gist too) > **Glenn (10:00PM):** > So that chrome event listeners tab just sees a noop handler because react uses a synthetic event handling system. ChatGPT’s response wasn’t super definitive, but I think the noop handler is there for some quirks/edgecases (either browser reasons; or maybe dev/stubbed out in prod reasons) > **Glenn (10:29PM):** > Skimming some docs on react events; this indirectly mentions the higher level overview of how the synthetic event system runs down then up: https://react.dev/learn/responding-to-events#capture-phase-events > **Glenn (10:38PM):** > Then skimming some other articles that are barely worth linking; react uses synthetic events that wrap native events basically for cross browser compatibility reasons; it uses the single listener ‘event delegation’ pattern for performance reasons, it used to pool and reuse event objects for performance reasons but doesn’t do that anymore since react 17 (https://legacy.reactjs.org/docs/legacy-event-pooling.html) because modern browsers suck less so it doesn’t improve performance anymore and also it confused even experienced react users; etc > **Glenn (10:40PM):** > Earlier versions of react bound event listeners to document; event delegation was disabled by default in react 17; react 18 did something to change that again to be better and more flexible somehow (https://markovate.com/blog/react-18-update/#:~:text=Changes%20to%20Event%20Delegation) > **Glenn (10:41PM):** > They also batch various events together to reduce the number of re-renders: https://react.dev/blog/2022/03/29/react-v18#new-feature-automatic-batching > > https://github.com/reactwg/react-18/discussions/21 > **Glenn (10:53PM):** > A bit more of the internals of the synthetic event and its parent classes/prototype: https://dev.to/grantcloyd/examining-react-s-synthetic-event-the-nativeevent-the-eventphase-and-bubbling-549k?utm_source=chatgpt.com#:~:text=Pulling%20Back%20the%20Curtain > **Glenn (10:55PM):** > And then this stuff about the event phases and bubbling: https://dev.to/grantcloyd/examining-react-s-synthetic-event-the-nativeevent-the-eventphase-and-bubbling-549k?utm_source=chatgpt.com#:~:text=event.eventPhase%20and%20Bubbling > **Glenn (10:59PM):** > Seemingly the pooling was related to object creation/removal and garbage collection issues from frequently doing that for high frequency events > **Glenn (11:01PM):** > Can look at `e.target` and `e.currentTarget` to see which element the event innovated from vs the one where the event handler is bound > **Glenn (11:05PM):** > Back to the event listener tab; if I tick the checkbox to show all ancestors > > The bottom one attached to the button is the react `noop`. > > One up is `dispatchDiscreteEvent` > > One up is `dispatchDiscreteEvent` again > > Then one up from that is `noop` > > And then one up again isn’t react related but just sort of this code sandbox sites native code > **Glenn (11:10PM):** > And `dispatchDiscreteEvent` then calls into `dispatchEvent` > **Glenn (11:11PM):** > But basically those `dispatchDiscreteEvent` handlers are on the react root node. > > So you could go look at it in chrome devtools ‘event listeners’ tab without needing to tick ‘show ancestors’ if you wanted to > **Glenn (11:15PM):** > Creating a log point on `dispatchDiscreteEvent` > > There are 2 `click` events (and a bunch of other events I don't care about right now such as: `focusin`, `pointerdown`, `mousedown`, `pointerup`, `mouseup`) > **Glenn (11:19PM):** > https://developer.mozilla.org/en-US/docs/Web/API/Event/eventPhase > > The first has `eventPhase` `1` (capturing) > > The next has `eventPhase` `3`: bubbling > > All standard react event handlers trigger on bubbling because of this event delegation in the root node thing. > > (You can also bind a react handler to trigger during the capture phase) > > If you bound a native event handler on the actual target element it would trigger in phase 2 (at the target element) > **Glenn (11:25PM):** > Looks like the react container has its own little internals: `__reactContainer$zwzryaw5zkr` > **Glenn (11:35PM):** > Here’s a gist revision with more of the internals you kind find on those properties: https://gist.github.com/0xdevalias/8c621c5d09d780b1d321bfdb86d67cdd/revisions#diff-fbb49510154bc56f46cbdc5d3afcc2281fa109b6fb3f475cf605a6955f8d5a1a > > `__reactFiber$`, `__reactProps$`, `__reactContainer$`, `__reactEvents$`, `__reactListeners$`, `__reactHandles$`, `__reactResources$`, `__reactMarker$` > **Glenn (11:39PM):** > And a better code snippet for finding all those: https://gist.github.com/0xdevalias/8c621c5d09d780b1d321bfdb86d67cdd/revisions#diff-fbb49510154bc56f46cbdc5d3afcc2281fa109b6fb3f475cf605a6955f8d5a1a > **Glenn (11:40PM):** > I cbf right now; but if I traced into `dispatchEvent` more I could no doubt figure how it maps to knowing where all the event handlers are among everything too. But cbf for now since reading it straight off the fiber is easier anyways > **Glenn (11:46PM):** > Also added some notes to the gist capturing the event phase bubbling/etc stuff from above for feature reference > **Glenn (11:58PM):** > This article also seems a pretty all in one overview of the random shit I found earlier: https://blog.logrocket.com/event-bubbling-capturing-react/ > **Glenn (12:08PM):** > Anyways; hyperfocus over; sleep for me. Night