diff --git a/extension/background.js b/extension/background.js index 18f1b8b..76f846b 100644 --- a/extension/background.js +++ b/extension/background.js @@ -166,6 +166,52 @@ const routeWithContents = (function() { return routeWithContents; })(); +// Returns a 'writable directory' object; its routeForRoot and +// routeForFilename properties can be wired up as routes to create a +// generally writable folder. +function createWritableDirectory() { + const dir = {}; // Map + return { + directory: dir, + routeForRoot: { + usage: 'ls $0', + async readdir({path}) { + // filter out keys not from this path prefix, + // get just last component of keys (filename) + return { entries: [".", "..", + ...Object.keys(dir) + .filter(key => key.startsWith(path)) + .map(key => key.substr(key.lastIndexOf("/") + 1))] }; + }, + getattr() { + return { + st_mode: unix.S_IFDIR | 0777, // writable so you can create/rm evals + st_nlink: 3, + st_size: 0, + }; + }, + }, + routeForFilename: { + usage: ['echo "2 + 2" > $0', + 'cat $0.result'], + + async mknod({path, mode}) { + dir[path] = ''; + return {}; + }, + async unlink({path}) { + delete dir[path]; + return {}; + }, + + ...routeWithContents( + async ({path}) => dir[path], + async ({path}, buf) => { dir[path] = buf; } + ) + } + }; +} + function routeDirectoryForChildren(path) { function depth(p) { return p === '/' ? 0 : (p.match(/\//g) || []).length; } @@ -234,6 +280,8 @@ Routes["/tabs/by-id"] = { const tabIdDirectory = createWritableDirectory(); Routes["/tabs/by-id/#TAB_ID"] = routeDefer(() => { + // we deferred construction of this route so that we have all the + // children to enumerate by now. const childrenRoute = routeDirectoryForChildren("/tabs/by-id/#TAB_ID"); return { ...tabIdDirectory.routeForRoot, // so getattr is inherited @@ -250,17 +298,7 @@ Routes["/tabs/by-id/#TAB_ID"] = routeDefer(() => { } }; }); -Routes["/tabs/by-id/#TAB_ID/:FILENAME"] = { - ...tabIdDirectory.routeForFilename, - async mknod(req) { - const ret = tabIdDirectory.routeForFilename.mknod(req); - // TODO: put icon on page - - return ret; - } -}; -// TODO: can I trigger 1. nav to Finder and 2. nav to Terminal from toolbar click? -// TODO: how can i let them drag files in? +Routes["/tabs/by-id/#TAB_ID/:FILENAME"] = tabIdDirectory.routeForFilename; (function() { const routeForTab = (readHandler, writeHandler) => routeWithContents(async ({tabId}) => { @@ -305,49 +343,6 @@ Routes["/tabs/by-id/#TAB_ID/:FILENAME"] = { ) }; })(); -function createWritableDirectory() { - const dir = {}; - return { - directory: dir, - routeForRoot: { - usage: 'ls $0', - async readdir({path}) { - // get just last component of keys (filename) - return { entries: [".", "..", - ...Object.keys(dir).map( - key => key.substr(key.lastIndexOf("/") + 1) - )] }; - }, - getattr() { - return { - st_mode: unix.S_IFDIR | 0777, // writable so you can create/rm evals - st_nlink: 3, - st_size: 0, - }; - }, - }, - routeForFilename: { - usage: ['echo "2 + 2" > $0', - 'cat $0.result'], - - async mknod({path, mode}) { - dir[path] = ''; - return {}; - }, - async unlink({path}) { - delete dir[path]; - return {}; - }, - - ...routeWithContents( - async ({path}) => dir[path], - async ({path}, buf) => { dir[path] = buf; } - ) - } - }; -} - - (function() { const evals = createWritableDirectory(); Routes["/tabs/by-id/#TAB_ID/evals"] = evals.routeForRoot; diff --git a/extension/embed-files.js b/extension/embed-files.js index 9ae3d03..d9576c4 100644 --- a/extension/embed-files.js +++ b/extension/embed-files.js @@ -1,6 +1,27 @@ -// Content script that injects a file manager into tabs. +if (chrome.extension.getBackgroundPage) { + // When running in background script: + // 'Server' that manages the files for all tabs. -document.body.insertAdjacentHTML('beforeend', ` + // TODO: can I trigger 1. nav to Finder and 2. nav to Terminal from toolbar click? + // accept requests from the page + + browser.runtime.onMessage.addListener(async (request, sender) => { + const {entries} = await Routes["/tabs/by-id/#TAB_ID"].readdir({path: `/tabs/by-id/${sender.tab.id}`}); + return entries; + }); + + // send the file list to the page + + // receive events from the page of + // they dragged a new file in, + // or they moved a file, + // or they double-clicked a file + +} else { + // When running in page: + // Content script that injects a file manager into the page. + + document.body.insertAdjacentHTML('beforeend', `