mirror of
https://github.com/osnr/TabFS.git
synced 2024-05-23 16:02:18 +02:00
embed-files: draw the tab dir files on all pages
This commit is contained in:
parent
1dd5136415
commit
08d2b5d1d4
|
@ -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<Path, {content: String, x, y}>
|
||||
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;
|
||||
|
|
|
@ -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', `
|
||||
<style>
|
||||
.--tabfs-file-container .--tabfs-file {
|
||||
/* fixed makes sense if it's a property of the tab; */
|
||||
|
@ -17,12 +38,14 @@ document.body.insertAdjacentHTML('beforeend', `
|
|||
<div class="--tabfs-file-container">
|
||||
</div>
|
||||
`);
|
||||
const container = document.getElementsByClassName('--tabfs-file-container')[0];
|
||||
const container = document.getElementsByClassName('--tabfs-file-container')[0];
|
||||
|
||||
const icons = {};
|
||||
const icons = {};
|
||||
|
||||
let frontierX = 0, frontierY = 0;
|
||||
const addFile = function(name, x, y, file) {
|
||||
// TODO: report into the extension
|
||||
|
||||
let frontierX = 0, frontierY = 0;
|
||||
function addFile(name, x, y, file) {
|
||||
if (!x) {
|
||||
x = frontierX; frontierX += 64;
|
||||
y = 0;
|
||||
|
@ -77,24 +100,28 @@ function addFile(name, x, y, file) {
|
|||
};
|
||||
|
||||
icon.addEventListener('mousedown', mouseDownHandler);
|
||||
}
|
||||
};
|
||||
|
||||
['a.js', 'b.html', 'c.js'].forEach(name => addFile(name));
|
||||
// ask for what the files are
|
||||
chrome.runtime.sendMessage({hello: 'hello'}, function(response) {
|
||||
response.forEach(name => addFile(name));
|
||||
});
|
||||
|
||||
document.body.addEventListener('dragenter', function(e) {
|
||||
document.body.addEventListener('dragenter', function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
document.body.addEventListener('dragover', function(e) {
|
||||
});
|
||||
document.body.addEventListener('dragover', function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
document.body.addEventListener('dragleave', function(e) {
|
||||
});
|
||||
document.body.addEventListener('dragleave', function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
});
|
||||
|
||||
document.body.addEventListener('drop', function(e) {
|
||||
document.body.addEventListener('drop', function(e) {
|
||||
// bubble thing
|
||||
e.preventDefault(); // stops browser nav to that file
|
||||
for (let file of [...e.dataTransfer.files]) {
|
||||
addFile(file.name, e.clientX, e.clientY, file);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
|
||||
|
||||
"background": {
|
||||
"scripts": ["vendor/browser-polyfill.js", "background.js"],
|
||||
"scripts": ["vendor/browser-polyfill.js", "background.js", "embed-files.js"],
|
||||
"persistent": true
|
||||
},
|
||||
"content_scripts": [{
|
||||
|
|
Loading…
Reference in a new issue