mirror of
https://github.com/osnr/TabFS.git
synced 2024-05-03 06:13:25 +02:00
console and execute-script work. with test
This commit is contained in:
parent
b09951ebc2
commit
957ea5a3d4
|
@ -229,51 +229,72 @@ router["/tabs/by-id"] = {
|
||||||
router["/tabs/by-id/*/text.txt"] = fromScript(`document.body.innerText`);
|
router["/tabs/by-id/*/text.txt"] = fromScript(`document.body.innerText`);
|
||||||
})();
|
})();
|
||||||
let nextConsoleFh = 0; let consoleForFh = {};
|
let nextConsoleFh = 0; let consoleForFh = {};
|
||||||
|
chrome.runtime.onMessage.addListener(data => {
|
||||||
|
if (!consoleForFh[data.fh]) return;
|
||||||
|
consoleForFh[data.fh].push(data.xs);
|
||||||
|
});
|
||||||
router["/tabs/by-id/*/console"] = {
|
router["/tabs/by-id/*/console"] = {
|
||||||
|
// this one is a bit weird. it doesn't start tracking until it's opened.
|
||||||
|
// tail -f console
|
||||||
|
async getattr() {
|
||||||
|
return {
|
||||||
|
st_mode: unix.S_IFREG | 0444,
|
||||||
|
st_nlink: 1,
|
||||||
|
st_size: 0 // FIXME
|
||||||
|
};
|
||||||
|
},
|
||||||
async open({path}) {
|
async open({path}) {
|
||||||
const tabId = parseInt(pathComponent(path, -2));
|
const tabId = parseInt(pathComponent(path, -2));
|
||||||
const fh = nextConsoleFh++;
|
const fh = nextConsoleFh++;
|
||||||
const code = `
|
const code = `
|
||||||
// runs in 'content script' context
|
// runs in 'content script' context
|
||||||
var script = document.createElement('script');
|
var script = document.createElement('script');
|
||||||
var code = document.createTextNode(\`
|
var code = \`
|
||||||
// runs in real Web page context (this is where we want to hook console.log)
|
// will run both here in content script context and in
|
||||||
|
// real Web page context (so we hook console.log for both)
|
||||||
(function() {
|
(function() {
|
||||||
if (!console.__logOld) console.__logOld = console.log;
|
if (!console.__logOld) console.__logOld = console.log;
|
||||||
|
if (!console.__logFhs) console.__logFhs = new Set();
|
||||||
|
console.__logFhs.add(${fh});
|
||||||
console.log = (...xs) => {
|
console.log = (...xs) => {
|
||||||
console.__logOld(...xs);
|
console.__logOld(...xs);
|
||||||
// TODO: use random event for security instead of this broadcast
|
// TODO: use random event for security instead of this broadcast
|
||||||
window.postMessage({fh: ${fh}, xs: xs}, '*');
|
for (let fh of console.__logFhs) {
|
||||||
|
window.postMessage({fh: ${fh}, xs: xs}, '*');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
})()
|
})()
|
||||||
\`);
|
\`;
|
||||||
script.appendChild(code);
|
eval(code);
|
||||||
|
script.appendChild(document.createTextNode(code));
|
||||||
(document.body || document.head).appendChild(script);
|
(document.body || document.head).appendChild(script);
|
||||||
|
|
||||||
window.addEventListener('message', function({data}) {
|
window.addEventListener('message', function({data}) {
|
||||||
if (data.fh !== ${fh}) return;
|
if (data.fh !== ${fh}) return;
|
||||||
|
// forward to the background script
|
||||||
chrome.runtime.sendMessage(null, data);
|
chrome.runtime.sendMessage(null, data);
|
||||||
});
|
});
|
||||||
`;
|
`;
|
||||||
consoleForFh[fh] = [];
|
consoleForFh[fh] = [];
|
||||||
chrome.runtime.onMessage.addListener(data => {
|
|
||||||
if (data.fh !== fh) return;
|
|
||||||
consoleForFh[fh].push(data.xs);
|
|
||||||
});
|
|
||||||
await browser.tabs.executeScript(tabId, {code});
|
await browser.tabs.executeScript(tabId, {code});
|
||||||
return {fh};
|
return {fh};
|
||||||
},
|
},
|
||||||
async read({path, fh}) {
|
async read({path, fh, offset, size}) {
|
||||||
const buf = consoleForFh[fh].join('\n');
|
const all = consoleForFh[fh].join('\n');
|
||||||
|
// TODO: do this more incrementally ?
|
||||||
|
// will probably break down if log is huge
|
||||||
|
const buf = String.fromCharCode(...toUtf8Array(all).slice(offset, offset + size));
|
||||||
return { buf };
|
return { buf };
|
||||||
},
|
},
|
||||||
async release({fh}) {
|
async release({path, fh}) {
|
||||||
const tabId = parseInt(pathComponent(path, -2));
|
const tabId = parseInt(pathComponent(path, -2));
|
||||||
// TODO: clean up everything
|
// TODO: clean up the hooks inside the contexts
|
||||||
|
delete consoleForFh[fh];
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
router["/tabs/by-id/*/eval"] = {
|
router["/tabs/by-id/*/execute-script"] = {
|
||||||
|
// note: runs in a content script, _not_ in the Web page context
|
||||||
async write({path, buf}) {
|
async write({path, buf}) {
|
||||||
// FIXME: chunk this properly (like if they write a script in
|
// FIXME: chunk this properly (like if they write a script in
|
||||||
// multiple chunks) and only execute when ready?
|
// multiple chunks) and only execute when ready?
|
||||||
|
|
11
test/test.c
11
test/test.c
|
@ -31,7 +31,7 @@ int matches_regex(char* str, char* pattern) {
|
||||||
// integration tests
|
// integration tests
|
||||||
int main() {
|
int main() {
|
||||||
// TODO: invoke over extension
|
// TODO: invoke over extension
|
||||||
assert(system("node ../extension/background.js --unhandled-rejections=strict") == 0); // run quick local JS tests
|
/* assert(system("node ../extension/background.js --unhandled-rejections=strict") == 0); // run quick local JS tests */
|
||||||
|
|
||||||
// reload the extension so we know it's the latest code.
|
// reload the extension so we know it's the latest code.
|
||||||
system("echo reload > ../fs/mnt/runtime/reload 2>/dev/null"); // this may error, but it should still have effect
|
system("echo reload > ../fs/mnt/runtime/reload 2>/dev/null"); // this may error, but it should still have effect
|
||||||
|
@ -50,6 +50,7 @@ int main() {
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
assert(times++ < 10000);
|
assert(times++ < 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(system("echo remove > ../fs/mnt/tabs/last-focused/control") == 0);
|
assert(system("echo remove > ../fs/mnt/tabs/last-focused/control") == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +70,14 @@ int main() {
|
||||||
}
|
}
|
||||||
assert(system("cat ../fs/mnt/tabs/last-focused/debugger/scripts/*test-script.js") == 0);
|
assert(system("cat ../fs/mnt/tabs/last-focused/debugger/scripts/*test-script.js") == 0);
|
||||||
|
|
||||||
|
{
|
||||||
|
FILE* console = fopen("../fs/mnt/tabs/last-focused/console", "r");
|
||||||
|
assert(system("echo \"console.log('hi')\" > ../fs/mnt/tabs/last-focused/execute-script") == 0);
|
||||||
|
char hi[3] = {0}; fread(hi, 1, 2, console);
|
||||||
|
assert(strcmp(hi, "hi") == 0);
|
||||||
|
fclose(console);
|
||||||
|
}
|
||||||
|
|
||||||
assert(system("echo remove > ../fs/mnt/tabs/last-focused/control") == 0);
|
assert(system("echo remove > ../fs/mnt/tabs/last-focused/control") == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue