diff --git a/packages/extension/package.json b/packages/extension/package.json index d50c057e0cf..84708736ec3 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -11,6 +11,8 @@ }, "devDependencies": { "@types/chrome": "^0.0.86", + "@types/firefox-webext-browser": "^67.0.1", + "extensionizer": "^1.0.1", "extract-loader": "^3.1.0", "file-loader": "^3.0.1", "html-loader": "^0.5.5" diff --git a/packages/extension/src/background/ChromeStore.ts b/packages/extension/src/background/ChromeStore.ts index 4e344297fdb..72a38e4a0c1 100644 --- a/packages/extension/src/background/ChromeStore.ts +++ b/packages/extension/src/background/ChromeStore.ts @@ -1,20 +1,22 @@ -// Copyright 2019 @polkadot/extension-bg authors & contributors +// Copyright 2019 @polkadot/extension authors & contributors // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. import { KeyringStore } from '@polkadot/ui-keyring/types'; +import extension from 'extensionizer'; + const lastError = (type: string): void => { - const error = chrome.runtime.lastError; + const error = extension.runtime.lastError; if (error) { - console.error(`ChromeStore.${type}:: chrome.runtime.lastError:`, error); + console.error(`ChromeStore.${type}:: runtime.lastError:`, error); } }; export default class ChromeStore implements KeyringStore { all (cb: (key: string, value: any) => void): void { - chrome.storage.local.get(null, (result: { [index: string]: any }) => { + extension.storage.local.get(null, (result: { [index: string]: any }) => { lastError('all'); Object.entries(result).forEach(([key, value]) => @@ -24,7 +26,7 @@ export default class ChromeStore implements KeyringStore { } get (key: string, cb: (value: any) => void): void { - chrome.storage.local.get([key], (result: { [index: string]: any }) => { + extension.storage.local.get([key], (result: { [index: string]: any }) => { lastError('get'); cb(result[key]); @@ -32,7 +34,7 @@ export default class ChromeStore implements KeyringStore { } remove (key: string, cb?: () => void): void { - chrome.storage.local.remove(key, () => { + extension.storage.local.remove(key, () => { lastError('remove'); cb && cb(); @@ -47,7 +49,7 @@ export default class ChromeStore implements KeyringStore { return; } - chrome.storage.local.set({ [key]: value }, () => { + extension.storage.local.set({ [key]: value }, () => { lastError('set'); cb && cb(); diff --git a/packages/extension/src/background/handlers/Extension.ts b/packages/extension/src/background/handlers/Extension.ts index cc79c556509..f00b454ee6f 100644 --- a/packages/extension/src/background/handlers/Extension.ts +++ b/packages/extension/src/background/handlers/Extension.ts @@ -1,4 +1,4 @@ -// Copyright 2019 @polkadot/extension-bg authors & contributors +// Copyright 2019 @polkadot/extension authors & contributors // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. diff --git a/packages/extension/src/background/handlers/State.ts b/packages/extension/src/background/handlers/State.ts index 7206efbef32..934cc56e76e 100644 --- a/packages/extension/src/background/handlers/State.ts +++ b/packages/extension/src/background/handlers/State.ts @@ -4,6 +4,7 @@ import { AuthorizeRequest, MessageAuthorize, MessageExtrinsicSign, MessageExtrinsicSign$Response, SigningRequest } from '../types'; +import extension from 'extensionizer'; import { assert } from '@polkadot/util'; type AuthRequest = { @@ -115,7 +116,7 @@ export default class State { : (signCount ? `${signCount}` : '') ); - chrome.browserAction.setBadgeText({ text }); + extension.browserAction.setBadgeText({ text }); } async authorizeUrl (url: string, request: MessageAuthorize): Promise { diff --git a/packages/extension/src/background/handlers/Tabs.ts b/packages/extension/src/background/handlers/Tabs.ts index cb3c4a01e1a..b1bb167dc32 100644 --- a/packages/extension/src/background/handlers/Tabs.ts +++ b/packages/extension/src/background/handlers/Tabs.ts @@ -1,4 +1,4 @@ -// Copyright 2019 @polkadot/extension-bg authors & contributors +// Copyright 2019 @polkadot/extension authors & contributors // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. diff --git a/packages/extension/src/background/handlers/index.ts b/packages/extension/src/background/handlers/index.ts index 124a1934b81..6d974767d2f 100644 --- a/packages/extension/src/background/handlers/index.ts +++ b/packages/extension/src/background/handlers/index.ts @@ -1,4 +1,4 @@ -// Copyright 2019 @polkadot/extension-bg authors & contributors +// Copyright 2019 @polkadot/extension authors & contributors // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. diff --git a/packages/extension/src/background/index.ts b/packages/extension/src/background/index.ts index b2953dcb0f6..d6bbfbfc4c2 100644 --- a/packages/extension/src/background/index.ts +++ b/packages/extension/src/background/index.ts @@ -1,7 +1,9 @@ -// Copyright 2019 @polkadot/extension-bg authors & contributors +// Copyright 2019 @polkadot/extension authors & contributors // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. +import extension from 'extensionizer'; + // Runs in the extension background, handling all keyring access import keyring from '@polkadot/ui-keyring'; @@ -10,8 +12,8 @@ import { cryptoWaitReady } from '@polkadot/util-crypto'; import ChromeStore from './ChromeStore'; import handlers from './handlers'; -chrome.browserAction.setBadgeBackgroundColor({ color: '#ff0000' }); -chrome.runtime.onMessage.addListener(handlers); +extension.browserAction.setBadgeBackgroundColor({ color: '#ff0000' }); +extension.runtime.onMessage.addListener(handlers); cryptoWaitReady() .then(() => { diff --git a/packages/extension/src/background/types.ts b/packages/extension/src/background/types.ts index 173f7fd8b03..b2290449182 100644 --- a/packages/extension/src/background/types.ts +++ b/packages/extension/src/background/types.ts @@ -1,4 +1,4 @@ -// Copyright 2019 @polkadot/extension-bg authors & contributors +// Copyright 2019 @polkadot/extension authors & contributors // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. diff --git a/packages/extension/src/events.ts b/packages/extension/src/events.ts index 48b923775ab..8c54d07847d 100644 --- a/packages/extension/src/events.ts +++ b/packages/extension/src/events.ts @@ -1,10 +1,19 @@ -// Copyright 2019 @polkadot/extension-bg authors & contributors +// Copyright 2019 @polkadot/extension authors & contributors // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. +// for FireFox, we need to listent here to allow origin restrictions to not +// be an issue (otherwise we cannot read the properties on the created events) +// const contentDocument = typeof gBrowser !== 'undefined' +// ? gBrowser.selectedBrowser.contentDocument +// : document; +const eventTarget = document; + const events = { request: 'PolkadotJsWebRequest', response: 'PolkadotJsWebResponse' }; +export { eventTarget }; + export default events; diff --git a/packages/extension/src/extensionizer.d.ts b/packages/extension/src/extensionizer.d.ts new file mode 100644 index 00000000000..df4244b2d0a --- /dev/null +++ b/packages/extension/src/extensionizer.d.ts @@ -0,0 +1,15 @@ +// Copyright 2019 @polkadot/extension authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +declare var gBrowser: undefined | { + selectedBrowser: { + contentDocument: Document + } +}; + +declare module 'extensionizer' { + const extensionizer: typeof chrome; + + export default extensionizer; +} diff --git a/packages/extension/src/inject/Accounts.ts b/packages/extension/src/inject/Accounts.ts index d68b61608e4..c4c4e1bb182 100644 --- a/packages/extension/src/inject/Accounts.ts +++ b/packages/extension/src/inject/Accounts.ts @@ -1,4 +1,4 @@ -// Copyright 2019 @polkadot/extension-inject authors & contributors +// Copyright 2019 @polkadot/extension authors & contributors // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. diff --git a/packages/extension/src/inject/Injected.ts b/packages/extension/src/inject/Injected.ts index b9d30d7be69..156a4d8f927 100644 --- a/packages/extension/src/inject/Injected.ts +++ b/packages/extension/src/inject/Injected.ts @@ -1,4 +1,4 @@ -// Copyright 2019 @polkadot/extension-inject authors & contributors +// Copyright 2019 @polkadot/extension authors & contributors // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. diff --git a/packages/extension/src/inject/Signer.ts b/packages/extension/src/inject/Signer.ts index 792483f1173..77a416bbaae 100644 --- a/packages/extension/src/inject/Signer.ts +++ b/packages/extension/src/inject/Signer.ts @@ -1,4 +1,4 @@ -// Copyright 2019 @polkadot/extension-inject authors & contributors +// Copyright 2019 @polkadot/extension authors & contributors // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. diff --git a/packages/extension/src/inject/index.ts b/packages/extension/src/inject/index.ts index 40638e8be71..679b04a7594 100644 --- a/packages/extension/src/inject/index.ts +++ b/packages/extension/src/inject/index.ts @@ -5,7 +5,7 @@ import { MessageTypes } from '../background/types'; import { WindowInjected } from './types'; -import events from '../events'; +import events, { eventTarget } from '../events'; import Injected from './Injected'; // when sending a message from the injector to the expension, we @@ -40,7 +40,7 @@ function sendMessage (message: MessageTypes, request: any = null): Promise } // setup a response listener (events created by the loader for extension responses) -document.addEventListener(events.response, (event) => { +eventTarget.addEventListener(events.response, (event) => { const response = (event as CustomEvent).detail; const promise = callbacks[response.id]; @@ -58,11 +58,14 @@ document.addEventListener(events.response, (event) => { } }); +// small helper with the typescript types, just cast window +const windowInject = window as WindowInjected; + // don't clobber the existing object, we will add it it (or create as needed) -(window as WindowInjected).injectedWeb3 = (window as WindowInjected).injectedWeb3 || {}; +windowInject.injectedWeb3 = windowInject.injectedWeb3 || {}; // add our enable function -(window as WindowInjected).injectedWeb3['polkadot-js'] = { +windowInject.injectedWeb3['polkadot-js'] = { name: 'polkadot-js', // process.env.PKG_NAME as string, version: process.env.PKG_VERSION as string, enable: (origin: string): Promise => diff --git a/packages/extension/src/inject/types.ts b/packages/extension/src/inject/types.ts index ad596ef20b7..6e92f60acc6 100644 --- a/packages/extension/src/inject/types.ts +++ b/packages/extension/src/inject/types.ts @@ -1,4 +1,4 @@ -// Copyright 2019 @polkadot/extension-inject authors & contributors +// Copyright 2019 @polkadot/extension authors & contributors // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. diff --git a/packages/extension/src/loader.ts b/packages/extension/src/loader.ts index 33f136f2753..2dcdf61970c 100644 --- a/packages/extension/src/loader.ts +++ b/packages/extension/src/loader.ts @@ -2,19 +2,22 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import events from './events'; +import extension from 'extensionizer'; + +import events, { eventTarget } from './events'; function sendResponse (detail: any): void { - document.dispatchEvent(new CustomEvent(events.response, { detail })); + // create the custom event, this will be handled on the injection script + eventTarget.dispatchEvent(new CustomEvent(events.response, { detail })); } // Handle all custom events, passing messages to the extension -document.addEventListener(events.request, (event) => { +eventTarget.addEventListener(events.request, (event) => { // get the request as part of the the event detailt const request = (event as CustomEvent).detail; // pass the detail as-is as a message to the extension - chrome.runtime.sendMessage(request, (response) => { + extension.runtime.sendMessage(request, (response) => { if (!response) { // no data, send diconnected/unknown error sendResponse({ id: request.id, error: 'Unknown response' }); @@ -28,7 +31,7 @@ document.addEventListener(events.request, (event) => { // inject our data injector const script = document.createElement('script'); -script.src = chrome.extension.getURL('inject.js'); +script.src = extension.extension.getURL('inject.js'); script.onload = (): void => { // remove the injecting tag when loaded if (script.parentNode) { diff --git a/yarn.lock b/yarn.lock index ff1174abc93..e2822edf705 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2121,6 +2121,11 @@ resolved "https://registry.yarnpkg.com/@types/filewriter/-/filewriter-0.0.28.tgz#c054e8af4d9dd75db4e63abc76f885168714d4b3" integrity sha1-wFTor02d11205jq8dviFFocU1LM= +"@types/firefox-webext-browser@^67.0.1": + version "67.0.1" + resolved "https://registry.yarnpkg.com/@types/firefox-webext-browser/-/firefox-webext-browser-67.0.1.tgz#92e3eb4440b56ab43eb93891ea4a3f33516fa7d7" + integrity sha512-+RE7MDu8EQ5EcQe7i0378oCvu1Sf9fEtRdPakYfdcEr79v7wTpO/meQXv9JLqvy7FwM2/9D8cwV7GyclXgRtxA== + "@types/fs-extra@^5.0.3": version "5.1.0" resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.1.0.tgz#2a325ef97901504a3828718c390d34b8426a10a1" @@ -5666,6 +5671,11 @@ extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== +extensionizer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/extensionizer/-/extensionizer-1.0.1.tgz#504544239a7610ba8404b15c1832091a37768d09" + integrity sha512-UES5CSOYqshNsWFrpORcQR47+ph6UvQK25mguD44IyeMemt40CG+LTZrH1PgpGUHX3w7ACtNQnmM0J+qEe8G0Q== + external-editor@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27"