diff options
-rw-r--r-- | extension/background.js | 85 |
1 files changed, 68 insertions, 17 deletions
diff --git a/extension/background.js b/extension/background.js index 5e487cf..6b1452b 100644 --- a/extension/background.js +++ b/extension/background.js @@ -7,6 +7,7 @@ const unix = { EINTR: 4, EIO: 5, ENXIO: 6, + EINVAL: 22, ENOTSUP: 45, ETIMEDOUT: 110, // FIXME: not on macOS (?) @@ -355,24 +356,74 @@ router["/tabs/by-id/*/control"] = { }, async truncate({path, size}) { return {}; } }; -router["/tabs/by-id/*/active"] = { - // echo true > mnt/tabs/by-id/1644/active - // cat mnt/tabs/by-id/1644/active - async read({path, fh, offset, size}) { - const tabId = parseInt(pathComponent(path, -2)); - const tab = await browser.tabs.get(tabId); - const buf = (JSON.stringify(tab.active) + '\n').slice(offset, offset + size); - return { buf }; - }, - async write({path, buf}) { - if (buf.trim() === "true") { +(() => { + const defineProperty = ({ assert, get, set }) => { + const getData = async path => { const tabId = parseInt(pathComponent(path, -2)); - await browser.tabs.update(tabId, { active: true }); - } - return {size: stringToUtf8Array(buf).length}; - }, - async truncate({path, size}) { return {}; } -}; + const tab = await browser.tabs.get(tabId); + const value = get(tab); + return JSON.stringify(value) + "\n"; + }; + + const setData = async (path, buf) => { + if (buf.length > 0) { + let value; + try { + value = JSON.parse(buf); + } catch (error) { + console.error(error); + } + if (!assert(value)) { + console.error("assertion failed", { buf, value }); + throw new UnixError(unix.EINVAL); + } + const tabId = parseInt(pathComponent(path, -2)); + const tab = await browser.tabs.get(tabId); + return set(tab, value); + } else { + return Promise.resolve(); + } + }; + + return { + async read({path, fh, size, offset}) { + return { buf: (await getData(path)).slice(offset, offset + size) }; + }, + async write({path, fh, offset, buf}) { + if (offset != 0) { + throw new UnixError(unix.EINVAL); + } + await setData(path, buf.trim()); + return { size: buf.length }; + }, + async truncate({path, size}) { + return {}; + } + }; + }; + + const isBoolean = value => typeof value === "boolean"; + const isInteger = Number.isInteger; + + router["/tabs/by-id/*/active"] = defineProperty({ + assert: isBoolean, + get: tab => tab.active, + set: (tab, active) => browser.tabs.update(tab.id, {active}), + }); + + router["/tabs/by-id/*/index"] = defineProperty({ + assert: isInteger, + get: tab => tab.index, + set: (tab, index) => browser.tabs.move(tab.id, {index}), + }); + + router["/tabs/by-id/*/discard"] = defineProperty({ + assert: isBoolean, + get: tab => tab.discarded, + set: (tab, _) => browser.tabs.discard(tab.id), + }); + +})(); // debugger/ : debugger-API-dependent (Chrome-only) (function() { |