browser-extension-manager 1.0.14 → 1.1.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 (242) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/CLAUDE.md +672 -0
  3. package/TODO.md +3 -0
  4. package/dist/assets/css/browser-extension-manager.scss +18 -0
  5. package/dist/assets/css/components/content/index.scss +5 -0
  6. package/dist/assets/css/components/options/index.scss +5 -0
  7. package/dist/assets/css/components/pages/index.scss +5 -0
  8. package/dist/assets/css/components/popup/index.scss +5 -0
  9. package/dist/assets/css/core/_animations.scss +64 -0
  10. package/dist/assets/css/core/_initialize.scss +23 -0
  11. package/dist/assets/css/core/_utilities.scss +80 -0
  12. package/dist/assets/themes/_template/_theme.js +5 -0
  13. package/dist/assets/themes/_template/_theme.scss +5 -0
  14. package/dist/assets/themes/bootstrap/_theme.js +16 -0
  15. package/dist/assets/themes/bootstrap/_theme.scss +232 -0
  16. package/dist/assets/themes/bootstrap/js/index.esm.js +19 -0
  17. package/dist/assets/themes/bootstrap/js/index.umd.js +34 -0
  18. package/dist/assets/themes/bootstrap/js/src/alert.js +87 -0
  19. package/dist/assets/themes/bootstrap/js/src/base-component.js +86 -0
  20. package/dist/assets/themes/bootstrap/js/src/button.js +72 -0
  21. package/dist/assets/themes/bootstrap/js/src/carousel.js +474 -0
  22. package/dist/assets/themes/bootstrap/js/src/collapse.js +297 -0
  23. package/dist/assets/themes/bootstrap/js/src/dom/data.js +55 -0
  24. package/dist/assets/themes/bootstrap/js/src/dom/event-handler.js +317 -0
  25. package/dist/assets/themes/bootstrap/js/src/dom/manipulator.js +71 -0
  26. package/dist/assets/themes/bootstrap/js/src/dom/selector-engine.js +126 -0
  27. package/dist/assets/themes/bootstrap/js/src/dropdown.js +458 -0
  28. package/dist/assets/themes/bootstrap/js/src/modal.js +378 -0
  29. package/dist/assets/themes/bootstrap/js/src/offcanvas.js +282 -0
  30. package/dist/assets/themes/bootstrap/js/src/popover.js +97 -0
  31. package/dist/assets/themes/bootstrap/js/src/scrollspy.js +296 -0
  32. package/dist/assets/themes/bootstrap/js/src/tab.js +315 -0
  33. package/dist/assets/themes/bootstrap/js/src/toast.js +224 -0
  34. package/dist/assets/themes/bootstrap/js/src/tooltip.js +632 -0
  35. package/dist/assets/themes/bootstrap/js/src/util/backdrop.js +151 -0
  36. package/dist/assets/themes/bootstrap/js/src/util/component-functions.js +35 -0
  37. package/dist/assets/themes/bootstrap/js/src/util/config.js +65 -0
  38. package/dist/assets/themes/bootstrap/js/src/util/focustrap.js +115 -0
  39. package/dist/assets/themes/bootstrap/js/src/util/index.js +306 -0
  40. package/dist/assets/themes/bootstrap/js/src/util/sanitizer.js +117 -0
  41. package/dist/assets/themes/bootstrap/js/src/util/scrollbar.js +114 -0
  42. package/dist/assets/themes/bootstrap/js/src/util/swipe.js +146 -0
  43. package/dist/assets/themes/bootstrap/js/src/util/template-factory.js +160 -0
  44. package/dist/assets/themes/bootstrap/scss/_accordion.scss +153 -0
  45. package/dist/assets/themes/bootstrap/scss/_alert.scss +68 -0
  46. package/dist/assets/themes/bootstrap/scss/_badge.scss +38 -0
  47. package/dist/assets/themes/bootstrap/scss/_breadcrumb.scss +40 -0
  48. package/dist/assets/themes/bootstrap/scss/_button-group.scss +147 -0
  49. package/dist/assets/themes/bootstrap/scss/_buttons.scss +216 -0
  50. package/dist/assets/themes/bootstrap/scss/_card.scss +238 -0
  51. package/dist/assets/themes/bootstrap/scss/_carousel.scss +226 -0
  52. package/dist/assets/themes/bootstrap/scss/_close.scss +66 -0
  53. package/dist/assets/themes/bootstrap/scss/_containers.scss +41 -0
  54. package/dist/assets/themes/bootstrap/scss/_dropdown.scss +250 -0
  55. package/dist/assets/themes/bootstrap/scss/_forms.scss +9 -0
  56. package/dist/assets/themes/bootstrap/scss/_functions.scss +302 -0
  57. package/dist/assets/themes/bootstrap/scss/_grid.scss +39 -0
  58. package/dist/assets/themes/bootstrap/scss/_helpers.scss +12 -0
  59. package/dist/assets/themes/bootstrap/scss/_images.scss +42 -0
  60. package/dist/assets/themes/bootstrap/scss/_list-group.scss +199 -0
  61. package/dist/assets/themes/bootstrap/scss/_maps.scss +174 -0
  62. package/dist/assets/themes/bootstrap/scss/_mixins.scss +42 -0
  63. package/dist/assets/themes/bootstrap/scss/_modal.scss +240 -0
  64. package/dist/assets/themes/bootstrap/scss/_nav.scss +197 -0
  65. package/dist/assets/themes/bootstrap/scss/_navbar.scss +289 -0
  66. package/dist/assets/themes/bootstrap/scss/_offcanvas.scss +147 -0
  67. package/dist/assets/themes/bootstrap/scss/_pagination.scss +109 -0
  68. package/dist/assets/themes/bootstrap/scss/_placeholders.scss +51 -0
  69. package/dist/assets/themes/bootstrap/scss/_popover.scss +196 -0
  70. package/dist/assets/themes/bootstrap/scss/_progress.scss +68 -0
  71. package/dist/assets/themes/bootstrap/scss/_reboot.scss +611 -0
  72. package/dist/assets/themes/bootstrap/scss/_root.scss +187 -0
  73. package/dist/assets/themes/bootstrap/scss/_spinners.scss +85 -0
  74. package/dist/assets/themes/bootstrap/scss/_tables.scss +171 -0
  75. package/dist/assets/themes/bootstrap/scss/_toasts.scss +73 -0
  76. package/dist/assets/themes/bootstrap/scss/_tooltip.scss +119 -0
  77. package/dist/assets/themes/bootstrap/scss/_transitions.scss +27 -0
  78. package/dist/assets/themes/bootstrap/scss/_type.scss +106 -0
  79. package/dist/assets/themes/bootstrap/scss/_utilities.scss +806 -0
  80. package/dist/assets/themes/bootstrap/scss/_variables-dark.scss +102 -0
  81. package/dist/assets/themes/bootstrap/scss/_variables.scss +1753 -0
  82. package/dist/assets/themes/bootstrap/scss/bootstrap-grid.scss +62 -0
  83. package/dist/assets/themes/bootstrap/scss/bootstrap-reboot.scss +10 -0
  84. package/dist/assets/themes/bootstrap/scss/bootstrap-utilities.scss +19 -0
  85. package/dist/assets/themes/bootstrap/scss/bootstrap.scss +52 -0
  86. package/dist/assets/themes/bootstrap/scss/forms/_floating-labels.scss +97 -0
  87. package/dist/assets/themes/bootstrap/scss/forms/_form-check.scss +189 -0
  88. package/dist/assets/themes/bootstrap/scss/forms/_form-control.scss +214 -0
  89. package/dist/assets/themes/bootstrap/scss/forms/_form-range.scss +91 -0
  90. package/dist/assets/themes/bootstrap/scss/forms/_form-select.scss +80 -0
  91. package/dist/assets/themes/bootstrap/scss/forms/_form-text.scss +11 -0
  92. package/dist/assets/themes/bootstrap/scss/forms/_input-group.scss +132 -0
  93. package/dist/assets/themes/bootstrap/scss/forms/_labels.scss +36 -0
  94. package/dist/assets/themes/bootstrap/scss/forms/_validation.scss +12 -0
  95. package/dist/assets/themes/bootstrap/scss/helpers/_clearfix.scss +3 -0
  96. package/dist/assets/themes/bootstrap/scss/helpers/_color-bg.scss +7 -0
  97. package/dist/assets/themes/bootstrap/scss/helpers/_colored-links.scss +30 -0
  98. package/dist/assets/themes/bootstrap/scss/helpers/_focus-ring.scss +5 -0
  99. package/dist/assets/themes/bootstrap/scss/helpers/_icon-link.scss +25 -0
  100. package/dist/assets/themes/bootstrap/scss/helpers/_position.scss +36 -0
  101. package/dist/assets/themes/bootstrap/scss/helpers/_ratio.scss +26 -0
  102. package/dist/assets/themes/bootstrap/scss/helpers/_stacks.scss +15 -0
  103. package/dist/assets/themes/bootstrap/scss/helpers/_stretched-link.scss +15 -0
  104. package/dist/assets/themes/bootstrap/scss/helpers/_text-truncation.scss +7 -0
  105. package/dist/assets/themes/bootstrap/scss/helpers/_visually-hidden.scss +8 -0
  106. package/dist/assets/themes/bootstrap/scss/helpers/_vr.scss +8 -0
  107. package/dist/assets/themes/bootstrap/scss/mixins/_alert.scss +18 -0
  108. package/dist/assets/themes/bootstrap/scss/mixins/_backdrop.scss +14 -0
  109. package/dist/assets/themes/bootstrap/scss/mixins/_banner.scss +7 -0
  110. package/dist/assets/themes/bootstrap/scss/mixins/_border-radius.scss +78 -0
  111. package/dist/assets/themes/bootstrap/scss/mixins/_box-shadow.scss +18 -0
  112. package/dist/assets/themes/bootstrap/scss/mixins/_breakpoints.scss +127 -0
  113. package/dist/assets/themes/bootstrap/scss/mixins/_buttons.scss +70 -0
  114. package/dist/assets/themes/bootstrap/scss/mixins/_caret.scss +69 -0
  115. package/dist/assets/themes/bootstrap/scss/mixins/_clearfix.scss +9 -0
  116. package/dist/assets/themes/bootstrap/scss/mixins/_color-mode.scss +21 -0
  117. package/dist/assets/themes/bootstrap/scss/mixins/_color-scheme.scss +7 -0
  118. package/dist/assets/themes/bootstrap/scss/mixins/_container.scss +11 -0
  119. package/dist/assets/themes/bootstrap/scss/mixins/_deprecate.scss +10 -0
  120. package/dist/assets/themes/bootstrap/scss/mixins/_forms.scss +163 -0
  121. package/dist/assets/themes/bootstrap/scss/mixins/_gradients.scss +47 -0
  122. package/dist/assets/themes/bootstrap/scss/mixins/_grid.scss +151 -0
  123. package/dist/assets/themes/bootstrap/scss/mixins/_image.scss +16 -0
  124. package/dist/assets/themes/bootstrap/scss/mixins/_list-group.scss +26 -0
  125. package/dist/assets/themes/bootstrap/scss/mixins/_lists.scss +7 -0
  126. package/dist/assets/themes/bootstrap/scss/mixins/_pagination.scss +10 -0
  127. package/dist/assets/themes/bootstrap/scss/mixins/_reset-text.scss +17 -0
  128. package/dist/assets/themes/bootstrap/scss/mixins/_resize.scss +6 -0
  129. package/dist/assets/themes/bootstrap/scss/mixins/_table-variants.scss +24 -0
  130. package/dist/assets/themes/bootstrap/scss/mixins/_text-truncate.scss +8 -0
  131. package/dist/assets/themes/bootstrap/scss/mixins/_transition.scss +26 -0
  132. package/dist/assets/themes/bootstrap/scss/mixins/_utilities.scss +97 -0
  133. package/dist/assets/themes/bootstrap/scss/mixins/_visually-hidden.scss +38 -0
  134. package/dist/assets/themes/bootstrap/scss/tests/jasmine.js +16 -0
  135. package/dist/assets/themes/bootstrap/scss/tests/mixins/_auto-import-of-variables-dark.test.scss +7 -0
  136. package/dist/assets/themes/bootstrap/scss/tests/mixins/_color-modes.test.scss +69 -0
  137. package/dist/assets/themes/bootstrap/scss/tests/mixins/_media-query-color-mode-full.test.scss +8 -0
  138. package/dist/assets/themes/bootstrap/scss/tests/mixins/_utilities.test.scss +393 -0
  139. package/dist/assets/themes/bootstrap/scss/tests/sass-true/register.js +14 -0
  140. package/dist/assets/themes/bootstrap/scss/tests/sass-true/runner.js +17 -0
  141. package/dist/assets/themes/bootstrap/scss/tests/utilities/_api.test.scss +75 -0
  142. package/dist/assets/themes/bootstrap/scss/utilities/_api.scss +47 -0
  143. package/dist/assets/themes/bootstrap/scss/vendor/_rfs.scss +348 -0
  144. package/dist/assets/themes/classy/README.md +75 -0
  145. package/dist/assets/themes/classy/_config.scss +185 -0
  146. package/dist/assets/themes/classy/_theme.js +29 -0
  147. package/dist/assets/themes/classy/_theme.scss +34 -0
  148. package/dist/assets/themes/classy/css/base/_animations.scss +27 -0
  149. package/dist/assets/themes/classy/css/base/_backgrounds.scss +191 -0
  150. package/dist/assets/themes/classy/css/base/_borders.scss +65 -0
  151. package/dist/assets/themes/classy/css/base/_root.scss +58 -0
  152. package/dist/assets/themes/classy/css/base/_soft-colors.scss +92 -0
  153. package/dist/assets/themes/classy/css/base/_spacing.scss +64 -0
  154. package/dist/assets/themes/classy/css/base/_typography.scss +179 -0
  155. package/dist/assets/themes/classy/css/base/_utilities.scss +77 -0
  156. package/dist/assets/themes/classy/css/components/_accordion.scss +33 -0
  157. package/dist/assets/themes/classy/css/components/_avatars.scss +32 -0
  158. package/dist/assets/themes/classy/css/components/_badges.scss +25 -0
  159. package/dist/assets/themes/classy/css/components/_buttons.scss +397 -0
  160. package/dist/assets/themes/classy/css/components/_cards.scss +33 -0
  161. package/dist/assets/themes/classy/css/components/_carousel.scss +41 -0
  162. package/dist/assets/themes/classy/css/components/_forms.scss +115 -0
  163. package/dist/assets/themes/classy/css/components/_links.scss +19 -0
  164. package/dist/assets/themes/classy/css/components/_logo-scroll.scss +57 -0
  165. package/dist/assets/themes/classy/css/components/_spinners.scss +19 -0
  166. package/dist/assets/themes/classy/css/components/_text.scss +41 -0
  167. package/dist/assets/themes/classy/css/layout/_blog.scss +42 -0
  168. package/dist/assets/themes/classy/css/layout/_general.scss +139 -0
  169. package/dist/assets/themes/classy/css/layout/_navigation.scss +576 -0
  170. package/dist/assets/themes/classy/css/layout/_team.scss +18 -0
  171. package/dist/assets/themes/classy/js/logo-scroll.js +83 -0
  172. package/dist/assets/themes/classy/js/navbar-scroll.js +65 -0
  173. package/dist/background.js +235 -261
  174. package/dist/build.js +93 -4
  175. package/dist/commands/setup.js +0 -268
  176. package/dist/config/manifest.json +11 -3
  177. package/dist/config/page-template.html +24 -0
  178. package/dist/defaults/.nvmrc +1 -1
  179. package/dist/defaults/CLAUDE.md +8 -0
  180. package/dist/defaults/config/browser-extension-manager.json +37 -0
  181. package/dist/defaults/src/assets/css/components/content/index.scss +11 -0
  182. package/dist/defaults/src/assets/css/components/options/index.scss +14 -0
  183. package/dist/defaults/src/assets/css/components/pages/index.scss +10 -0
  184. package/dist/defaults/src/assets/css/components/popup/index.scss +10 -0
  185. package/dist/defaults/src/assets/css/components/sidepanel/index.scss +6 -0
  186. package/dist/defaults/src/assets/css/main.scss +32 -0
  187. package/dist/defaults/src/assets/js/components/background/index.js +22 -0
  188. package/dist/defaults/src/assets/js/components/content/index.js +22 -0
  189. package/dist/defaults/src/assets/js/components/options/index.js +22 -0
  190. package/dist/defaults/src/assets/js/components/pages/index.js +22 -0
  191. package/dist/defaults/src/assets/js/components/popup/index.js +22 -0
  192. package/dist/defaults/src/assets/js/components/sidepanel/index.js +20 -0
  193. package/dist/defaults/src/assets/vendor/.gitkeep +0 -0
  194. package/dist/defaults/src/manifest.json +11 -6
  195. package/dist/defaults/src/views/options/index.html +8 -0
  196. package/dist/defaults/src/views/pages/index.html +10 -0
  197. package/dist/defaults/src/views/popup/index.html +4 -0
  198. package/dist/defaults/src/views/sidepanel/index.html +4 -0
  199. package/dist/gulp/main.js +11 -5
  200. package/dist/gulp/plugins/webpack/strip-dev-blocks.js +53 -0
  201. package/dist/gulp/tasks/{_package.js → BU/_package.js} +1 -1
  202. package/dist/gulp/tasks/{developmentRebuild.js → BU/developmentRebuild.js} +1 -1
  203. package/dist/gulp/tasks/{themes.js → BU/themes.js} +2 -1
  204. package/dist/gulp/tasks/{test.js → _.js} +3 -3
  205. package/dist/gulp/tasks/audit.js +154 -0
  206. package/dist/gulp/tasks/defaults.js +308 -0
  207. package/dist/gulp/tasks/distribute.js +71 -78
  208. package/dist/gulp/tasks/html.js +150 -0
  209. package/dist/gulp/tasks/icons.js +3 -2
  210. package/dist/gulp/tasks/package.js +194 -13
  211. package/dist/gulp/tasks/sass.js +188 -43
  212. package/dist/gulp/tasks/serve.js +1 -0
  213. package/dist/gulp/tasks/utils/template-transform.js +50 -0
  214. package/dist/gulp/tasks/webpack.js +341 -134
  215. package/dist/index.js +34 -34
  216. package/dist/options.js +40 -0
  217. package/dist/page.js +40 -0
  218. package/dist/popup.js +40 -0
  219. package/dist/sidepanel.js +40 -0
  220. package/firebase-debug.log +350 -0
  221. package/package.json +25 -18
  222. package/dist/assets/css/main.scss +0 -3
  223. package/dist/assets/themes/bootstrap/5.3.3/css/bootstrap.css +0 -12057
  224. package/dist/assets/themes/bootstrap/5.3.3/css/bootstrap.css.map +0 -1
  225. package/dist/assets/themes/bootstrap/5.3.3/js/bootstrap.bundle.js +0 -6314
  226. package/dist/assets/themes/bootstrap/5.3.3/js/bootstrap.bundle.js.map +0 -1
  227. package/dist/assets/themes/bootstrap/5.3.3/js/bootstrap.js +0 -4494
  228. package/dist/assets/themes/bootstrap/5.3.3/js/bootstrap.js.map +0 -1
  229. package/dist/defaults/src/assets/css/content.scss +0 -2
  230. package/dist/defaults/src/assets/css/options.scss +0 -11
  231. package/dist/defaults/src/assets/css/popup.scss +0 -14
  232. package/dist/defaults/src/assets/js/background.js +0 -18
  233. package/dist/defaults/src/assets/js/content.js +0 -15
  234. package/dist/defaults/src/assets/js/options.js +0 -17
  235. package/dist/defaults/src/assets/js/popup.js +0 -17
  236. package/dist/defaults/src/pages/options.html +0 -26
  237. package/dist/defaults/src/pages/popup.html +0 -26
  238. /package/dist/{defaults/src/assets/images/_ → assets/css/bundles/.gitkeep} +0 -0
  239. /package/dist/assets/css/{fontawesome.scss → core/_fontawesome.scss} +0 -0
  240. /package/dist/defaults/src/assets/{vendor/_ → images/.gitkeep} +0 -0
  241. /package/dist/gulp/tasks/{_importer.js → BU/_importer.js} +0 -0
  242. /package/dist/gulp/tasks/{_vendor.js → BU/_vendor.js} +0 -0
