mirror of
https://github.com/osnr/TabFS.git
synced 2024-05-07 16:16:34 +02:00
prevent explosion of scriptsForTab!
This commit is contained in:
parent
44c8dfcec6
commit
705b245be5
|
@ -52,24 +52,41 @@ async function detachDebugger(tabId) {
|
|||
else { resolve(); }
|
||||
}));
|
||||
}
|
||||
const TabManager = {
|
||||
debugTab: async function(tabId) {
|
||||
// meant to be higher-level wrapper for raw attach/detach
|
||||
// TODO: could we remember if we're already attached? idk if it's worth it
|
||||
try { await attachDebugger(tabId); }
|
||||
catch (e) {
|
||||
if (e.message.indexOf('Another debugger is already attached') !== -1) {
|
||||
await detachDebugger(tabId);
|
||||
await attachDebugger(tabId);
|
||||
}
|
||||
const TabManager = (function() {
|
||||
if (TESTING) return;
|
||||
chrome.debugger.onEvent.addListener((source, method, params) => {
|
||||
console.log(source, method, params);
|
||||
if (method === "Page.frameStartedLoading") {
|
||||
// we're gonna assume we're always plugged into both Page and Debugger.
|
||||
TabManager.scriptsForTab[source.tabId] = [];
|
||||
|
||||
} else if (method === "Debugger.scriptParsed") {
|
||||
TabManager.scriptsForTab[source.tabId] = TabManager.scriptsForTab[source.tabId] || [];
|
||||
TabManager.scriptsForTab[source.tabId].push(params);
|
||||
}
|
||||
// TODO: detach automatically? some kind of reference counting thing?
|
||||
},
|
||||
enableDomainForTab: async function(tabId, domain) {
|
||||
// TODO: could we remember if we're already enabled? idk if it's worth it
|
||||
await sendDebuggerCommand(tabId, `${domain}.enable`, {});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
scriptsForTab: {},
|
||||
debugTab: async function(tabId) {
|
||||
// meant to be higher-level wrapper for raw attach/detach
|
||||
// TODO: could we remember if we're already attached? idk if it's worth it
|
||||
try { await attachDebugger(tabId); }
|
||||
catch (e) {
|
||||
if (e.message.indexOf('Another debugger is already attached') !== -1) {
|
||||
await detachDebugger(tabId);
|
||||
await attachDebugger(tabId);
|
||||
}
|
||||
}
|
||||
// TODO: detach automatically? some kind of reference counting thing?
|
||||
},
|
||||
enableDomainForTab: async function(tabId, domain) {
|
||||
// TODO: could we remember if we're already enabled? idk if it's worth it
|
||||
if (domain === 'Debugger') { TabManager.scriptsForTab[tabId] = []; }
|
||||
await sendDebuggerCommand(tabId, `${domain}.enable`, {});
|
||||
}
|
||||
};
|
||||
})();
|
||||
function sendDebuggerCommand(tabId, method, commandParams) {
|
||||
return new Promise((resolve, reject) =>
|
||||
chrome.debugger.sendCommand({tabId}, method, commandParams, result => {
|
||||
|
@ -78,23 +95,6 @@ function sendDebuggerCommand(tabId, method, commandParams) {
|
|||
);
|
||||
}
|
||||
|
||||
const BrowserState = { scriptsForTab: {} };
|
||||
(function() {
|
||||
if (TESTING) return;
|
||||
|
||||
chrome.debugger.onEvent.addListener((source, method, params) => {
|
||||
console.log(source, method, params);
|
||||
if (method === "Page.frameStartedLoading") {
|
||||
// we're gonna assume we're always plugged into both Page and Debugger.
|
||||
BrowserState.scriptsForTab[source.tabId] = [];
|
||||
|
||||
} else if (method === "Debugger.scriptParsed") {
|
||||
BrowserState.scriptsForTab[source.tabId] = BrowserState.scriptsForTab[source.tabId] || [];
|
||||
BrowserState.scriptsForTab[source.tabId].push(params);
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
const router = {};
|
||||
|
||||
const Cache = {
|
||||
|
@ -288,14 +288,16 @@ router["/tabs/by-id/*/control"] = {
|
|||
},
|
||||
async readdir({path}) {
|
||||
const tabId = parseInt(pathComponent(path, -3));
|
||||
return { entries: [".", "..", ...BrowserState.scriptsForTab[tabId].map(params => sanitize(params.url).slice(0, 200) + "_" + params.scriptId)] };
|
||||
return { entries: [".", "..", ...TabManager.scriptsForTab[tabId].map(params => sanitize(params.url).slice(0, 200) + "_" + params.scriptId)] };
|
||||
}
|
||||
};
|
||||
router["/tabs/by-id/*/debugger/scripts/*"] = defineFile(async path => {
|
||||
const [tabId, suffix] = [parseInt(pathComponent(path, -4)), pathComponent(path, -1)];
|
||||
await TabManager.debugTab(tabId);
|
||||
console.log('BEFORE', TabManager.scriptsForTab[tabId].length);
|
||||
await TabManager.enableDomainForTab(tabId, "Page");
|
||||
await TabManager.enableDomainForTab(tabId, "Debugger");
|
||||
console.log('AFTER', TabManager.scriptsForTab[tabId].length)
|
||||
|
||||
const parts = path.split("_"); const scriptId = parts[parts.length - 1];
|
||||
const {scriptSource} = await sendDebuggerCommand(tabId, "Debugger.getScriptSource", {scriptId});
|
||||
|
|
57
tabfs.md
57
tabfs.md
|
@ -358,7 +358,18 @@ TODO: make diagrams?
|
|||
|
||||
GPLv3
|
||||
|
||||
## things that would be cool to do
|
||||
## things that could/should be done
|
||||
|
||||
- add more synthetic files!! view DOM nodes, snapshot current HTML of
|
||||
page, spelunk into living objects. see what your code is doing. make
|
||||
more files writable also
|
||||
|
||||
- build more (GUI and CLI) tools on top, on both sides
|
||||
|
||||
- more persistence stuff
|
||||
|
||||
- why can't Preview open images? GUI programs often struggle with the
|
||||
filesystem for some reason. CLI more reliable
|
||||
|
||||
- multithreading. the key constraint is that I pass `-s` to
|
||||
`fuse_main` in `tabfs.c`, which makes everything
|
||||
|
@ -379,18 +390,20 @@ GPLv3
|
|||
filesystem, even ones you'd assume are reasonably battle-tested and
|
||||
well-engineered like sshfs?
|
||||
|
||||
- other performance stuff -- remembering when we're already attached
|
||||
to things, reference counting, minimizing browser roundtrips. not
|
||||
sure impact of these
|
||||
|
||||
- TypeScript (how to do with the minimum amount of build system and
|
||||
package manager nonsense?)
|
||||
|
||||
- look into support for Firefox / Windows / Safari / etc. best FUSE
|
||||
equiv for Windows? can you bridge to the remote debugging APIs that
|
||||
all of them already have to get the augmented functionality? or just
|
||||
implement it all with JS monkey patching?
|
||||
|
||||
- window management. tab management where you can move tabs
|
||||
|
||||
- snapshotting (snapshot.html / snapshot.mhtml file)
|
||||
|
||||
- fix leaks
|
||||
|
||||
- elim unnecessary round-trips / browser API calls
|
||||
- window management. tab management where you can move tabs. 'merge
|
||||
all windows'
|
||||
|
||||
## hmm
|
||||
|
||||
|
@ -423,14 +436,30 @@ 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
|
||||
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
|
||||
- a lot of existing uses of these APIs are in an automation context:
|
||||
testing your code on a robotic browser as part of some pipeline. I'm
|
||||
much more interested in an interactive, end-user context. augmenting
|
||||
the way I use my everyday 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)
|
||||
|
||||
- system call tracing (dtruss or strace) super useful when anything is
|
||||
going wrong. (need to disable SIP on macOS, though.) the
|
||||
combination of dtruss (application side) & console logging fs
|
||||
request/response (filesystem side) gives a huge amount of insight
|
||||
into basically any problem, end to end
|
||||
|
||||
- for a lot of things in the extension API, the browser can notify you
|
||||
of updates but there's no apparent way to query the full current
|
||||
state. so we'd need to sit in a lot of these places from the
|
||||
beginning and accumulate the incoming events to know, like, the last
|
||||
time a tab was updated, or the list of scripts currently running on
|
||||
a tab
|
||||
|
||||
- async/await was absolutely vital to making this readable
|
||||
|
||||
- open input space -- filesystem. (it reminds me of Screenotate.)
|
||||
|
||||
- now you have this whole 'language', this whole toolset, to control
|
||||
|
|
|
@ -41,6 +41,9 @@ int main() {
|
|||
assert(system("echo file://$(pwd)/test-page.html > ../fs/mnt/tabs/create") == 0);
|
||||
assert(file_contents_equal("../fs/mnt/tabs/last-focused/title.txt", "Title of Test Page"));
|
||||
assert(file_contents_equal("../fs/mnt/tabs/last-focused/text.txt", "Body Text of Test Page"));
|
||||
|
||||
assert(system("ls ../fs/mnt/tabs/last-focused/debugger/scripts") == 0);
|
||||
|
||||
assert(system("echo remove > ../fs/mnt/tabs/last-focused/control") == 0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue