cleanup refcount stuff that wasn't being used anyway, update md

This commit is contained in:
Omar Rizwan 2020-12-28 10:41:15 -08:00
parent e31f915bdd
commit b8181bd6f5
3 changed files with 94 additions and 60 deletions

0
.gitmodules vendored
View file

View file

@ -53,35 +53,21 @@ async function detachDebugger(tabId) {
})); }));
} }
const TabManager = { const TabManager = {
tabState: {},
// higher-level wrapper which avoids unnecessary attaches and tries
// to keep debugger attached in a reasonable state whenever you call
// it (do we need this?)
debugTab: async function(tabId) { debugTab: async function(tabId) {
this.tabState[tabId] = this.tabState[tabId] || {}; // meant to be higher-level wrapper for raw attach/detach
if (this.tabState[tabId].debugging) { // TODO: could we remember if we're already attached? idk if it's worth it
this.tabState[tabId].debugging += 1; try { await attachDebugger(tabId); }
catch (e) {
} else { if (e.message.indexOf('Another debugger is already attached') !== -1) {
try { await attachDebugger(tabId); } await detachDebugger(tabId);
catch (e) { await attachDebugger(tabId);
if (e.message.indexOf('Another debugger is already attached') !== -1) {
await detachDebugger(tabId);
await attachDebugger(tabId);
}
} }
this.tabState[tabId].debugging = 1;
} }
// FIXME: unsubscribe // TODO: detach automatically? some kind of reference counting thing?
}, },
enableDomainForTab: async function(tabId, domain) { enableDomainForTab: async function(tabId, domain) {
this.tabState[tabId] = this.tabState[tabId] || {}; // TODO: could we remember if we're already enabled? idk if it's worth it
if (this.tabState[tabId][domain]) { this.tabState[tabId][domain] += 1; await sendDebuggerCommand(tabId, `${domain}.enable`, {});
} else {
await sendDebuggerCommand(tabId, `${domain}.enable`, {});
this.tabState[tabId][domain] = 1;
}
} }
}; };
function sendDebuggerCommand(tabId, method, commandParams) { function sendDebuggerCommand(tabId, method, commandParams) {
@ -217,7 +203,6 @@ router["/tabs/by-id"] = {
// TODO: dom/ ? // TODO: dom/ ?
// TODO: globals/ ? // TODO: globals/ ?
// screenshot.png (FIXME: how to keep from blocking when unfocused?)
// TODO: archive.mhtml ? // TODO: archive.mhtml ?
// TODO: printed.pdf // TODO: printed.pdf
// control // control
@ -373,6 +358,9 @@ router["/windows/last-focused"] = {
} }
}; };
router["/windows/*/visible-tab.png"] = { ...defineFile(async path => { router["/windows/*/visible-tab.png"] = { ...defineFile(async path => {
// this is a window thing (rn, the _only_ window thing) because you
// can only capture the visible tab for each window anyway; you
// can't take a screenshot of just any arbitrary tab
const windowId = parseInt(pathComponent(path, -2)); const windowId = parseInt(pathComponent(path, -2));
const dataUrl = await browser.tabs.captureVisibleTab(windowId, {format: 'png'}); const dataUrl = await browser.tabs.captureVisibleTab(windowId, {format: 'png'});
return Uint8Array.from(atob(dataUrl.substr(("data:image/png;base64,").length)), return Uint8Array.from(atob(dataUrl.substr(("data:image/png;base64,").length)),

116
tabfs.md
View file

@ -4,7 +4,7 @@ title: TabFS
<!-- I'm setting this page in Verdana-on-gray so I feel more comfortable --> <!-- I'm setting this page in Verdana-on-gray so I feel more comfortable -->
<!-- jotting random notes and stuff down. --> <!-- jotting random notes and stuff down. -->
<style> <style>
body { font-family: Verdana; background: #eee; } body { font-family: Verdana, sans-serif; background: #eee; }
h1 { font-family: Helvetica; } h1 { font-family: Helvetica; }
</style> </style>
@ -29,14 +29,22 @@ Firefox, on macOS and Linux.[^otherbrowsers]
Each of your open tabs is mapped to a folder. Each of your open tabs is mapped to a folder.
<div class="figure"> <div class="figure">
<img src="doc/finder.png"> <img src="doc/00-browser.png" style="width: 70%">
<img src="doc/00-finder.png" style="width: 80%; max-height: 1000px">
<p class="caption" style="margin-top: -20px">I have 3 tabs open, and
they map to 3 folders in TabFS</p>
</div> </div>
The files inside a tab's folder directly reflect (and can control) the The files inside a tab's folder directly reflect (and can control) the
state of that tab in your browser. (TODO: update as I add more) state of that tab in your browser. (TODO: update as I add more)
<div class="figure"> <div class="figure">
<img src="doc/finder-contents.png"> <video autoplay loop muted>
<source src="doc/finder-contents.mp4" type="video/mp4">
</video>
<p class="caption">Example: the url.txt, text.txt, and title.txt
files inside a tab's folder, which tell me those live properties
for that tab</p>
</div> </div>
This gives you a _ton_ of power, because now you can apply [all the This gives you a _ton_ of power, because now you can apply [all the
@ -54,13 +62,17 @@ file](https://twitter.com/rsnous/status/1308588645872435202) that you
can run whenever, and it's no different from scripting any other part can run whenever, and it's no different from scripting any other part
of your computer. of your computer.
## Examples of stuff you can do! ## Examples of stuff you can do![^examples]
[^examples]: maybe some of these feel a little more vital and
fleshed-out and urgent than others. the things I actually wanted
to do and reached for vs. the things that satisfy some pedagogical
property (simple to explain, stack on top of the previous example,
...)
(assuming your current directory is the `fs` subdirectory of the git (assuming your current directory is the `fs` subdirectory of the git
repo and you have the extension running) repo and you have the extension running)
(TODO: more of these)
### List the titles of all the tabs you have open ### List the titles of all the tabs you have open
``` ```
@ -74,6 +86,18 @@ Home / Twitter
... ...
``` ```
### Cull tabs like any other files
<div class="figure">
<video autoplay loop muted>
<source src="doc/delete.mp4" type="video/mp4">
</video>
<p class="caption">Selecting and deleting a bunch of tabs in my file manager</p>
</div>
I'm using Dired in Emacs here, but you could use whatever tools you
already feel comfortable managing your files with.
### Close all Stack Overflow tabs ### Close all Stack Overflow tabs
``` ```
@ -130,15 +154,16 @@ post](https://stackoverflow.com/questions/2963260/how-do-i-auto-reload-a-chrome-
with ways to automate this, but they're all sort of hacky. You need with ways to automate this, but they're all sort of hacky. You need
yet another extension, or you need to tack weird permissions onto your yet another extension, or you need to tack weird permissions onto your
work-in-progress extension, and you don't just get a command you can work-in-progress extension, and you don't just get a command you can
trigger from your editor or shell. trigger from your editor or shell to refresh the extension.
TabFS lets you do all this in [an ordinary shell TabFS lets you do all this in [an ordinary shell
script](https://github.com/osnr/playgroundize-devtools-protocol/blob/main/go.sh). script](https://github.com/osnr/playgroundize-devtools-protocol/blob/main/go.sh).
You don't have to write any browser-side code at all. You don't have to write any browser-side code at all.
The script linked above turns the extension (this one's title is This script turns an extension (this one's title is "Playgroundize
"Playgroundize DevTools Protocol") off, then turns it back on, then DevTools Protocol") off, then turns it back on, then reloads any tabs
reloads any Chrome DevTools pages that are open: that have the relevant pages open (in this case, I decided it's tabs
whose titles start with "Chrome Dev"):
``` ```
#!/bin/bash -eux #!/bin/bash -eux
@ -147,12 +172,8 @@ echo true > mnt/extensions/Playg*/enabled
echo reload | tee mnt/tabs/by-title/Chrome_Dev*/control echo reload | tee mnt/tabs/by-title/Chrome_Dev*/control
``` ```
I mapped this script to Ctrl-. in my Emacs, so now I can just hit that I mapped this script to Ctrl-. in my text editor, and now I just hit
every time I want to reload my extension code! that every time I want to reload my extension code.
### TODO: Cull tabs like any other files
I do this in Emacs dired.
### TODO: Live edit a running Web page ### TODO: Live edit a running Web page
@ -263,10 +284,13 @@ click "Inspect")
</div> </div>
This console is also incredibly helpful for debugging anything that This console is also incredibly helpful for debugging anything that
goes wrong, which probably will happen. goes wrong, which probably will happen. (If you get a generic I/O
error at the shell when running a command on TabFS, that probably
means that an exception happened which you can check here.)
(My OS and applications are pretty chatty! They do a lot of (My OS and applications are pretty chatty. They do a lot of
operations, even when I don't feel like I'm actually doing anything.) operations, even when I don't feel like I'm actually doing
anything. My sense is that macOS is generally chattier than Linux.)
## Design ## Design
@ -280,10 +304,17 @@ operations, even when I don't feel like I'm actually doing anything.)
**The most interesting file**. Defines all the synthetic files and **The most interesting file**. Defines all the synthetic files and
what browser operations they invoke behind the scenes.[^frustrates] what browser operations they invoke behind the scenes.[^frustrates]
[^frustrates]: it frustrates me that I can't have something like a [^frustrates]: it frustrates me that I can't show you, like, a table
table of contents for this source file. because it does have a of contents for this source file. because it does have a structure
structure to it! so I feel like the UI for looking at the file to it! so I feel like the UI for looking at this one file should
should highlight and exploit that structure. be
[custom-tailored](https://twitter.com/rsnous/status/1262956983222591488)
to
[highlight](https://twitter.com/rsnous/status/1262957486262214657)
and exploit that structure. (I wonder what other cases like this
are out there, where ad hoc UI for one file would be useful. like
if you have tangled-but-regular business logic, or the giant
opcode switch statement of an emulator or interpreter.)
I want to link you to a particular route and talk about it here I want to link you to a particular route and talk about it here
and also have some kind of and also have some kind of
@ -327,14 +358,14 @@ TODO: make diagrams?
GPLv3 GPLv3
## things that would be good to do ## things that would be cool to do
- multithreading. the key constraint is that I give `-s` to - multithreading. the key constraint is that I pass `-s` to
`fuse_main` in `tabfs.c`, which makes everything `fuse_main` in `tabfs.c`, which makes everything
single-threaded. but I'm not clear on how much it would improve single-threaded. but I'm not clear on how much it would improve
performance? maybe a lot, but not sure. maybe workload-dependent? performance? maybe a lot, but not sure. maybe workload-dependent?
the extension itself (and the standard I/O comm between the fs and the extension itself (and the stdin/stdout comm between the fs and
the extension) would still be single-threaded, but you could the extension) would still be single-threaded, but you could
interleave requests since most of that stuff is async. like the interleave requests since most of that stuff is async. like the
screenshot request that takes like half a second, you could do other screenshot request that takes like half a second, you could do other
@ -344,15 +375,19 @@ GPLv3
individual request hangs anyway; they're not expecting the individual request hangs anyway; they're not expecting the
filesystem to be so slow (and to be fair to them, they really have filesystem to be so slow (and to be fair to them, they really have
[no way](https://twitter.com/whitequark/status/1133905587819941888) [no way](https://twitter.com/whitequark/status/1133905587819941888)
to). some of these are problems that may be inevitable for any FUSE to). some of these problems may be inevitable for any FUSE
filesystem, even ones you'd assume are reasonably battle-tested and filesystem, even ones you'd assume are reasonably battle-tested and
well-engineered like sshfs? well-engineered like sshfs?
- look into support for Firefox / Windows / Safari / etc. best FUSE - look into support for Firefox / Windows / Safari / etc. best FUSE
equiv for Windows? can you bridge to the remote debugging APIs that equiv for Windows? can you bridge to the remote debugging APIs that
all of them have to get the augmented functionality? or just all of them already have to get the augmented functionality? or just
implement it all with JS monkey patching? implement it all with JS monkey patching?
- window management. tab management where you can move tabs
- snapshotting (snapshot.html / snapshot.mhtml file)
- fix leaks - fix leaks
- elim unnecessary round-trips / browser API calls - elim unnecessary round-trips / browser API calls
@ -376,9 +411,10 @@ inside of the browser. can we have 'browser tabs as files'?
- there are two 'operating systems' on my computer, the browser and - there are two 'operating systems' on my computer, the browser and
Unix, and Unix is by far the more accessible and programmable and Unix, and Unix is by far the more accessible and programmable and
cohesive as a computing environment (shells, processes), even though cohesive as a computing environment (it has concepts that compose!
it's arguably the less important to my daily life. how can the browser shell, processes, files), even though it's arguably the less important
take on these properties? to my daily life. how can the browser take on more of the properties
of Unix?
- it's [way too - it's [way too
hard](https://twitter.com/rsnous/status/1342236988938719232) to make a hard](https://twitter.com/rsnous/status/1342236988938719232) to make a
@ -387,6 +423,14 @@ suggests making an extension is a whole Thing, a whole Project. like,
why can't I just take a minute to ask my browser a question or tell it why can't I just take a minute to ask my browser a question or tell it
to automate something? lightness to automate something? lightness
- a lot of existing uses of these APIs are in an automation context,
if you want to test your code on an automated browser. I'm much more
interested in an interactive, end-user context. augmenting the way I
use my normal browser. that's why this is an extension. it doesn't
require your browser to run in some weird remote debugging mode that
you'd always forget to turn on. it just [stays
running](https://twitter.com/rsnous/status/1340150818553561094)
- open input space -- filesystem. (it reminds me of Screenotate.) - open input space -- filesystem. (it reminds me of Screenotate.)
- now you have this whole 'language', this whole toolset, to control - now you have this whole 'language', this whole toolset, to control
@ -410,11 +454,13 @@ files
- fake filesystems talk - fake filesystems talk
- [rmdir a non-empty - [rmdir a non-empty
directory](https://twitter.com/rsnous/status/1107427906832089088). I directory](https://twitter.com/rsnous/status/1107427906832089088)
feel like a new OS, something like Plan 9, should -- when I was thinking if you should be able to `rm by-id/TABID`
even though `TABID` is a folder. I feel like a new OS, something
like Plan 9, should
[generalize](https://twitter.com/rsnous/status/1070830656005988352) [generalize](https://twitter.com/rsnous/status/1070830656005988352)
its file I/O APIs just enough to avoid problems like this. like its file I/O APIs just enough to avoid problems like this. like
design them with the disk in mind but also a few concrete cases design them with the disk in mind but also a few concrete cases of
of synthetic filesystems, very slow remote filesystems, etc synthetic filesystems, very slow remote filesystems, etc
do you like setting up sockets? I don't do you like setting up sockets? I don't