@@ -0,0 +1,65 @@
1
+ // Navbar scroll effect for Classy theme
2
+ export default function setupNavbarScroll() {
3
+ const navbar = document.querySelector('.navbar-floating');
4
+ if (!navbar) return;
5
+
6
+ let scrollThreshold = 50; // Pixels to scroll before showing background
7
+ let isGlassy = false;
8
+ let currentOpacity = 0;
9
+ let targetOpacity = 0;
10
+ let animationFrame = null;
11
+
12
+ // Set initial custom property for ::before opacity
13
+ navbar.style.setProperty('--navbar-before-opacity', '0');
14
+
15
+ function animateOpacity() {
16
+ const diff = targetOpacity - currentOpacity;
17
+
18
+ if (Math.abs(diff) > 0.01) {
19
+ currentOpacity += diff * 0.1;
20
+ navbar.style.setProperty('--navbar-before-opacity', currentOpacity);
21
+ animationFrame = requestAnimationFrame(animateOpacity);
22
+ } else {
23
+ currentOpacity = targetOpacity;
24
+ navbar.style.setProperty('--navbar-before-opacity', currentOpacity);
25
+ animationFrame = null;
26
+ }
27
+ }
28
+
29
+ function updateNavbar() {
30
+ const shouldBeGlassy = window.scrollY > scrollThreshold;
31
+
32
+ if (shouldBeGlassy !== isGlassy) {
33
+ isGlassy = shouldBeGlassy;
34
+
35
+ if (isGlassy) {
36
+ navbar.classList.add('bg-glassy', 'shadow-sm');
37
+ targetOpacity = 0.25;
38
+ } else {
39
+ navbar.classList.remove('bg-glassy', 'shadow-sm');
40
+ targetOpacity = 0;
41
+ }
42
+
43
+ if (!animationFrame) {
44
+ animateOpacity();
45
+ }
46
+ }
47
+ }
48
+
49
+ // Initial check
50
+ updateNavbar();
51
+
52
+ // Listen for scroll events with requestAnimationFrame
53
+ let ticking = false;
54
+ function requestTick() {
55
+ if (!ticking) {
56
+ ticking = true;
57
+ window.requestAnimationFrame(() => {
58
+ updateNavbar();
59
+ ticking = false;
60
+ });
61
+ }
62
+ }
63
+
64
+ window.addEventListener('scroll', requestTick, { passive: true });
65
+ }
@@ -1,326 +1,300 @@
1
1
  // Libraries
