Add WebExtension API polyfill (#3339)

Start of #3200
This will be an ongoing effort.
This commit is contained in:
Felix Becker 2019-04-10 16:59:35 +02:00 committed by GitHub
parent 079a5c050d
commit 88537f3ebe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 41 additions and 47 deletions

View File

@ -1,3 +0,0 @@
const chrome = global.chrome
export const getURL = (path: string) => chrome.extension.getURL(path)

View File

@ -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 })

View File

@ -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
}

View File

@ -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<void> {
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))

View File

@ -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<void> {
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)
}

View File

@ -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)

View File

@ -57,17 +57,7 @@ export const requestGraphQL: typeof performRequest = (args: GraphQLRequestArgs)
return performRequest(args)
}
return from(
new Promise<any>((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<T extends GQL.IGraphQLResponseRoot>({

View File

@ -0,0 +1,3 @@
declare module 'webextension-polyfill' {
export = browser
}

View File

@ -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
},

View File

@ -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"
}
}

View File

@ -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"