addonova 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +93 -0
  2. package/bin/index.js +42 -3
  3. package/package.json +24 -2
  4. package/src/commands/init.js +31 -31
  5. package/src/commands/update.js +67 -0
  6. package/src/index.js +1 -0
  7. package/template/config/chrome.js +13 -5
  8. package/template/config/edge.js +14 -6
  9. package/template/config/firefox.js +2 -2
  10. package/template/config/naver.js +14 -6
  11. package/template/config/opera.js +14 -6
  12. package/template/config/thunderbird.js +2 -2
  13. package/template/package.json.tpl +38 -23
  14. package/template/platform/chrome/platform.js +13 -0
  15. package/template/platform/edge/platform.js +14 -0
  16. package/template/platform/naver/platform.js +28 -0
  17. package/template/platform/opera/platform.js +14 -0
  18. package/template/src/_locales/en.i18n +3 -2
  19. package/template/src/assets/icons/128.png +0 -0
  20. package/template/src/assets/icons/32.png +0 -0
  21. package/template/src/assets/icons/48.png +0 -0
  22. package/template/src/assets/icons/64.png +0 -0
  23. package/template/src/js/background.js +6 -1
  24. package/template/src/js/lib/browser.js +263 -0
  25. package/template/src/js/lib/common.js +14 -0
  26. package/template/src/js/lib/config.js +21 -0
  27. package/template/src/js/lib/runtime.js +83 -0
  28. package/template/src/manifest/manifest-firefox.json +10 -7
  29. package/template/src/manifest/manifest.json +10 -7
  30. package/{template → workspace}/tasks/build.js +18 -10
  31. package/{template → workspace}/tasks/bundle-css.js +27 -34
  32. package/{template → workspace}/tasks/bundle-js.js +0 -1
  33. package/{template → workspace}/tasks/cli.js +12 -6
  34. package/{template → workspace}/tasks/copy.js +1 -2
  35. package/{template → workspace}/tasks/paths.js +2 -3
  36. package/{template → workspace}/tasks/zip.js +1 -1
  37. package/{template → workspace}/tools/json2i18n.js +7 -3
  38. package/template/tasks/translate.js +0 -255
  39. /package/template/src/{scss/popup.scss → css/popup.css} +0 -0
  40. /package/{template → workspace}/tasks/bundle-html.js +0 -0
  41. /package/{template → workspace}/tasks/bundle-locales.js +0 -0
  42. /package/{template → workspace}/tasks/bundle-manifest.js +0 -0
  43. /package/{template → workspace}/tasks/folder.js +0 -0
  44. /package/{template → workspace}/tasks/task.js +0 -0
  45. /package/{template → workspace}/tasks/utils.js +0 -0
  46. /package/{template → workspace}/tasks/watch.js +0 -0
  47. /package/{template → workspace}/tools/translate.js +0 -0
@@ -4,36 +4,51 @@
4
4
  "description": "{{description}}",
5
5
  "json.schemaValidation": "off",
6
6
  "license": "GPLv3",
7
- "author": "{{name}}",
7
+ "author": "Addonova",
8
8
  "type": "module",
9
9
  "engines": {
10
10
  "node": ">=22",
11
11
  "npm": ">=11"
12
12
  },
