From 88537f3ebe77b32fb132bdd84a2ec5384efea207 Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Wed, 10 Apr 2019 16:59:35 +0200 Subject: [PATCH] Add WebExtension API polyfill (#3339) Start of #3200 This will be an ongoing effort. --- client/browser/src/browser/extension.ts | 3 --- client/browser/src/config/polyfill.ts | 8 ++++++++ client/browser/src/config/polyfill.tsx | 19 ------------------- .../src/extension/scripts/auto-reloading.ts | 16 ++++++++-------- .../browser/src/extension/scripts/inject.tsx | 3 +-- client/browser/src/libs/sentry/index.ts | 4 +--- client/browser/src/shared/backend/graphql.tsx | 12 +----------- .../src/types/web-ext-types/index.d.ts | 3 +++ client/browser/tsconfig.json | 8 +++++++- package.json | 2 ++ yarn.lock | 10 ++++++++++ 11 files changed, 41 insertions(+), 47 deletions(-) delete mode 100644 client/browser/src/browser/extension.ts create mode 100644 client/browser/src/config/polyfill.ts delete mode 100644 client/browser/src/config/polyfill.tsx create mode 100644 client/browser/src/types/web-ext-types/index.d.ts diff --git a/client/browser/src/browser/extension.ts b/client/browser/src/browser/extension.ts deleted file mode 100644 index e055f13ab47..00000000000 --- a/client/browser/src/browser/extension.ts +++ /dev/null @@ -1,3 +0,0 @@ -const chrome = global.chrome - -export const getURL = (path: string) => chrome.extension.getURL(path) diff --git a/client/browser/src/config/polyfill.ts b/client/browser/src/config/polyfill.ts new file mode 100644 index 00000000000..b52f19492f3 --- /dev/null +++ b/client/browser/src/config/polyfill.ts @@ -0,0 +1,8 @@ +// Same polyfills as the webapp +import '../../../../shared/src/polyfills' + +// Polyfill global browser API for Chrome +// The API is much nicer to use because it supports Promises +// The polyfill is also very simple. +import browser from 'webextension-polyfill' +Object.assign(self, { browser }) diff --git a/client/browser/src/config/polyfill.tsx b/client/browser/src/config/polyfill.tsx deleted file mode 100644 index 5ad91e77aa5..00000000000 --- a/client/browser/src/config/polyfill.tsx +++ /dev/null @@ -1,19 +0,0 @@ -// This gets automatically expanded into imports that only pick what we need. -import '@babel/polyfill' - -// Polyfill URL because Chrome and Firefox are not spec-compliant -// Hostnames of URIs with custom schemes (e.g. git) are not parsed out -// The polyfill does not expose createObjectURL, which we need for creating data: URIs for Web -// Workers. So retain it. -// -// tslint:disable-next-line:no-unbound-method -const createObjectURL = window.URL ? window.URL.createObjectURL : null - -import { URL, URLSearchParams } from 'whatwg-url' - -const GLOBAL = global as any -GLOBAL.URL = URL -GLOBAL.URLSearchParams = URLSearchParams -if (!window.URL.createObjectURL && createObjectURL) { - window.URL.createObjectURL = createObjectURL -} diff --git a/client/browser/src/extension/scripts/auto-reloading.ts b/client/browser/src/extension/scripts/auto-reloading.ts index 3a86e03211e..e42d0ab77aa 100644 --- a/client/browser/src/extension/scripts/auto-reloading.ts +++ b/client/browser/src/extension/scripts/auto-reloading.ts @@ -4,12 +4,12 @@ import io from 'socket.io-client' * Reloads the extension when notified from the development server. Only enabled * during development when `process.env.AUTO_RELOAD !== 'false'. */ -const initializeExtension = () => - chrome.management.getSelf(self => { - if (self.installType === 'development') { - // Since the port is hard-coded, it must match scripts/dev.ts - io.connect('http://localhost:8890').on('file.change', () => chrome.runtime.reload()) - } - }) +async function main(): Promise { + const self = await browser.management.getSelf() + if (self.installType === 'development') { + // Since the port is hard-coded, it must match scripts/dev.ts + io.connect('http://localhost:8890').on('file.change', () => browser.runtime.reload()) + } +} -initializeExtension() +main().catch(console.error.bind(console)) diff --git a/client/browser/src/extension/scripts/inject.tsx b/client/browser/src/extension/scripts/inject.tsx index f854c73fd84..4b35d9ec9d2 100644 --- a/client/browser/src/extension/scripts/inject.tsx +++ b/client/browser/src/extension/scripts/inject.tsx @@ -5,7 +5,6 @@ import React from 'react' import { Observable, Subscription } from 'rxjs' import { startWith } from 'rxjs/operators' import { setLinkComponent } from '../../../../../shared/src/components/Link' -import { getURL } from '../../browser/extension' import storage from '../../browser/storage' import { StorageItems } from '../../browser/types' import { determineCodeHost as detectCodeHost, injectCodeIntelligenceToCodeHost } from '../../libs/code_intelligence' @@ -78,7 +77,7 @@ async function main(): Promise { styleSheet.id = 'ext-style-sheet' styleSheet.rel = 'stylesheet' styleSheet.type = 'text/css' - styleSheet.href = getURL('css/style.bundle.css') + styleSheet.href = browser.extension.getURL('css/style.bundle.css') document.head.appendChild(styleSheet) } diff --git a/client/browser/src/libs/sentry/index.ts b/client/browser/src/libs/sentry/index.ts index ffeac56fb8c..30ea436c284 100644 --- a/client/browser/src/libs/sentry/index.ts +++ b/client/browser/src/libs/sentry/index.ts @@ -46,9 +46,7 @@ export function initSentry(script: 'content' | 'options' | 'background'): void { return } - const extensionID = chrome.runtime.id - - callSentryInit(extensionID) + callSentryInit(browser.runtime.id) Sentry.configureScope(async scope => { scope.setTag('script', script) diff --git a/client/browser/src/shared/backend/graphql.tsx b/client/browser/src/shared/backend/graphql.tsx index 0a2f3f80645..85e4b28a12f 100644 --- a/client/browser/src/shared/backend/graphql.tsx +++ b/client/browser/src/shared/backend/graphql.tsx @@ -57,17 +57,7 @@ export const requestGraphQL: typeof performRequest = (args: GraphQLRequestArgs) return performRequest(args) } - return from( - new Promise((resolve, reject) => { - chrome.runtime.sendMessage( - { - type: 'requestGraphQL', - payload: args, - }, - ({ err, result }) => (err ? reject(err) : resolve(result)) - ) - }) - ) + return from(browser.runtime.sendMessage({ type: 'requestGraphQL', payload: args })) } function performRequest({ diff --git a/client/browser/src/types/web-ext-types/index.d.ts b/client/browser/src/types/web-ext-types/index.d.ts new file mode 100644 index 00000000000..89ef8e6ac3b --- /dev/null +++ b/client/browser/src/types/web-ext-types/index.d.ts @@ -0,0 +1,3 @@ +declare module 'webextension-polyfill' { + export = browser +} diff --git a/client/browser/tsconfig.json b/client/browser/tsconfig.json index bc1c0fceda9..381e8240237 100644 --- a/client/browser/tsconfig.json +++ b/client/browser/tsconfig.json @@ -1,7 +1,13 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "typeRoots": ["../../shared/src/types", "../../node_modules/@types", "src/types"], + "baseUrl": ".", + "typeRoots": [ + "src/types", + "../../shared/src/types", + "../../node_modules/@types", + "../../node_modules/web-ext-types" + ], "jsx": "react", "resolveJsonModule": true }, diff --git a/package.json b/package.json index 092cc34dfea..6771979aaca 100644 --- a/package.json +++ b/package.json @@ -175,6 +175,7 @@ "typedoc": "^0.14.0", "typescript": "3.5.0-dev.20190406", "utc-version": "^1.1.0", + "web-ext-types": "^3.1.0", "webpack": "^4.28.2", "webpack-dev-server": "^3.1.13", "worker-loader": "^2.0.0", @@ -229,6 +230,7 @@ "utility-types": "^3.4.1", "uuid": "^3.2.1", "webext-domain-permission-toggle": "^0.1.0", + "webextension-polyfill": "^0.4.0", "whatwg-url": "^7.0.0" } } diff --git a/yarn.lock b/yarn.lock index f3d608f43c0..f0d2cddcb83 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15372,6 +15372,11 @@ wcwidth@^1.0.0: dependencies: defaults "^1.0.3" +web-ext-types@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/web-ext-types/-/web-ext-types-3.1.0.tgz#32aab56a3d0f4a3d499d43b4838b3356102d11eb" + integrity sha512-HKVibk040vuhpbOljcIYYYC8GP9w9REbHpquI3im/aoZqoDIRq9DnsHl4Zsg+4Fg3SBnWsnvlIr1rnspV4TdXQ== + web-namespaces@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.2.tgz#c8dc267ab639505276bae19e129dbd6ae72b22b4" @@ -15382,6 +15387,11 @@ webext-domain-permission-toggle@^0.1.0: resolved "https://registry.npmjs.org/webext-domain-permission-toggle/-/webext-domain-permission-toggle-0.1.0.tgz#82c0f611a075958e5b879fd77f69908236615607" integrity sha512-zPwVKYa5EiH0htXedmoAWUaMqU7pOr+4dlzFyGVM64Q0jLVo3V8AVcYOVDKtY+c9qOkhtoSUCGcXCnbs5u8eNg== +webextension-polyfill@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/webextension-polyfill/-/webextension-polyfill-0.4.0.tgz#9cc5a60f0f2bf907a6b349fdd7e61701f54956f9" + integrity sha512-oreMp+EoAo1pzRMigx4jB5jInIpx6NTCySPSjGyLLee/dCIPiRqowCEfbFP8o20wz9SOtNwSsfkaJ9D/tRgpag== + webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"