Skip to content

Commit 1851c80

Browse files
authored
Merge pull request #13 from nextgensparx/improve-browser-support
Add support for browsers that use the WebExtension API
2 parents 0419eed + 6162d65 commit 1851c80

File tree

8 files changed

+122
-8
lines changed

8 files changed

+122
-8
lines changed

README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,59 @@ yarn serve
7575
yarn build
7676
```
7777

78+
## Plugin options
79+
80+
Plugin options can be set inside your `vue.config.js`:
81+
82+
```js
83+
// vue.config.js
84+
module.exports = {
85+
pluginOptions: {
86+
browserExtension: {
87+
options: {
88+
// options...
89+
}
90+
}
91+
}
92+
}
93+
```
94+
95+
- **components**
96+
- Type: `Object.<string, boolean>`
97+
98+
The browser extension components that will be managed by this plugin.
99+
100+
Valid components are:
101+
- popup
102+
- options
103+
- contentScript
104+
- standalone
105+
106+
```js
107+
components: {
108+
popup: true,
109+
contentScript: true
110+
}
111+
```
112+
113+
- **api**
114+
- Type: `'chrome'|'browser'`
115+
- Default: `'browser'`
116+
117+
Browser extension API to use.
118+
119+
- **usePolyfill**
120+
- Type: `boolean`
121+
- Default: `true`
122+
123+
Whether to add [webextension-polyfill](https://github.com/mozilla/webextension-polyfill) to polyfill WebExtension APIs in chrome.
124+
125+
- **autoImportPolyfill**
126+
- Type: `boolean`
127+
- Default: `true`
128+
129+
Whether to auto import `webextension-polyfill` using Webpack's [ProvidePlugin](https://webpack.js.org/plugins/provide-plugin/).
130+
78131

79132
## Testing
80133
This library is following the standard styling of vue projects, and those are really the only tests to perform.

generator/index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ module.exports = (api, options) => {
2929
}
3030
}
3131

32+
if (options.usePolyfill) {
33+
pkg.dependencies['webextension-polyfill'] = '^0.3.0'
34+
pkg.devDependencies = {
35+
'imports-loader': '^0.8.0'
36+
}
37+
}
38+
3239
if (api.hasPlugin('eslint')) {
3340
console.log('Adding eslint config stuffs')
3441
pkg.eslintConfig = eslintConfig

generator/template/base-app/src/background.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import store from './store'
2+
<%_ if (options.usePolyfill && !options.autoImportPolyfill) { -%>
3+
import browser from 'webextension-polyfill'
4+
<%_ } -%>
25

36
<%_ if (options.popupPage) { -%>
4-
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {<%_ } else { -%>
5-
chrome.browserAction.onClicked.addListener(function (tab) {<%_ } -%>
7+
<%- options.api %>.runtime.onMessage.addListener(function (request, sender, sendResponse) {<%_ } else { -%>
8+
<%- options.api %>.browserAction.onClicked.addListener(function (tab) {<%_ } -%>
69
console.log(`Hello ${store.getters.foo}!`)
710

811
<%_ if (options.contentScript) { -%>
9-
chrome.tabs.executeScript({
12+
<%- options.api %>.tabs.executeScript({
1013
file: 'content-script.js',
1114
});
1215
<%_ } -%>

generator/template/base-app/src/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
},
3333
"options_ui": {
3434
"page": "options/options.html",
35-
"chrome_style": true
35+
"<%- options.api %>_style": true
3636
<%_ } -%>
3737
}
3838
}

generator/template/popup/src/popup/router/pages/Index.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33
</template>
44

55
<script>
6+
<%_ if (options.usePolyfill && !options.autoImportPolyfill) { -%>
7+
import browser from 'webextension-polyfill'
8+
<%_ } -%>
9+
610
export default {
711
data () {
812
return {}
913
},
1014
mounted () {
11-
chrome.runtime.sendMessage({});
15+
<%- options.api %>.runtime.sendMessage({})
1216
}
1317
}
1418
</script>

generator/template/standalone/src/standalone/router/pages/Index.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33
</template>
44

55
<script>
6+
<%_ if (options.usePolyfill && !options.autoImportPolyfill) { -%>
7+
import browser from 'webextension-polyfill'
8+
<%_ } -%>
9+
610
export default {
711
data () {
812
return {}
913
},
1014
mounted () {
11-
chrome.runtime.sendMessage({});
15+
<%- options.api %>.runtime.sendMessage({});
1216
}
1317
}
1418
</script>

index.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ const path = require('path')
22
const fs = require('fs')
33
const { exec } = require('child_process')
44
const logger = require('@vue/cli-shared-utils')
5+
const webpack = require('webpack')
56
const CopyWebpackPlugin = require('copy-webpack-plugin')
6-
const ChromeExtensionReloader = require('webpack-chrome-extension-reloader')
77
const ZipPlugin = require('zip-webpack-plugin')
88
const defaultOptions = { components: {} }
99

@@ -32,6 +32,18 @@ module.exports = (api, options) => {
3232
webpackConfig.output.chunkFilename = 'js/[id].[name].js?[hash:8]'
3333
webpackConfig.node.global = false
3434

35+
if (pluginOptions.autoImportPolyfill) {
36+
webpackConfig.plugins.push(new webpack.ProvidePlugin({
37+
'browser': 'webextension-polyfill'
38+
}))
39+
40+
// Workaround for https://github.com/mozilla/webextension-polyfill/issues/68
41+
webpackConfig.module.rules.push({
42+
test: require.resolve('webextension-polyfill', {paths: [appRootPath]}),
43+
use: 'imports-loader?browser=>undefined'
44+
})
45+
}
46+
3547
if (isProduction) {
3648
if (hasKeyFile) {
3749
webpackConfig.plugins.push(new CopyWebpackPlugin([{ from: keyFile, to: 'key.pem' }]))
@@ -84,13 +96,14 @@ module.exports = (api, options) => {
8496
}))
8597
}
8698

87-
if (isDevelopment) {
99+
if (options.api === 'chrome' && isDevelopment) {
88100
const entries = { background: 'background' }
89101

90102
if (pluginOptions.components.contentScript) {
91103
entries.contentScript = 'content-script'
92104
}
93105

106+
const ChromeExtensionReloader = require('webpack-chrome-extension-reloader')
94107
webpackConfig.plugins.push(new ChromeExtensionReloader({ entries }))
95108
}
96109
})

prompts.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,35 @@ module.exports = [
4141

4242
return componentMap
4343
}
44+
},
45+
{
46+
name: 'api',
47+
type: 'list',
48+
default: 'browser',
49+
message: 'Which extension API do you wish to use?',
50+
choices: [
51+
{
52+
name: 'browser (WebExtension)',
53+
value: 'browser'
54+
},
55+
{
56+
name: 'chrome',
57+
value: 'chrome'
58+
}
59+
]
60+
},
61+
{
62+
name: 'usePolyfill',
63+
type: 'confirm',
64+
message: 'Add WebExtension polyfill?',
65+
default: true,
66+
when: answers => answers.api === 'browser'
67+
},
68+
{
69+
name: 'autoImportPolyfill',
70+
type: 'confirm',
71+
message: 'Make polyfill available without import?',
72+
default: true,
73+
when: answers => answers.usePolyfill
4474
}
4575
]

0 commit comments

Comments
 (0)