13
13
  "scripts": {
14
- "build": "node --max-old-space-size=3072 workspace/tasks/cli.js build --all --release",
15
- "release": "node workspace/tasks/cli.js build --all --release",
16
- "release:chrome": "node --max-old-space-size=3072 workspace/tasks/cli.js build --chrome --release",
17
- "release:edge": "node --max-old-space-size=3072 workspace/tasks/cli.js build --edge --release",
18
- "release:opera": "node --max-old-space-size=3072 workspace/tasks/cli.js build --opera --release",
19
- "release:naver": "node --max-old-space-size=3072 workspace/tasks/cli.js build --naver --release",
20
- "edge": "node --max-old-space-size=3072 workspace/tasks/cli.js build --edge --release",
21
- "help": "node --max-old-space-size=3072 workspace/tasks/cli.js --help",
22
- "debug": "node --max-old-space-size=3072 workspace/tasks/cli.js build --all --debug",
23
- "debug:chrome": "node --max-old-space-size=3072 workspace/tasks/cli.js build --chrome --debug",
24
- "watch": "node --max-old-space-size=3072 workspace/tasks/cli.js build --all --debug --watch",
25
- "zip": "node --max-old-space-size=3072 workspace/tasks/cli.js zip",
26
- "chrome:watch": "node --max-old-space-size=3072 workspace/tasks/cli.js build --chrome --release --watch",
27
- "locales": "node --max-old-space-size=3072 workspace/tools/translate.js"
14
+ "release": "addonova-release",
15
+ "release:chrome": "addonova-release:chrome",
16
+ "release:edge": "addonova-release:edge",
17
+ "release:opera": "addonova-release:opera",
18
+ "release:firefox": "addonova-release:firefox",
19
+ "release:thunderbird": "addonova-release:thunderbird",
20
+ "release:naver": "addonova-release:naver",
21
+
22
+ "debug": "addonova-debug",
23
+ "debug:chrome": "addonova-debug:chrome",
24
+ "debug:edge": "addonova-debug:edge",
25
+ "debug:opera": "addonova-debug:opera",
26
+ "debug:firefox": "addonova-debug:firefox",
27
+ "debug:thunderbird": "addonova-debug:thunderbird",
28
+ "debug:naver": "addonova-debug:naver",
29
+
30
+ "watch": "addonova-watch",
31
+ "zip": "addonova zip",
32
+
33
+ "addonova-release": "node --max-old-space-size=3072 node_modules/addonova/workspace/tasks/cli.js build --all --release",
34
+ "addonova-release:chrome": "node --max-old-space-size=3072 node_modules/addonova/workspace/tasks/cli.js build --chrome --release",
35
+ "addonova-release:edge": "node --max-old-space-size=3072 node_modules/addonova/workspace/tasks/cli.js build --edge --release",
36
+ "addonova-release:opera": "node --max-old-space-size=3072 node_modules/addonova/workspace/tasks/cli.js build --opera --release",
37
+ "addonova-release:firefox": "node --max-old-space-size=3072 node_modules/addonova/workspace/tasks/cli.js build --firefox --release",
38
+ "addonova-release:thunderbird": "node --max-old-space-size=3072 node_modules/addonova/workspace/tasks/cli.js build --thunderbird --release",
39
+ "addonova-release:naver": "node --max-old-space-size=3072 node_modules/addonova/workspace/tasks/cli.js build --naver --release",
40
+
41
+ "addonova-debug": "node --max-old-space-size=3072 node_modules/addonova/workspace/tasks/cli.js build --all --debug",
42
+ "addonova-debug:chrome": "node --max-old-space-size=3072 node_modules/addonova/workspace/tasks/cli.js build --chrome --debug",
43
+ "addonova-debug:edge": "node --max-old-space-size=3072 node_modules/addonova/workspace/tasks/cli.js build --edge --debug",
44
+ "addonova-debug:opera": "node --max-old-space-size=3072 node_modules/addonova/workspace/tasks/cli.js build --opera --debug",
45
+ "addonova-debug:firefox": "node --max-old-space-size=3072 node_modules/addonova/workspace/tasks/cli.js build --firefox --debug",
46
+ "addonova-debug:thunderbird": "node --max-old-space-size=3072 node_modules/addonova/workspace/tasks/cli.js build --thunderbird --debug",
47
+ "addonova-debug:naver": "node --max-old-space-size=3072 node_modules/addonova/workspace/tasks/cli.js build --naver --debug",
48
+
49
+ "addonova-watch": "node --max-old-space-size=3072 node_modules/addonova/workspace/tasks/cli.js build --all --debug --watch"
28
50
  },
29
51
  "devDependencies": {
30
- "@craftamap/esbuild-plugin-html": "^0.9.0",
31
- "chokidar": "^5.0.0",
32
- "esbuild": "^0.27.3",
33
- "esbuild-sass-plugin": "^3.6.0",
34
- "globals": "^17.4.0",
35
- "globby": "^16.1.0",
36
- "sass": "^1.97.3",
37
- "yazl": "^3.3.1"
52
+ "addonova": "^1.0.0"
38
53
  }
39
54
  }
