diff --git a/extension/background.js b/extension/background.js index 51ac05b..5325fa6 100644 --- a/extension/background.js +++ b/extension/background.js @@ -232,7 +232,6 @@ Routes["/tabs/by-id"] = { } }; -// cannot use this wildcard trick w/o breaking the parent logic const tabIdDirectory = createWritableDirectory(); Routes["/tabs/by-id/#TAB_ID"] = routeDefer(() => { const childrenRoute = routeDirectoryForChildren("/tabs/by-id/#TAB_ID"); @@ -246,9 +245,17 @@ Routes["/tabs/by-id/#TAB_ID"] = routeDefer(() => { } }; }); -Routes["/tabs/by-id/#TAB_ID/:FILENAME"] = tabIdDirectory.routeForFilename; - +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? (function() { const routeForTab = (readHandler, writeHandler) => routeWithContents(async ({tabId}) => { diff --git a/extension/embed-files.js b/extension/embed-files.js new file mode 100644 index 0000000..0010fdf --- /dev/null +++ b/extension/embed-files.js @@ -0,0 +1,112 @@ +// Content script that injects a file manager into tabs. + +document.body.insertAdjacentHTML('beforeend', ` + + +
+
+`); +const container = document.getElementsByClassName('--tabfs-file-container')[0]; + +const icons = {}; + +let frontierX = 0, frontierY = 0; +function addFile(name, x, y, file) { + if (!x) { + x = frontierX; frontierX += 64; + y = 0; + } + + container.insertAdjacentHTML('beforeend', ` +
${name}
+`); + const icon = container.lastElementChild; + icon.style.left = x; icon.style.top = y; + + // from https://htmldom.dev/make-a-draggable-element/: + + // The current position of mouse + let mouseX = 0; + let mouseY = 0; + + // Handle the mousedown event + // that's triggered when user drags the element + const mouseDownHandler = function(e) { + // Get the current mouse position + mouseX = e.clientX; + mouseY = e.clientY; + + // Attach the listeners to `document` + document.addEventListener('mousemove', mouseMoveHandler); + document.addEventListener('mouseup', mouseUpHandler); + + e.preventDefault(); + }; + + const mouseMoveHandler = function(e) { + // How far the mouse has been moved + const dx = e.clientX - mouseX; + const dy = e.clientY - mouseY; + + // Set the position of element + icon.style.top = `${icon.offsetTop + dy}px`; + icon.style.left = `${icon.offsetLeft + dx}px`; + + // Reassign the position of mouse + mouseX = e.clientX; + mouseY = e.clientY; + + e.preventDefault(); + }; + + const mouseUpHandler = function() { + // Remove the handlers of `mousemove` and `mouseup` + document.removeEventListener('mousemove', mouseMoveHandler); + document.removeEventListener('mouseup', mouseUpHandler); + }; + + icon.addEventListener('mousedown', mouseDownHandler); +} + +['a.js', 'b.html', 'c.js'].forEach(name => addFile(name)); + +// make the files draggable +// remember their positions on rerender, like do a merge when we get a new set of files + +// from https://htmldom.dev/highlight-an-element-when-dragging-a-file-over-it/: + +document.body.addEventListener('dragenter', function(e) { + e.preventDefault(); + e.target.classList.add('dragging'); +}); +document.body.addEventListener('dragover', function(e) { + e.preventDefault(); +}); +document.body.addEventListener('dragleave', function(e) { + e.preventDefault(); + e.target.classList.remove('dragging'); +}); + +document.body.addEventListener('drop', function(e) { + e.preventDefault(); + e.target.classList.remove('dragging'); + + for (let file of [...e.dataTransfer.files]) { + addFile(file.name, e.clientX, e.clientY, file); + } +}); diff --git a/extension/manifest.json b/extension/manifest.json index c94608e..8b55454 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -17,6 +17,10 @@ "scripts": ["vendor/browser-polyfill.js", "background.js"], "persistent": true }, + "content_scripts": [{ + "matches": ["*://*/*"], + "js": ["embed-files.js"] + }], "browser_specific_settings": { "gecko": {