diff --git a/extension/src/js/background.js b/extension/src/js/background.js index e85e9d5..32b640b 100644 --- a/extension/src/js/background.js +++ b/extension/src/js/background.js @@ -65,31 +65,49 @@ async function makeCaptureRequest( // TODO FIXME ugh. need defensive error handling on the very top... function capture(comment: ?string = null, tag_str: ?string = null) { chrome.tabs.query({currentWindow: true, active: true }, tabs => { - const tab = tabs[0]; + const tab = tabs[0] if (tab.url == null) { - showNotification('ERROR: trying to capture null'); - return; + showNotification('ERROR: trying to capture null') + return } - const url: string = tab.url; - const title: ?string = tab.title; + const url: string = tab.url + const title: ?string = tab.title + + + const payload = (selection: ?string) => { + return { + url: url, + title: title, + selection: selection, + comment: comment, + tag_str: tag_str, + } + } + + // TODO await properly and handle errors + const has_scripting = 'scripting' in chrome get_options(opts => { - // console.log('action!'); - // ugh.. https://stackoverflow.com/a/19165930/706389 - chrome.tabs.executeScript( { - code: "window.getSelection().toString();" - }, selections => { - const selection = selections == null ? null : selections[0]; - makeCaptureRequest({ - url: url, - title: title, - selection: selection, - comment: comment, - tag_str: tag_str, - }, opts); - }); - }); - }); + if (has_scripting) { + // $FlowFixMe + chrome.scripting.executeScript({ + target: {tabId: tab.id}, + func: () => window.getSelection().toString() + }, results => { + const [res] = results // should only inject in one frame, so just one result + const selection = res.result + makeCaptureRequest(payload(selection), opts) + }) + } else { + chrome.tabs.executeScript( { + code: "window.getSelection().toString();" + }, selections => { + const selection = selections == null ? null : selections[0] + makeCaptureRequest(payload(selection), opts) + }) + } + }) + }) } diff --git a/extension/src/manifest.json b/extension/src/manifest.json index 4592c06..66df0da 100644 --- a/extension/src/manifest.json +++ b/extension/src/manifest.json @@ -8,19 +8,6 @@ "options_ui": { "page": "options.html" }, - "browser_action": { - "default_icon": "img/unicorn.png", - "default_popup": "popup.html", - "default_title": "Capture page, with extra information" - }, - "commands": { - "capture-simple": { - "description": "Quick capture: url, title and selection" - }, - "_execute_browser_action": { - "description": "Capture page, with extra information" - } - }, "icons": { "128": "img/unicorn.png" }, diff --git a/extension/webpack.config.js b/extension/webpack.config.js index 5953d50..b82997f 100644 --- a/extension/webpack.config.js +++ b/extension/webpack.config.js @@ -25,34 +25,74 @@ const target = env.TARGET; const name = "grasp" + (dev ? ' [dev]' : ''); -// Firefox wouldn't let you rebind its default shortcuts most of which use Shift -// On the other hand, Chrome wouldn't let you use Alt -const modifier = target === T.CHROME ? 'Shift' : 'Alt'; // ugh. declarative formats are shit. -const commandsExtra = { + +// Firefox wouldn't let you rebind its default shortcuts most of which use Shift +// On the other hand, Chrome wouldn't let you use Alt +const modifier = target === T.CHROME ? 'Shift' : 'Alt' + +const action_name = 'browser_action' + +const commands = { "capture-simple": { + "description": "Quick capture: url, title and selection", "suggested_key": { "default": `Ctrl+${modifier}+C`, - "mac": `Command+${modifier}+C` - } - }, - "_execute_browser_action": { + "mac": `Command+${modifier}+C`, + }, + } +} + +commands[`_execute_${action_name}`] = { + "description": "Capture page, with extra information", "suggested_key": { "default": `Ctrl+${modifier}+Y`, - "mac": `Command+${modifier}+Y` - } - }, -}; + "mac": `Command+${modifier}+Y`, + }, +} + + +const action = { + "default_icon": "img/unicorn.png", + "default_popup": "popup.html", + "default_title": "Capture page, with extra information", +} +if (target == T.FIREFOX) { + action['browser_style'] = true +} + + +// prepare for manifest v3 +const host_permissions = [ + "http://localhost/capture", + "https://localhost/capture", +] + + +const optional_permissions = [ + "http://*/capture", + "https://*/capture", +] + // TODO make permissions literate const permissions = [ "storage", "notifications", - "activeTab", - "http://localhost/capture", - "https://localhost/capture" -]; + + // need to query active tab and get its url/title + "activeTab", + + ...host_permissions, +] + +if (target === T.FIREFOX) { + // chrome v2 doesn't support scripting api + // code has a fallback just for that + // need to get selected text + permissions.push("scripting") +} const manifestExtra = { @@ -60,12 +100,11 @@ const manifestExtra = { version: pkg.version, description: pkg.description, permissions: permissions, - commands: commandsExtra, - optional_permissions: [ - "http://*/capture", - "https://*/capture", - ], -}; + commands: commands, + optional_permissions: optional_permissions, +} +manifestExtra[action_name] = action + if (dev) { manifestExtra.content_security_policy = "script-src 'self' 'unsafe-eval'; object-src 'self'"; @@ -76,7 +115,6 @@ if (target === T.CHROME) { } if (target === T.FIREFOX) { manifestExtra.options_ui = {browser_style: true}; - manifestExtra.browser_action = {browser_style: true}; } const buildPath = path.join(__dirname, 'dist', target);