@@ -0,0 +1,13 @@
1
+ const API = (() => {
2
+ if (typeof browser !== 'undefined') return browser;
3
+ if (typeof chrome !== 'undefined') return chrome;
4
+ throw new Error('Extension API not found');
5
+ })();
6
+
7
+ const LINKS = {
8
+ "support": API.runtime.getManifest().homepage_url,
9
+ "review": `https://chromewebstore.google.com/detail/${API.runtime.id}/reviews`,
10
+ "facebook": "https://www.facebook.com/codehemu/",
11
+ "youtube": "https://www.youtube.com/@CodeHemu",
12
+ "twitter": "https://x.com/CodeHemu"
13
+ };
@@ -0,0 +1,14 @@
1
+ const API = (() => {
2
+ if (typeof browser !== 'undefined') return browser;
3
+ if (typeof chrome !== 'undefined') return chrome;
4
+ throw new Error('Extension API not found');
5
+ })();
6
+
7
+ const LINKS = {
8
+ "support": API.runtime.getManifest().homepage_url,
9
+ "review": `https://microsoftedge.microsoft.com/addons/detail/${API.runtime.id}`,
10
+ "facebook": "https://www.facebook.com/codehemu/",
11
+ "youtube": "https://www.youtube.com/@CodeHemu",
12
+ "twitter": "https://x.com/CodeHemu"
13
+ };
14
+
@@ -0,0 +1,28 @@
1
+ const API = (() => {
2
+ if (typeof browser !== 'undefined') return browser;
3
+ if (typeof chrome !== 'undefined') return chrome;
4
+ throw new Error('Extension API not found');
5
+ })();
6
+
7
+ const LINKS = {
8
+ "support": API.runtime.getManifest().homepage_url,
9
+ "review": `https://store.whale.naver.com/detail/${API.runtime.id}`,
10
+ "facebook": "https://www.facebook.com/codehemu/",
11
+ "youtube": "https://www.youtube.com/@CodeHemu",
12
+ "twitter": "https://x.com/CodeHemu"
13
+ };
14
+
15
+ const DEBOUNCE = (callback, delay) => {
16
+ if (typeof callback !== "function") {
17
+ return false;
18
+ }
19
+
20
+ let timer;
21
+ return function(...args) {
22
+ const context = this;
23
+ clearTimeout(timer);
24
+ timer = setTimeout(function() {
25
+ callback.apply(context, args);
26
+ }, delay);
27
+ };
28
+ };
@@ -0,0 +1,14 @@
1
+ const API = (() => {
2
+ if (typeof browser !== 'undefined') return browser;
3
+ if (typeof chrome !== 'undefined') return chrome;
4
+ throw new Error('Extension API not found');
5
+ })();
6
+
7
+ const LINKS = {
8
+ "support": API.runtime.getManifest().homepage_url,
9
+ "review": "https://addons.opera.com/en/extensions/details/volume-booster-increase-sound/",
10
+ "facebook": "https://www.facebook.com/codehemu/",
11
+ "youtube": "https://www.youtube.com/@CodeHemu",
12
+ "twitter": "https://x.com/CodeHemu"
13
+ };
14
+
@@ -1,4 +1,5 @@
1
1
  @extensionName
2
- {{name}}
2
+ addonova-starter
3
+
3
4
  @extensionDescription
