browser-extension-manager 0.0.1 → 1.0.1

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 (34) hide show
  1. package/dist/assets/themes/bootstrap/5.3.3/css/bootstrap.css +12057 -0
  2. package/dist/assets/themes/bootstrap/5.3.3/css/bootstrap.css.map +1 -0
  3. package/dist/assets/themes/bootstrap/5.3.3/js/bootstrap.bundle.js +6314 -0
  4. package/dist/assets/themes/bootstrap/5.3.3/js/bootstrap.bundle.js.map +1 -0
  5. package/dist/assets/themes/bootstrap/5.3.3/js/bootstrap.js +4494 -0
  6. package/dist/assets/themes/bootstrap/5.3.3/js/bootstrap.js.map +1 -0
  7. package/dist/background.js +82 -0
  8. package/dist/build.js +19 -1
  9. package/dist/commands/clean.js +1 -0
  10. package/dist/config/manifest.json +8 -0
  11. package/dist/defaults/src/assets/css/options.scss +9 -0
  12. package/dist/defaults/src/assets/css/popup.scss +12 -0
  13. package/dist/defaults/src/assets/js/options.js +10 -0
  14. package/dist/defaults/src/assets/js/popup.js +3 -0
  15. package/dist/defaults/src/manifest.json +14 -0
  16. package/dist/defaults/src/pages/options.html +6 -1
  17. package/dist/defaults/src/pages/popup.html +6 -1
  18. package/dist/gulp/main.js +2 -1
  19. package/dist/gulp/tasks/_importer.js +35 -0
  20. package/dist/gulp/tasks/_package.js +171 -0
  21. package/dist/gulp/tasks/developmentRebuild.js +3 -2
  22. package/dist/gulp/tasks/distribute.js +3 -1
  23. package/dist/gulp/tasks/icons.js +14 -41
  24. package/dist/gulp/tasks/package.js +95 -46
  25. package/dist/gulp/tasks/sass.js +29 -3
  26. package/dist/gulp/tasks/serve.js +15 -164
  27. package/dist/gulp/tasks/test.js +2 -0
  28. package/dist/gulp/tasks/themes.js +75 -0
  29. package/dist/gulp/tasks/webpack.js +4 -1
  30. package/package.json +3 -3
  31. package/dist/assets/js copy/base.js +0 -7
  32. package/dist/assets/js copy/core.js +0 -81
  33. package/dist/assets/js copy/main.js +0 -10
  34. package/dist/defaults/src/assets/images/icons/icon.png +0 -0