2
+ import extension from './lib/extension.js';
3
+ import LoggerLite from './lib/logger-lite.js';
2
4
 
3
5
  // Variables
4
6
  const serviceWorker = self;
5
7
 
6
- // Class
7
- function Manager() {
8
- const self = this;
9
-
10
- // Properties
11
- self.extension = null;
12
- self.logger = null;
13
-
14
- // Defaults
15
- self.config = {};
16
- self.version = '%%% version %%%';
17
- self.brand = {
18
- name: '%%% brand.name %%%',
19
- };
20
- self.app = '%%% app.id %%%';
21
- self.environment = '%%% environment %%%';
22
- self.libraries = {
23
- firebase: false,
24
- messaging: false,
25
- promoServer: false,
26
- cachePolyfill: false,
27
- };
28
- self.cache = {
29
- breaker: '',
30
- name: ''
31
- };
32
-
33
- // Return
34
- return self;
35
- }
8
+ // Import build config at the top level (synchronous)
9
+ importScripts('/build.js');
36
10
 
37
- // Initialize
38
- Manager.prototype.initialize = function () {
39
- const self = this;
11
+ // ⚠️⚠️⚠️ CRITICAL: Setup global listeners BEFORE importing Firebase ⚠️⚠️⚠️
12
+ // https://stackoverflow.com/questions/78270541/cant-catch-fcm-notificationclick-event-in-service-worker-using-firebase-messa
13
+ setupGlobalHandlers();
40
14
 
41
- return new Promise(function(resolve, reject) {
15
+ // Import Firebase libraries at the top level (before any async operations)
16
+ // ⚠️ importScripts MUST be called at top-level (synchronously) - it cannot be called inside functions or after async operations
17
+ // importScripts(
18
+ // 'https://www.gstatic.com/firebasejs/%%% firebaseVersion %%%/firebase-app-compat.js',
19
+ // 'https://www.gstatic.com/firebasejs/%%% firebaseVersion %%%/firebase-messaging-compat.js',
20
+ // );
21
+
22
+ // Class
23
+ class Manager {
24
+ constructor() {
42
25
  // Properties
43
- self.extension = require('./lib/extension');
44
- self.logger = new (require('./lib/logger-lite'))('background');
26
+ this.extension = null;
27
+ this.logger = null;
28
+ this.serviceWorker = null;
29
+
30
+ // Load config from build.js
31
+ this.config = serviceWorker.BEM_BUILD_JSON?.config || {};
32
+
33
+ // Defaults
34
+ this.version = this.config?.version || 'unknown';
35
+ this.brand = this.config?.brand || { name: 'unknown' };
36
+ this.app = this.config?.app?.id || 'extension';
37
+ this.environment = this.config?.bem?.environment || 'production';
38
+ this.libraries = {
39
+ firebase: false,
40
+ messaging: false,
41
+ promoServer: false,
42
+ };
43
+ this.cache = {
44
+ breaker: this.config?.bem?.cache_breaker || new Date().getTime(),
45
+ name: ''
46
+ };
47
+ }
48
+
49
+ // Initialize
50
+ async initialize() {
51
+ // Set properties
52
+ this.extension = extension;
53
+ this.logger = new LoggerLite('background');
54
+ this.serviceWorker = serviceWorker;
45
55
 
46
56
  // Parse config file
47
- parseConfiguration(self);
57
+ this.parseConfiguration();
48
58
 
49
- // Setup listeners
50
- setupListeners(self);
59
+ // Setup instance-specific message handlers
60
+ this.setupInstanceHandlers();
51
61
 
52
- // Import firebase
53
- // importFirebase(self);
62
+ // Initialize Firebase
63
+ this.initializeFirebase();
54
64
 
55
65
  // Setup livereload
56
- setupLiveReload(self);
66
+ this.setupLiveReload();
57
67
 
58
68
  // Log
59
- self.logger.log('Initialized!', self.version, self.cache.name, self);
60
-
61
- // Return
62
- return resolve(self);
63
- });
64
- };
69
+ this.logger.log('Initialized!', this.version, this.cache.name, this);
70
+ this.logger.log('Config loaded from BEM_BUILD_JSON:', this.config);
65
71
 
66
- // Parse configuration
67
- function parseConfiguration(self) {
68
- try {
69
- // Log
70
- self.cache.breaker = new Date().getTime();
71
- self.cache.name = `${self.app}-${self.cache.breaker}`;
72
-
73
- self.logger.log('Parsed configuration', self.config);
74
- } catch (e) {
75
- self.logger.error('Error parsing configuration', e);
72
+ // Return manager instance
73
+ return this;
76
74
  }
77
- }
78
-
79
- // Setup listeners
80
- function setupListeners(self) {
81
- // Force service worker to use the latest version
82
- serviceWorker.addEventListener('install', (event) => {
83
- event.waitUntil(serviceWorker.skipWaiting());
84
- });
85
-
86
- serviceWorker.addEventListener('activate', (event) => {
87
- event.waitUntil(serviceWorker.clients.claim());
88
- });
89
-
90
- // Handle clicks on notifications
91
- // Open the URL of the notification
92
- // ⚠️⚠️⚠️ THIS MUST BE PLACED BEFORE THE FIREBASE IMPORTS HANDLER ⚠️⚠️⚠️
93
- // https://stackoverflow.com/questions/78270541/cant-catch-fcm-notificationclick-event-in-background-using-firebase-messa
94
- serviceWorker.addEventListener('notificationclick', (event) => {
95
- // Get the properties of the notification
96
- const notification = event.notification;
97
- const data = (notification.data && notification.data.FCM_MSG ? notification.data.FCM_MSG.data : null) || {};
98
- const payload = (notification.data && notification.data.FCM_MSG ? notification.data.FCM_MSG.notification : null) || {};
99
75
 
100
- // Get the click action
101
- const clickAction = payload.click_action || data.click_action || '/';
102
-
103
- // Log
104
- self.logger.log('Event: notificationclick event', event);
105
- self.logger.log('Event: notificationclick data', data);
106
- self.logger.log('Event: notificationclick payload', payload);
107
- self.logger.log('Event: notificationclick clickAction', clickAction);
108
-
109
- // Handle the click
110
- event.waitUntil(
111
- clients.openWindow(clickAction)
112
- );
113
-
114
- // Close the notification
115
- notification.close();
116
- });
117
-
118
- // Send messages: https://stackoverflow.com/questions/35725594/how-do-i-pass-data-like-a-user-id-to-a-web-worker-for-fetching-additional-push
119
- // more messaging: http://craig-russell.co.uk/2016/01/29/background-messaging.html#.XSKpRZNKiL8
120
- serviceWorker.addEventListener('message', (event) => {
76
+ // Parse configuration
77
+ parseConfiguration() {
121
78
  try {
79
+ // Set cache name
80
+ this.cache.name = `${this.app}-${this.cache.breaker}`;
81
+ } catch (e) {
82
+ this.logger.error('Error parsing configuration', e);
83
+ }
84
+ }
85
+
86
+ // Setup instance-specific message handlers
87
+ setupInstanceHandlers() {
88
+ // Send messages: https://stackoverflow.com/questions/35725594/how-do-i-pass-data-like-a-user-id-to-a-web-worker-for-fetching-additional-push
89
+ // more messaging: http://craig-russell.co.uk/2016/01/29/background-messaging.html#.XSKpRZNKiL8
90
+ serviceWorker.addEventListener('message', (event) => {
122
91
  // Get the data
123
92
  const data = event.data || {};
124
- const response = {
125
- status: 'success',
126
- command: '',
127
- data: {}
128
- };
129
93
 
130
94
  // Parse the data
131
- data.command = data.command || '';
132
- data.args = data.args || {};
133
- response.command = data.command;
95
+ const command = data.command || '';
96
+ const payload = data.payload || {};
134
97
 
135
98
  // Quit if no command
136
- if (data.command === '') { return };
99
+ if (!command) return;
137
100
 
138
101
  // Log
139
- self.logger.log('Event: postMessage', data);
140
-
141
- // Handle the command
142
- if (data.command === 'function') {
143
- data.args.function = data.args.function || function() {};
144
- data.args.function();
145
- } else if (data.command === 'debug') {
146
- self.logger.log('Debug data =', data);
147
- event.ports[0].postMessage(response);
148
- } else if (data.command === 'skipWaiting') {
149
- self.skipWaiting();
150
- event.ports[0].postMessage(response);
151
- } else if (data.command === 'unregister') {
152
- self.registration.unregister()
153
- .then(() => {
154
- event.ports[0].postMessage(response);
155
- })
156
- .catch(() => {
157
- response.status = 'fail';
158
- event.ports[0].postMessage(response);
159
- });
160
- } else if (data.command === 'cache') {
161
- data.args.pages = data.args.pages || [];
162
- var defaultPages =
163
- [
164
- '/',
165
- '/index.html',
166
- /* '/?homescreen=1', */
167
- '/assets/css/main.css',
168
- '/assets/js/main.js',
169
- ];
170
- var pagesToCache = arrayUnique(data.args.pages.concat(defaultPages));
171
- caches.open(SWManager.cache.name).then(cache => {
172
- return cache.addAll(
173
- pagesToCache
174
- )
102
+ this.logger.log('message', command, payload, event);
103
+
104
+ // Handle commands
105
+ if (command === 'update-cache') {
106
+ const pages = payload.pages || [];
107
+ this.updateCache(pages)
175
108
  .then(() => {
176
- self.logger.log('Cached resources.');
177
- event.ports[0].postMessage(response);
109
+ event.ports[0]?.postMessage({ status: 'success' });
178
110
  })
179
- .catch(() => {
180
- response.status = 'fail';
181
- event.ports[0].postMessage(response);
182
- self.logger.log('Failed to cache resources.')
111
+ .catch(error => {
112
+ event.ports[0]?.postMessage({ status: 'error', error: error.message });
183
113
  });
184
- })
185
114
  }
115
+ });
186
116
 
187
- event.ports[0].postMessage(response);
188
- } catch (e) {
189
- // Set up a response
190
- response.success = 'fail';
117
+ // Log
118
+ this.logger.log('Set up message handlers');
119
+ }
191
120
 
192
- // Try to send a response
193
- try { event.ports[0].postMessage(response) } catch (e) {}
121
+ // Initialize Firebase
122
+ initializeFirebase() {
123
+ // Get Firebase config
124
+ const firebaseConfig = this.config?.web_manager?.firebase?.app?.config;
194
125
 
195
- // Log
196
- self.logger.log('Failed to receive message:', data, e);
126
+ // Check if Firebase config is available
127
+ if (!firebaseConfig) {
128
+ this.logger.log('Firebase config not available yet, skipping Firebase initialization');
129
+ return;
197
130
  }
198
- });
199
131
 
200
- // Log
201
- self.logger.log('Set up listeners');
202
- }
132
+ // Check if already initialized
133
+ if (this.libraries.firebase) {
134
+ this.logger.log('Firebase already initialized');
135
+ return;
136
+ }
203
137
 
204
- // Import Firebase
205
- function importFirebase(self) {
206
- // Import Firebase libraries
207
- // importScripts(
208
- // 'https://www.gstatic.com/firebasejs/%%% firebaseVersion %%%/firebase-app-compat.js',
209
- // 'https://www.gstatic.com/firebasejs/%%% firebaseVersion %%%/firebase-messaging-compat.js',
210
- // 'https://www.gstatic.com/firebasejs/%%% firebaseVersion %%%/firebase-database-compat.js',
211
- // 'https://www.gstatic.com/firebasejs/%%% firebaseVersion %%%/firebase-firestore-compat.js',
212
- // );
213
- console.error('---0');
214
- console.error('---1', __dirname);
215
- // const firebase = require('web-manager/node_modules/firebase/firebase-app-compat.js');
216
- // const firebase = require('web-manager');
217
- // const firebase = require('firebase/firebase-auth-compat.js');
218
- console.error('---2', firebase);
219
-
220
- // Initialize app
221
- const app = firebase.initializeApp(self.config.firebase);
222
-
223
- // Initialize messaging
224
- self.libraries.messaging = firebase.messaging();
225
-
226
- // Attach firebase to SWManager
227
- self.libraries.firebase = firebase;
228
- }
138
+ // Log
139
+ this.logger.log('Initializing Firebase');
140
+
141
+ // Initialize app (libraries were already imported at the top if uncommented)
142
+ // firebase.initializeApp(firebaseConfig);
229
143
 
230
- function setupLiveReload(self) {
231
- // Quit if not in dev mode
232
- if (self.environment !== 'development') { return };
144
+ // Initialize messaging
145
+ // this.libraries.messaging = firebase.messaging();
146
+
147
+ // Attach firebase to Manager
148
+ // this.libraries.firebase = firebase;
149
+ }
150
+
151
+ // Update cache
152
+ updateCache(pages) {
153
+ // Set default pages to cache
154
+ const defaults = [
155
+ '/',
156
+ '/assets/css/main.bundle.css',
157
+ '/assets/js/main.bundle.js',
158
+ ];
159
+
160
+ // Ensure pages is an array
161
+ pages = pages || [];
162
+
163
+ // Merge with additional pages
164
+ const pagesToCache = [...new Set([...defaults, ...pages])];
165
+
166
+ // Open cache and add pages
167
+ return caches.open(this.cache.name)
168
+ .then(cache => cache.addAll(pagesToCache))
169
+ .then(() => this.logger.log('Cached resources:', pagesToCache))
170
+ .catch(error => this.logger.error('Failed to cache resources:', error));
171
+ }
233
172
 
234
173
  // Setup livereload
235
- const address = `ws://localhost:%%% liveReloadPort %%%/livereload`;
236
- let connection;
237
- let isReconnecting = false; // Flag to track reconnections
174
+ setupLiveReload() {
175
+ // Quit if not in dev mode
176
+ if (this.environment !== 'development') return;
177
+
178
+ // Get port from config or use default
179
+ const port = this.config?.bem?.liveReloadPort || 35729;
238
180
 
239
- // Function to establish a connection
240
- function connect() {
241
- connection = new WebSocket(address);
181
+ // Setup livereload
182
+ const address = `ws://localhost:${port}/livereload`;
183
+ let connection;
184
+ let isReconnecting = false; // Flag to track reconnections
242
185
 
243
- // Log connection
244
- self.logger.log(`Reload connecting to ${address}...`);
186
+ // Log
187
+ this.logger.log(`Setting up live reload on ${address}...`);
245
188
 
246
- // Log connection errors
247
- connection.onerror = (e) => {
248
- self.logger.error('Reload connection got error:', e);
249
- };
189
+ // Function to establish a connection
190
+ const connect = () => {
191
+ connection = new WebSocket(address);
250
192
 
251
- // Log when set up correctly
252
- connection.onopen = () => {
253
- self.logger.log('Reload connection set up!');
193
+ // Log connection
194
+ this.logger.log(`Reload connecting to ${address}...`);
254
195
 
255
- // Reload the extension only on reconnections
256
- if (isReconnecting) {
257
- // reload();
258
- }
196
+ // Log connection errors
197
+ connection.onerror = (e) => {
198
+ this.logger.error('Reload connection got error:', e);
199
+ };
259
200
 
260
- // Reset the reconnection flag
261
- isReconnecting = false;
262
- };
201
+ // Log when set up correctly
202
+ connection.onopen = () => {
203
+ this.logger.log('Reload connection set up!');
263
204
 
264
- // Handle connection close and attempt to reconnect
265
- connection.onclose = () => {
266
- // Set time
267
- const seconds = 1;
205
+ // Reload the extension only on reconnections
206
+ if (isReconnecting) {
207
+ // reload();
208
+ }
268
209
 
269
- // Log
270
- self.logger.log(`Reload connection closed. Attempting to reconnect in ${seconds} second(s)...`);
210
+ // Reset the reconnection flag
211
+ isReconnecting = false;
212
+ };
271
213
 
272
- // Set the reconnection flag
273
- isReconnecting = true;
214
+ // Handle connection close and attempt to reconnect
215
+ connection.onclose = () => {
216
+ // Set time
217
+ const seconds = 1;
274
218
 
275
- // Reconnect
276
- setTimeout(connect, seconds * 1000); // Retry
277
- };
219
+ // Log
220
+ this.logger.log(`Reload connection closed. Attempting to reconnect in ${seconds} second(s)...`);
278
221
 
279
- // Handle incoming messages
280
- connection.onmessage = function (event) {
281
- if (!event.data) {
282
- return;
283
- }
222
+ // Set the reconnection flag
223
+ isReconnecting = true;
284
224
 
285
- // Get data
286
- const data = JSON.parse(event.data);
225
+ // Reconnect
226
+ setTimeout(connect, seconds * 1000); // Retry
227
+ };
287
228
 
288
- // Log
289
- self.logger.log('Reload connection got message:', data);
229
+ // Handle incoming messages
230
+ connection.onmessage = (event) => {
231
+ if (!event.data) {
232
+ return;
233
+ }
290
234
 
291
- // Handle reload command
292
- if (data && data.command === 'reload') {
293
- reload();
294
- }
235
+ // Get data
236
+ const data = JSON.parse(event.data);
237
+
238
+ // Log
239
+ this.logger.log('Reload connection got message:', data);
240
+
241
+ // Handle reload command
242
+ if (data && data.command === 'reload') {
243
+ reload();
244
+ }
245
+ };
295
246
  };
296
- }
297
247
 
298
- function reload() {
299
- self.logger.log('Reloading extension...');
300
- setTimeout(() => {
301
- self.extension.runtime.reload();
302
- }, 1000);
303
- }
248
+ const reload = () => {
249
+ this.logger.log('Reloading extension...');
250
+ setTimeout(() => {
251
+ this.extension.runtime.reload();
252
+ }, 1000);
253
+ };
304
254
 
305
- // Start the initial connection
306
- connect();
255
+ // Start the initial connection
256
+ connect();
257
+ }
307
258
  }
308
259
 
309
- function arrayUnique(array) {
310
- var a = array.concat();
260
+ // Helper: Setup global listeners
261
+ // This is called at top-level before any async operations to ensure listeners are registered first
262
+ function setupGlobalHandlers() {
263
+ // Force service worker to use the latest version
264
+ serviceWorker.addEventListener('install', (event) => {
265
+ serviceWorker.skipWaiting();
266
+ });
267
+
268
+ serviceWorker.addEventListener('activate', (event) => {
269
+ event.waitUntil(serviceWorker.clients.claim());
270
+ });
311
271
 
312
- // Loop through array
313
- for(var i=0; i<a.length; ++i) {
314
- for(var j=i+1; j<a.length; ++j) {
315
- if(a[i] === a[j]) {
316
- a.splice(j--, 1);
317
- }
318
- }
319
- }
272
+ // Handle clicks on notifications
273
+ // ⚠️ MUST be registered before any async operations
274
+ serviceWorker.addEventListener('notificationclick', (event) => {
275
+ // Get the properties of the notification
276
+ const notification = event.notification;
277
+ const data = (notification.data && notification.data.FCM_MSG ? notification.data.FCM_MSG.data : null) || {};
278
+ const payload = (notification.data && notification.data.FCM_MSG ? notification.data.FCM_MSG.notification : null) || {};
279
+
280
+ // Get the click action
281
+ const clickAction = payload.click_action || data.click_action || '/';
282
+
283
+ // Log
284
+ console.log('notificationclick event', event);
285
+ console.log('notificationclick data', data);
286
+ console.log('notificationclick payload', payload);
287
+ console.log('notificationclick clickAction', clickAction);
288
+
289
+ // Handle the click
290
+ event.waitUntil(
291
+ clients.openWindow(clickAction)
292
+ );
320
293
 
321
- // Return
322
- return a;
294
+ // Close the notification
295
+ notification.close();
296
+ });
323
297
  }
324
298
 
325
299
  // Export
326
- module.exports = Manager;
300
+ export default Manager;