4
- {{description}}
5
+ manifest.json description
Binary file
Binary file
Binary file
@@ -1 +1,6 @@
1
- console.log('Background service worker started');
1
+ importScripts("lib/platform.js");
2
+ importScripts("lib/config.js");
3
+ importScripts("lib/browser.js");
4
+ importScripts("lib/runtime.js");
5
+ importScripts("lib/common.js");
6
+
@@ -0,0 +1,263 @@
1
+ const app = {};
2
+
3
+ app.error = function () {
4
+ return API.runtime.lastError;
5
+ };
6
+
7
+ app.storage = {
8
+ "local": {},
9
+ "read": function (id) {
10
+ return app.storage.local[id];
11
+ },
12
+ "update": function (callback) {
13
+ if (app.session) app.session.load();
14
+ /* */
15
+ API.storage.local.get(null, function (e) {
16
+ app.storage.local = e;
17
+ if (callback) {
18
+ callback("update");
19
+ }
20
+ });
21
+ },
22
+ "write": function (id, data, callback) {
23
+ const tmp = {};
24
+ tmp[id] = data;
25
+ app.storage.local[id] = data;
26
+ /* */
27
+ API.storage.local.set(tmp, function (e) {
28
+ if (callback) {
29
+ callback(e);
30
+ }
31
+ });
32
+ },
33
+ "load": function (callback) {
34
+ const keys = Object.keys(app.storage.local);
35
+ /* */
36
+ if (keys && keys.length) {
37
+ if (callback) {
38
+ callback("cache");
39
+ }
40
+ } else {
41
+ app.storage.update(function () {
42
+ if (callback) callback("disk");
43
+ });
44
+ }
45
+ }
46
+ };
47
+
48
+ app.popup = {
49
+ "port": null,
50
+ "message": {},
51
+ "receive": function(id, callback) {
52
+ if (id) {
53
+ app.popup.message[id] = callback;
54
+ }
55
+ },
56
+ "send": function(id, data) {
57
+ if (id) {
58
+ API.runtime.sendMessage({
59
+ "data": data,
60
+ "method": id,
61
+ "path": "background-to-popup"
62
+ }, app.error);
63
+ }
64
+ },
65
+ "post": function(id, data) {
66
+ if (id) {
67
+ if (app.popup.port) {
68
+ app.popup.port.postMessage({
69
+ "data": data,
70
+ "method": id,
71
+ "path": "background-to-popup"
72
+ });
73
+ }
74
+ }
75
+ }
76
+ };
77
+
78
+ app.window = {
79
+ set id (e) {
80
+ app.storage.write("window.id", e);
81
+ },
82
+ get id () {
83
+ return app.storage.read("window.id") !== undefined ? app.storage.read("window.id") : '';
84
+ },
85
+ "create": function (options, callback) {
86
+ API.windows.create(options, function (e) {
87
+ if (callback) callback(e);
88
+ });
89
+ },
90
+ "get": function (windowId, callback) {
91
+ API.windows.get(windowId, function (e) {
92
+ if (callback) callback(e);
93
+ });
94
+ },
95
+ "update": function (windowId, options, callback) {
96
+ API.windows.update(windowId, options, function (e) {
97
+ if (callback) callback(e);
98
+ });
99
+ },
100
+ "remove": function (windowId, callback) {
101
+ API.windows.remove(windowId, function (e) {
102
+ if (callback) callback(e);
103
+ });
104
+ },
105
+ "query": {
106
+ "current": function (callback) {
107
+ API.windows.getCurrent(callback);
108
+ }
109
+ },
110
+ "on": {
111
+ "removed": function (callback) {
112
+ API.windows.onRemoved.addListener(function (e) {
113
+ app.storage.load(function () {
114
+ callback(e);
115
+ });
116
+ });
117
+ }
118
+ }
119
+ };
120
+
121
+ app.on = {
122
+ "management": function (callback) {
123
+ API.management.getSelf(callback);
124
+ },
125
+ "uninstalled": function (url) {
126
+ API.runtime.setUninstallURL(url, function () {
127
+ if (app.error()) {
128
+ console.error("Error setting uninstall URL:", app.error());
129
+ }
130
+ });
131
+ },
132
+ "installed": function (callback) {
133
+ API.runtime.onInstalled.addListener(function (e) {
134
+ app.storage.load(function () {
135
+ callback(e);
136
+ });
137
+ });
138
+ },
139
+ "startup": function (callback) {
140
+ API.runtime.onStartup.addListener(function (e) {
141
+ app.storage.load(function () {
142
+ callback(e);
143
+ });
144
+ });
145
+ },
146
+ "connect": function (callback) {
147
+ API.runtime.onConnect.addListener(function (e) {
148
+ app.storage.load(function () {
149
+ if (callback) callback(e);
150
+ });
151
+ });
152
+ },
153
+ "storage": function (callback) {
154
+ API.storage.onChanged.addListener(function (changes, namespace) {
155
+ app.storage.update(function () {
156
+ if (callback) {
157
+ callback(changes, namespace);
158
+ }
159
+ });
160
+ });
161
+ },
162
+ "message": function (callback) {
163
+ API.runtime.onMessage.addListener(function (request, sender, sendResponse) {
164
+ app.storage.load(function () {
165
+ callback(request, sender, sendResponse);
166
+ });
167
+ return true;
168
+ });
169
+ }
170
+ };
171
+
172
+ app.tab = {
173
+ "get": function (tabId, callback) {
174
+ API.tabs.get(tabId, function (e) {
175
+ if (callback) callback(e);
176
+ });
177
+ },
178
+ "remove": function (tabId, callback) {
179
+ API.tabs.remove(tabId, function (e) {
180
+ if (callback) callback(e);
181
+ });
182
+ },
183
+ "query": {
184
+ "index": function (callback) {
185
+ API.tabs.query({"active": true, "currentWindow": true}, function (tabs) {
186
+ if (tabs && tabs.length) {
187
+ callback(tabs[0].index);
188
+ } else callback(undefined);
189
+ });
190
+ }
191
+ },
192
+ "update": function (tabId, options, callback) {
193
+ if (tabId) {
194
+ API.tabs.update(tabId, options, function (e) {
195
+ if (callback) callback(e);
196
+ });
197
+ } else {
198
+ API.tabs.update(options, function (e) {
199
+ if (callback) callback(e);
200
+ });
201
+ }
202
+ },
203
+ "open": function (url, index, active, pinned, callback) {
204
+ const properties = {
205
+ "url": url,
206
+ "active": active !== undefined ? active : true,
207
+ "pinned": active !== undefined ? pinned : false
208
+ };
209
+ /* */
210
+ if (index !== undefined) {
211
+ if (typeof index === "number") {
212
+ properties.index = index + 1;
213
+ }
214
+ }
215
+ /* */
216
+ API.tabs.create(properties, function (tab) {
217
+ if (callback) callback(tab);
218
+ });
219
+ },
220
+ "on": {
221
+ "remove": function (callback) {
222
+ API.tabs.onRemoved.addListener(function (e) {
223
+ app.storage.load(function () {
224
+ callback(e);
225
+ });
226
+ });
227
+ }
228
+ }
229
+ };
230
+
231
+
232
+ app.interface = {
233
+ "path": chrome.runtime.getURL("data/interface/popup.html"),
234
+ set id(e) {
235
+ app.storage.write("interface.id", e);
236
+ },
237
+ get id() {
238
+ return app.storage.read("interface.id") !== undefined ? app.storage.read("interface.id") : '';
239
+ },
240
+ "create": function(url, callback) {
241
+ app.window.query.current(function(win) {
242
+ app.window.id = win.id;
243
+ url = url ? url : app.interface.path;
244
+ /* */
245
+ const width = config.interface.size.width;
246
+ const height = config.interface.size.height;
247
+ const top = config.interface.size.top || (win.top + Math.round((win.height - height) / 2));
248
+ const left = config.interface.size.left || (win.left + Math.round((win.width - width) / 2));
249
+ /* */
250
+ app.window.create({
251
+ "url": url,
252
+ "top": top,
253
+ "left": left,
254
+ "width": width,
255
+ "type": "popup",
256
+ "height": height
257
+ }, function(e) {
258
+ app.interface.id = e.id;
259
+ if (callback) callback(true);
260
+ });
261
+ });
262
+ }
263
+ };
@@ -0,0 +1,14 @@
1
+ var core = {
2
+ "start": function() {
3
+ core.load();
4
+ },
5
+ "install": function() {
6
+ core.load();
7
+ },
8
+ "load": function() {
9
+
10
+ }
11
+ };
12
+
13
+ app.on.startup(core.start);
14
+ app.on.installed(core.install);
@@ -0,0 +1,21 @@
1
+ const config = {};
2
+
3
+ config.welcome = {
4
+ set lastupdate (val) {app.storage.write("lastupdate", val)},
5
+ get lastupdate () {return app.storage.read("lastupdate") !== undefined ? app.storage.read("lastupdate") : 0}
6
+ };
7
+
8
+
9
+ config.interface = {
10
+ set size (val) {app.storage.write("interface.size", val)},
11
+ set context (val) {app.storage.write("interface.context", val)},
12
+ get size () {return app.storage.read("interface.size") !== undefined ? app.storage.read("interface.size") : config.interface.default.size},
13
+ get context () {return app.storage.read("interface.context") !== undefined ? app.storage.read("interface.context") : config.interface.default.context},
14
+ "default": {
15
+ "context": "win",
16
+ "size": {
17
+ "width": 425,
18
+ "height": 575
19
+ }
20
+ }
21
+ };
@@ -0,0 +1,83 @@
1
+ app.version = function () {
2
+ return API.runtime.getManifest().version;
3
+ };
4
+
5
+ if (!navigator.webdriver) {
6
+ app.on.uninstalled(LINKS.support);
7
+ app.on.installed(function(e) {
8
+ app.on.management(function(result) {
9
+ if (result.installType === "normal") {
10
+ app.tab.query.index(function(index) {
11
+ const previous = e.previousVersion !== undefined && e.previousVersion !== app.version();
12
+ const doupdate = previous && parseInt((Date.now() - config.welcome.lastupdate) / (24 * 3600 * 1000)) > 45;
13
+ if (e.reason === "install" || (e.reason === "update" && doupdate)) {
14
+ app.tab.open(LINKS.support, index, e.reason === "install");
15
+ config.welcome.lastupdate = Date.now();
16
+ }
17
+ });
18
+ }
19
+ });
20
+ });
21
+ }
22
+
23
+ app.on.message(function(request, sender) {
24
+ if (request) {
25
+ if (request.path === "popup-to-background") {
26
+ for (const id in app.popup.message) {
27
+ if (app.popup.message[id]) {
28
+ if ((typeof app.popup.message[id]) === "function") {
29
+ if (id === request.method) {
30
+ app.popup.message[id](request.data);
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
36
+ }
37
+ });
38
+
39
+ app.on.connect(function(port) {
40
+ if (port) {
41
+ if (port.name) {
42
+ if (port.name in app) {
43
+ app[port.name].port = port;
44
+ }
45
+ }
46
+ /* */
47
+ port.onDisconnect.addListener(function(e) {
48
+ app.storage.load(function() {
49
+ if (e) {
50
+ if (e.name) {
51
+ if (e.name in app) {
52
+ app[e.name].port = null;
53
+ }
54
+ }
55
+ }
56
+ });
57
+ });
58
+ /* */
59
+ port.onMessage.addListener(function(e) {
60
+ app.storage.load(function() {
61
+ if (e) {
62
+ if (e.path) {
63
+ if (e.port) {
64
+ if (e.port in app) {
65
+ if (e.path === (e.port + "-to-background")) {
66
+ for (const id in app[e.port].message) {
67
+ if (app[e.port].message[id]) {
68
+ if ((typeof app[e.port].message[id]) === "function") {
69
+ if (id === e.method) {
70
+ app[e.port].message[id](e.data);
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ });
81
+ });
82
+ }
83
+ });
@@ -5,21 +5,24 @@
5
5
  "description": "__MSG_extensionDescription__",
6
6
  "default_locale": "en",
7
7
  "icons": {
8
- "16": "assets/icon-16.png",
9
- "48": "assets/icon-48.png",
10
- "128": "assets/icon-128.png"
8
+ "32": "data/icons/32.png",
9
+ "48": "data/icons/48.png",
10
+ "64": "data/icons/64.png",
11
+ "128": "data/icons/128.png"
11
12
  },
12
13
  "action": {
13
- "default_popup": "popup.html",
14
+ "default_popup": "data/interface/popup.html",
14
15
  "default_icon": {
15
- "16": "assets/icon-16.png",
16
- "48": "assets/icon-48.png",
17
- "128": "assets/icon-128.png"
16
+ "32": "data/icons/32.png",
17
+ "48": "data/icons/48.png",
18
+ "64": "data/icons/64.png",
19
+ "128": "data/icons/128.png"
18
20
  }
19
21
  },
20
22
  "background": {
21
23
  "scripts": ["background.js"]
22
24
  },
25
+ "homepage_url": "https://example.com",
23
26
  "browser_specific_settings": {
24
27
  "gecko": {
25
28
  "id": "{{name}}@example.org"
@@ -5,16 +5,19 @@
5
5
  "description": "__MSG_extensionDescription__",
6
6
  "default_locale": "en",
7
7
  "icons": {
8
- "16": "assets/icon-16.png",
9
- "48": "assets/icon-48.png",
10
- "128": "assets/icon-128.png"
8
+ "32": "data/icons/32.png",
9
+ "48": "data/icons/48.png",
10
+ "64": "data/icons/64.png",
11
+ "128": "data/icons/128.png"
11
12
  },
13
+ "homepage_url": "https://example.com",
12
14
  "action": {
13
- "default_popup": "popup.html",
15
+ "default_popup": "data/interface/popup.html",
14
16
  "default_icon": {
15
- "16": "assets/icon-16.png",
16
- "48": "assets/icon-48.png",
17
- "128": "assets/icon-128.png"
17
+ "32": "data/icons/32.png",
18
+ "48": "data/icons/48.png",
19
+ "64": "data/icons/64.png",
20
+ "128": "data/icons/128.png"
18
21
  }
19
22
  },
20
23
  "background": {