@@ -50,6 +50,9 @@ Manager.prototype.initialize = function () {
50
50
  // Import firebase
51
51
  // importFirebase(self);
52
52
 
53
+ // Setup livereload
54
+ setupLiveReload(self);
55
+
53
56
  // Log
54
57
  self.log('Initialized!', self.version, self.cache.name, self);
55
58
 
@@ -241,6 +244,85 @@ function importFirebase(self) {
241
244
  self.libraries.firebase = firebase;
242
245
  }
243
246
 
247
+ function setupLiveReload(self) {
248
+ // Quit if not in dev mode
249
+ if (self.environment !== 'development') { return };
250
+
251
+ // Setup livereload
252
+ const address = `ws://localhost:{ liveReloadPort }/livereload`;
253
+ let connection;
254
+ let isReconnecting = false; // Flag to track reconnections
255
+
256
+ // Function to establish a connection
257
+ function connect() {
258
+ connection = new WebSocket(address);
259
+
260
+ // Log connection
261
+ self.log(`Reload connecting to ${address}...`);
262
+
263
+ // Log connection errors
264
+ connection.onerror = (e) => {
265
+ self.error('Reload connection got error:', e);
266
+ };
267
+
268
+ // Log when set up correctly
269
+ connection.onopen = () => {
270
+ self.log('Reload connection set up!');
271
+
272
+ // Reload the extension only on reconnections
273
+ if (isReconnecting) {
274
+ // reload();
275
+ }
276
+
277
+ // Reset the reconnection flag
278
+ isReconnecting = false;
279
+ };
280
+
281
+ // Handle connection close and attempt to reconnect
282
+ connection.onclose = () => {
283
+ // Set time
284
+ const seconds = 1;
285
+
286
+ // Log
287
+ self.log(`Reload connection closed. Attempting to reconnect in ${seconds} second(s)...`);
288
+
289
+ // Set the reconnection flag
290
+ isReconnecting = true;
291
+
292
+ // Reconnect
293
+ setTimeout(connect, seconds * 1000); // Retry
294
+ };
295
+
296
+ // Handle incoming messages
297
+ connection.onmessage = function (event) {
298
+ if (!event.data) {
299
+ return;
300
+ }
301
+
302
+ // Get data
303
+ const data = JSON.parse(event.data);
304
+
305
+ // Log
306
+ self.log('Reload connection got message:', data);
307
+
308
+ // Handle reload command
309
+ if (data && data.command === 'reload') {
310
+ reload();
311
+ }
312
+ };
313
+ }
314
+
315
+ function reload() {
316
+ self.log('Reloading extension...');
317
+ setTimeout(() => {
318
+ self.extension.runtime.reload();
319
+ }, 1000);
320
+ }
321
+
322
+ // Start the initial connection
323
+ connect();
324
+ }
325
+
244
326
  function arrayUnique(array) {
245
327
  var a = array.concat();
246
328
 
package/dist/build.js CHANGED
@@ -67,7 +67,7 @@ Manager.prototype.getManifest = Manager.getManifest;
67
67
 
68
68
  // getConfig: requires and parses config.json
69
69
  Manager.getConfig = function () {
70
- return JSON5.parse(jetpack.read(path.join(process.cwd(), 'config.json')));
70
+ return JSON5.parse(jetpack.read(path.join(process.cwd(), 'config', 'config.json')));
71
71
  }
72
72
  Manager.prototype.getConfig = Manager.getConfig;
73
73
 
@@ -82,6 +82,24 @@ Manager.getPackage = function (type) {
82
82
  }
83
83
  Manager.prototype.getPackage = Manager.getPackage;
84
84
 
85
+ // getRootPath: returns the root path of the project or package
86
+ Manager.getRootPath = function (type) {
87
+ return type === 'project'
88
+ ? process.cwd()
89
+ : path.resolve(__dirname, '..')
90
+ }
91
+ Manager.prototype.getRootPath = Manager.getRootPath;
92
+
93
+ // getLiveReloadPort: (35729)
94
+ Manager.getLiveReloadPort = function () {
95
+ // Check if the port is set in the environment
96
+ process.env.BXM_LIVERELOAD_PORT = process.env.BXM_LIVERELOAD_PORT || 35729;
97
+
98
+ // Return the port
99
+ return process.env.BXM_LIVERELOAD_PORT;
100
+ }
101
+ Manager.prototype.getLiveReloadPort = Manager.getLiveReloadPort;
102
+
85
103
  // Require
86
104
  Manager.require = function (path) {
87
105
  return require(path);
@@ -12,6 +12,7 @@ const dirs = [
12
12
  '.temp',
13
13
  'dist',
14
14
  'packaged',
15
+ // 'src/assets/themes',
15
16
  ]
16
17
 
17
18
  module.exports = async function (options) {
@@ -75,4 +75,12 @@
75
75
  pages: [
76
76
  ],
77
77
  },
78
+
79
+ // IDs
80
+ browser_specific_settings: {
81
+ gecko: {
82
+ id: 'my-addon@example.com',
83
+ strict_min_version: '91.0',
84
+ },
85
+ },
78
86
  }
@@ -1,2 +1,11 @@
1
1
  // options.scss
2
2
  // This file contains the styles for the options page of the extension.
3
+
4
+ // Imports
5
+ @import '/node_modules/browser-extension-manager/dist/assets/themes/bootstrap/5.3.3/css/bootstrap.css';
6
+
7
+ // Page size
8
+ body {
9
+ min-width: 400px;
10
+ max-width: 100%;
11
+ }
@@ -1,2 +1,14 @@
1
1
  // popup.scss
2
2
  // This file contains the styles for the popup page of the extension.
3
+
4
+ // Imports
5
+ @import '/node_modules/browser-extension-manager/dist/assets/themes/bootstrap/5.3.3/css/bootstrap.css';
6
+
7
+ // Page size
8
+ body {
9
+ min-width: 400px;
10
+ max-width: 100%;
11
+ }
12
+
13
+
14
+
@@ -0,0 +1,10 @@
1
+ // Import the Ultimate Extension Manager
2
+ const Manager = new (require('browser-extension-manager'));
3
+
4
+ // Import themes
5
+ const bootstrap = require('/node_modules/browser-extension-manager/dist/assets/themes/bootstrap/5.3.3/js/bootstrap.bundle.js');
6
+
7
+ // Initialize
8
+ Manager.initialize(() => {
9
+ console.log('Initialized');
10
+ })
@@ -1,6 +1,9 @@
1
1
  // Import the Ultimate Extension Manager
2
2
  const Manager = new (require('browser-extension-manager'));
3
3
 
4
+ // Import themes
5
+ const bootstrap = require('/node_modules/browser-extension-manager/dist/assets/themes/bootstrap/5.3.3/js/bootstrap.bundle.js');
6
+
4
7
  // Initialize
5
8
  Manager.initialize(() => {
6
9
  console.log('Initialized');
@@ -75,6 +75,12 @@
75
75
 
76
76
  // Commands
77
77
  commands: {
78
+ // test: {
79
+ // description: 'Test',
80
+ // suggested_key: {
81
+ // default: 'Alt+T',
82
+ // },
83
+ // },
78
84
  },
79
85
 
80
86
  // Sandbox
@@ -83,4 +89,12 @@
83
89
  // 'pages/sandbox.html',
84
90
  ],
85
91
  },
92
+
93
+ // IDs
94
+ browser_specific_settings: {
95
+ gecko: {
96
+ // id: 'my-addon@example.com',
97
+ // strict_min_version: '91.0',
98
+ },
99
+ },
86
100
  }
@@ -1,10 +1,13 @@
1
1
  <!doctype html>
2
2
  <html>
3
3
  <head>
4
+ <!-- Meta -->
4
5
  <meta charset="utf-8">
5
- <link href="/assets/css/options.bundle.css" rel="stylesheet">
6
6
  <meta name="viewport" content="width=device-width,initial-scale=1">
7
7
  <title>Options & Settings</title>
8
+
9
+ <!-- CSS -->
10
+ <link href="/assets/css/options.bundle.css" rel="stylesheet">
8
11
  </head>
9
12
  <body class="wrap">
10
13
  <footer class="main-footer">
@@ -16,6 +19,8 @@
16
19
  </div>
17
20
  </div>
18
21
  </footer>
22
+
23
+ <!-- JS -->
19
24
  <script src="/assets/css/options.bundle.js"></script>
20
25
  </body>
21
26
  </html>
@@ -1,10 +1,13 @@
1
1
  <!doctype html>
2
2
  <html>
3
3
  <head>
4
+ <!-- Meta -->
4
5
  <meta charset="utf-8">
5
- <link href="/assets/css/popup.bundle.css" rel="stylesheet">
6
6
  <meta name="viewport" content="width=device-width,initial-scale=1">
7
7
  <title>Popup</title>
8
+
9
+ <!-- CSS -->
10
+ <link href="/assets/css/popup.bundle.css" rel="stylesheet">
8
11
  </head>
9
12
  <body class="wrap">
10
13
  <footer class="main-footer">
@@ -16,6 +19,8 @@
16
19
  </div>
17
20
  </div>
18
21
  </footer>
22
+
23
+ <!-- JS -->
19
24
  <script src="/assets/css/popup.bundle.js"></script>
20
25
  </body>
21
26
  </html>
package/dist/gulp/main.js CHANGED
@@ -14,7 +14,7 @@ const tasks = jetpack.list(path.join(__dirname, 'tasks'));
14
14
 
15
15
  // Init global
16
16
  global.tasks = {};
17
- global.browserSync = null;
17
+ global.websocket = null;
18
18
 
19
19
  // Load tasks
20
20
  tasks.forEach((file) => {
@@ -34,6 +34,7 @@ global.tasks = exports;
34
34
  exports.build = series(
35
35
  // exports.setup,
36
36
  // exports.clean,
37
+ // exports.themes,
37
38
  exports.distribute,
38
39
  parallel(exports.sass, exports.webpack, exports.icons),
39
40
  exports.package,
@@ -0,0 +1,35 @@
1
+ const customAliasImporter = {
2
+ canonicalize(url) {
3
+ if (url.startsWith('@themes/')) {
4
+ const fullPath = path.resolve(
5
+ rootPathProject,
6
+ 'node_modules/browser-extension-manager/dist/assets/themes',
7
+ url.replace('@themes/', '')
8
+ )
9
+
10
+ console.log('🧭 [SASS IMPORTER] canonicalize:', url)
11
+ console.log('✅ [SASS IMPORTER] Resolved to:', fullPath)
12
+
13
+ return new URL(`file://${fullPath}`)
14
+ }
15
+
16
+ return null
17
+ },
18
+
19
+ load(canonicalUrl) {
20
+ const fs = require('fs')
21
+ const filePath = canonicalUrl.pathname
22
+
23
+ console.log('📦 [SASS IMPORTER] Loading file from:', filePath)
24
+
25
+ if (fs.existsSync(filePath)) {
26
+ return {
27
+ contents: fs.readFileSync(filePath, 'utf8'),
28
+ syntax: 'scss'
29
+ }
30
+ }
31
+
32
+ console.log('❌ [SASS IMPORTER] File not found:', filePath)
33
+ return null
34
+ }
35
+ }
@@ -0,0 +1,171 @@
1
+ // Libraries
2
+ const Manager = new (require('../../build.js'));
3
+ const logger = Manager.logger('package');
4
+ const path = require('path');
5
+ const jetpack = require('fs-jetpack');
6
+ const { series, parallel, watch } = require('gulp');
7
+ const { execute, getKeys } = require('node-powertools');
8
+ const JSON5 = require('json5');
9
+
10
+ // Load package
11
+ const package = Manager.getPackage('main');
12
+ const project = Manager.getPackage('project');
13
+ const rootPathPackage = Manager.getRootPath('main');
14
+ const rootPathProject = Manager.getRootPath('project');
15
+
16
+ // Glob
17
+ const input = [
18
+ // Files to include
19
+ 'dist/**/*',
20
+
21
+ // Files to exclude
22
+ // '!dist/**',
23
+ ];
24
+ const output = 'dist';
25
+ const delay = 250;
26
+
27
+ // Supported browsers
28
+ const BROWSERS = ['chrome', 'firefox', 'opera'];
29
+
30
+ // Environment Check
31
+ const targetBrowser = process.env.BROWSER;
32
+ const isSpecificBrowser = targetBrowser && BROWSERS.includes(targetBrowser);
33
+
34
+ // Special Compilation Task for manifest.json with default settings
35
+ async function compileManifest(browser, complete) {
36
+ try {
37
+ const manifestPath = path.join('dist', 'manifest.json');
38
+ const outputPath = path.join('packaged', browser, 'manifest.json');
39
+ const configPath = path.join(rootPathPackage, 'dist', 'config', 'manifest.json');
40
+
41
+ // Read and parse using JSON5
42
+ const manifest = JSON5.parse(jetpack.read(manifestPath));
43
+ const defaultConfig = JSON5.parse(jetpack.read(configPath));
44
+
45
+ // Apply defaults
46
+ getKeys(defaultConfig).forEach(key => {
47
+ const defaultValue = key.split('.').reduce((o, k) => (o || {})[k], defaultConfig);
48
+ const userValue = key.split('.').reduce((o, k) => (o || {})[k], manifest);
49
+
50
+ if (Array.isArray(defaultValue) && Array.isArray(userValue)) {
51
+ // Merge arrays
52
+ const mergedArray = Array.from(new Set([...defaultValue, ...userValue]));
53
+ key.split('.').reduce((o, k, i, arr) => {
54
+ if (i === arr.length - 1) o[k] = mergedArray;
55
+ else o[k] = o[k] || {};
56
+ return o[k];
57
+ }, manifest);
58
+ } else if (userValue === undefined) {
59
+ // Apply default if user value doesn't exist
60
+ key.split('.').reduce((o, k, i, arr) => {
61
+ if (i === arr.length - 1) o[k] = defaultValue;
62
+ else o[k] = o[k] || {};
63
+ return o[k];
64
+ }, manifest);
65
+ }
66
+ });
67
+
68
+ // Save as regular JSON
69
+ jetpack.write(outputPath, JSON.stringify(manifest, null, 2));
70
+
71
+ logger.log(`Manifest compiled with defaults and saved for ${browser}`);
72
+ } catch (e) {
73
+ logger.error(`Error compiling manifest for ${browser}`, e);
74
+ }
75
+ return complete();
76
+ }
77
+
78
+ // Special Compilation Task for _locales
79
+ async function compileLocales(browser, complete) {
80
+ try {
81
+ const localesDir = path.join('dist', '_locales');
82
+ const outputDir = path.join('packaged', browser, '_locales');
83
+
84
+ // Ensure the directory exists
85
+ jetpack.dir(outputDir);
86
+
87
+ // Process each locale file
88
+ jetpack.find(localesDir, { matching: '**/*.json' }).forEach(filePath => {
89
+ const relativePath = path.relative(localesDir, filePath);
90
+ const outputPath = path.join(outputDir, relativePath);
91
+
92
+ // Read and parse using JSON5
93
+ const localeData = JSON5.parse(jetpack.read(filePath));
94
+
95
+ // Save as regular JSON
96
+ jetpack.write(outputPath, JSON.stringify(localeData, null, 2));
97
+
98
+ logger.log(`Locale compiled and saved: ${outputPath}`);
99
+ });
100
+ } catch (e) {
101
+ logger.error(`Error compiling locales for ${browser}`, e);
102
+ }
103
+ return complete();
104
+ }
105
+
106
+ // Package Task for Each Browser
107
+ async function packageBrowser(browser, complete) {
108
+ // Log
109
+ logger.log(`Starting packaging for ${browser}...`);
110
+
111
+ try {
112
+ const outputDir = `packaged/${browser}`;
113
+
114
+ // Ensure the directory exists
115
+ jetpack.dir(outputDir);
116
+
117
+ // Perform any browser-specific adjustments if needed
118
+ // await execute(`npx bxm setup --browser=${browser}`);
119
+
120
+ // Copy files to browser-specific directory
121
+ await execute(`cp -r dist/* ${outputDir}`);
122
+
123
+ // Compile manifest and locales
124
+ await compileManifest(browser, () => {});
125
+ await compileLocales(browser, () => {});
126
+
127
+ // Create packed extension (.zip)
128
+ if (Manager.isBuildMode()) {
129
+ await execute(`zip -r ${outputDir}.zip ${outputDir}`);
130
+ }
131
+
132
+ // Log completion
133
+ logger.log(`Finished packaging for ${browser}`);
134
+ } catch (e) {
135
+ logger.error(`Error packaging for ${browser}`, e);
136
+ }
137
+
138
+ return complete();
139
+ }
140
+
141
+ // Generate tasks for each browser
142
+ const tasks = isSpecificBrowser
143
+ ? [packageBrowser.bind(null, targetBrowser)]
144
+ : BROWSERS.map((browser) => packageBrowser.bind(null, browser));
145
+
146
+ // Watcher Task
147
+ function packageWatcher(complete) {
148
+ // Quit if in build mode
149
+ if (Manager.isBuildMode()) {
150
+ logger.log('[watcher] Skipping watcher in build mode');
151
+ return complete();
152
+ }
153
+
154
+ // Log
155
+ logger.log('[watcher] Watching for changes...');
156
+
157
+ // Watch for changes in the dist folder
158
+ watch(input, { delay: delay }, parallel(...tasks))
159
+ .on('change', function (path) {
160
+ logger.log(`[watcher] File ${path} was changed`);
161
+ });
162
+
163
+ // Complete
164
+ return complete();
165
+ }
166
+
167
+ // Export tasks
168
+ module.exports = series(
169
+ parallel(...tasks),
170
+ packageWatcher
171
+ );
@@ -8,12 +8,13 @@ const { execute } = require('node-powertools');
8
8
  // Load package
9
9
  const package = Manager.getPackage('main');
10
10
  const project = Manager.getPackage('project');
11
+ const rootPathPackage = Manager.getRootPath('main');
12
+ const rootPathProject = Manager.getRootPath('project');
11
13
 
12
14
  // Glob
13
15
  const input = [
14
16
  // Files to include
15
- // `${__dirname}/../../defaults/dist/**/*`,
16
- `${path.join(__dirname, '..', '..', 'defaults/dist')}/**/*`,
17
+ `${rootPathPackage}/dist/defaults/dist/**/*`,
17
18
 
18
19
  // Files to exclude
19
20
  ];
@@ -11,6 +11,8 @@ const { execute } = require('node-powertools');
11
11
  const package = Manager.getPackage('main');
12
12
  const project = Manager.getPackage('project');
13
13
  const manifest = Manager.getManifest();
14
+ const rootPathPackage = Manager.getRootPath('main');
15
+ const rootPathProject = Manager.getRootPath('project');
14
16
 
15
17
  // Glob
16
18
  const input = [
@@ -86,7 +88,7 @@ function customPathTransform() {
86
88
  // Watcher task
87
89
  function distributeWatcher(complete) {
88
90
  // Quit if in build mode
89
- if (process.env.BXM_ === 'true') {
91
+ if (Manager.isBuildMode()) {
90
92
  logger.log('[watcher] Skipping watcher in build mode');
91
93
  return complete();
92
94
  }
@@ -8,13 +8,13 @@ const responsive = require('gulp-responsive-modern');
8
8
  // Load package
9
9
  const package = Manager.getPackage('main');
10
10
  const project = Manager.getPackage('project');
11
+ const rootPathPackage = Manager.getRootPath('main');
12
+ const rootPathProject = Manager.getRootPath('project');
11
13
 
12
14
  // Glob
13
15
  const input = [
14
16
  // Files to include
15
- // 'src/assets/images/**/*.{jpg,jpeg,png}',
16
- // 'src/assets/images/icons/**/*.{jpg,jpeg,png}',
17
- 'src/assets/images/icons/icon.png',
17
+ 'config/icon.{png,svg}',
18
18
 
19
19
  // Files to exclude
20
20
  // '!dist/**',
@@ -24,6 +24,9 @@ const delay = 250;
24
24
 
25
25
  // Main task
26
26
  function icons(complete) {
27
+ // Define sizes
28
+ const sizes = [1024, 512, 256, 128, 48, 32, 16];
29
+
27
30
  // Log
28
31
  logger.log('Starting...');
29
32
 
@@ -65,46 +68,16 @@ function icons(complete) {
65
68
  return src(files)
66
69
  .pipe(
67
70
  responsive({
68
- '**/*.{jpg,jpeg,png}': [
69
- // 1024 resized version in original format
70
- {
71
- width: 1024,
72
- rename: { suffix: '-1024x' }
73
- },
74
- // 512 resized version in original format
75
- {
76
- width: 512,
77
- rename: { suffix: '-512x' }
78
- },
79
- // 256 resized version in original format
80
- {
81
- width: 256,
82
- rename: { suffix: '-256x' }
83
- },
84
- // 128 resized version in original format
85
- {
86
- width: 128,
87
- rename: { suffix: '-128x' }
88
- },
89
- // 48 resized version in original format
90
- {
91
- width: 48,
92
- rename: { suffix: '-48x' }
93
- },
94
- // 32 resized version in original format
95
- {
96
- width: 32,
97
- rename: { suffix: '-32x' }
98
- },
99
- // 16 resized version in original format
100
- {
101
- width: 16,
102
- rename: { suffix: '-16x' }
103
- },
71
+ '**/*.{jpg,jpeg,png,svg}': [
72
+ // Generate configurations dynamically
73
+ ...sizes.map((size) => ({
74
+ width: size,
75
+ rename: { suffix: `-${size}x`, extname: '.png' },
76
+ })),
104
77
  // Original size in original format
105
78
  {
106
- rename: { suffix: '' }
107
- }
79
+ rename: { suffix: '', extname: '.png' },
80
+ },
108
81
  ]
109
82
  }, {
110
83
  quality: 100,