@hexonet/semantic-release-whmcs 5.0.69 → 5.1.0

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 (37) hide show
  1. package/HISTORY.md +28 -0
  2. package/extensions/I-Still-Dont-Care-About-Cookies/LICENSE +14 -0
  3. package/extensions/I-Still-Dont-Care-About-Cookies/_locales/en/messages.json +160 -0
  4. package/extensions/I-Still-Dont-Care-About-Cookies/_metadata/generated_indexed_rulesets/_ruleset1 +0 -0
  5. package/extensions/I-Still-Dont-Care-About-Cookies/data/background.html +2 -0
  6. package/extensions/I-Still-Dont-Care-About-Cookies/data/background.js +681 -0
  7. package/extensions/I-Still-Dont-Care-About-Cookies/data/css/common.css +14306 -0
  8. package/extensions/I-Still-Dont-Care-About-Cookies/data/hotreload.js +43 -0
  9. package/extensions/I-Still-Dont-Care-About-Cookies/data/js/0_defaultClickHandler.js +590 -0
  10. package/extensions/I-Still-Dont-Care-About-Cookies/data/js/2_sessionStorageHandler.js +30 -0
  11. package/extensions/I-Still-Dont-Care-About-Cookies/data/js/3_localStorageHandler.js +243 -0
  12. package/extensions/I-Still-Dont-Care-About-Cookies/data/js/5_clickHandler.js +8523 -0
  13. package/extensions/I-Still-Dont-Care-About-Cookies/data/js/6_cookieHandler.js +764 -0
  14. package/extensions/I-Still-Dont-Care-About-Cookies/data/js/8_googleHandler.js +105 -0
  15. package/extensions/I-Still-Dont-Care-About-Cookies/data/js/embedsHandler.js +107 -0
  16. package/extensions/I-Still-Dont-Care-About-Cookies/data/menu/index.html +79 -0
  17. package/extensions/I-Still-Dont-Care-About-Cookies/data/menu/script.js +161 -0
  18. package/extensions/I-Still-Dont-Care-About-Cookies/data/menu/spinner.svg +12 -0
  19. package/extensions/I-Still-Dont-Care-About-Cookies/data/menu/style.css +68 -0
  20. package/extensions/I-Still-Dont-Care-About-Cookies/data/options.html +42 -0
  21. package/extensions/I-Still-Dont-Care-About-Cookies/data/options.js +63 -0
  22. package/extensions/I-Still-Dont-Care-About-Cookies/data/rules.js +20684 -0
  23. package/extensions/I-Still-Dont-Care-About-Cookies/icons/128.png +0 -0
  24. package/extensions/I-Still-Dont-Care-About-Cookies/icons/16.png +0 -0
  25. package/extensions/I-Still-Dont-Care-About-Cookies/icons/32.png +0 -0
  26. package/extensions/I-Still-Dont-Care-About-Cookies/icons/48.png +0 -0
  27. package/extensions/I-Still-Dont-Care-About-Cookies/manifest.json +47 -0
  28. package/extensions/I-Still-Dont-Care-About-Cookies/manifest_v2.json +46 -0
  29. package/extensions/I-Still-Dont-Care-About-Cookies/rules.json +19539 -0
  30. package/lib/delete-marketplace-version.js +82 -31
  31. package/lib/publish.js +52 -43
  32. package/lib/puppet-utils.js +145 -0
  33. package/lib/puppet.js +68 -41
  34. package/lib/resolve-config.js +1 -0
  35. package/lib/set-compatible-versions.js +26 -10
  36. package/package.json +6 -6
  37. package/whmcs.js +7 -5
@@ -0,0 +1,681 @@
1
+ import { blockUrls, commons, commonJSHandlers, rules } from "./rules.js";
2
+ // Vars
3
+ let initialized = false;
4
+ let cachedRules = {};
5
+ let tabList = {};
6
+ const xmlTabs = {};
7
+ let lastDeclarativeNetRuleId = 1;
8
+ let settings = { statusIndicators: true, whitelistedDomains: {} };
9
+ const isManifestV3 = chrome.runtime.getManifest().manifest_version == 3;
10
+
11
+ // Badges
12
+ function setBadge(tabId, text) {
13
+ const chromeAction = chrome?.browserAction ?? chrome?.action;
14
+
15
+ if (!chromeAction || !settings.statusIndicators) return;
16
+
17
+ chromeAction.setBadgeText({ text: text || "", tabId: tabId });
18
+
19
+ if (chromeAction.setBadgeBackgroundColor)
20
+ chromeAction.setBadgeBackgroundColor({
21
+ color: "#646464",
22
+ tabId: tabId,
23
+ });
24
+ }
25
+
26
+ function setSuccessBadge(tabId) {
27
+ setBadge(tabId, "✅");
28
+ }
29
+
30
+ function setDisabledBadge(tabId) {
31
+ setBadge(tabId, "⛔");
32
+ }
33
+
34
+ // Common functions
35
+ function getHostname(url, cleanup) {
36
+ try {
37
+ if (url.indexOf("http") != 0) {
38
+ throw true;
39
+ }
40
+
41
+ const a = new URL(url);
42
+
43
+ return typeof cleanup == "undefined"
44
+ ? a.hostname
45
+ : a.hostname.replace(/^w{2,3}\d*\./i, "");
46
+ } catch (error) {
47
+ return false;
48
+ }
49
+ }
50
+
51
+ // Whitelisting
52
+ function updateSettings() {
53
+ return new Promise((resolve) => {
54
+ lastDeclarativeNetRuleId = 1;
55
+ chrome.storage.local.get(
56
+ { settings: { whitelistedDomains: {}, statusIndicators: true } },
57
+ async ({ settings: storedSettings }) => {
58
+ settings = storedSettings;
59
+
60
+ if (isManifestV3) {
61
+ await updateWhitelistRules();
62
+ }
63
+ resolve();
64
+ }
65
+ );
66
+ });
67
+ }
68
+
69
+ async function updateWhitelistRules() {
70
+ if (!isManifestV3) {
71
+ console.warn("Called unsupported function");
72
+ return;
73
+ }
74
+ const previousRules = (
75
+ await chrome.declarativeNetRequest.getDynamicRules()
76
+ ).map((v) => {
77
+ return v.id;
78
+ });
79
+ const addRules = Object.entries(settings.whitelistedDomains)
80
+ .filter((element) => element[1])
81
+ .map((v) => {
82
+ return {
83
+ id: lastDeclarativeNetRuleId++,
84
+ priority: 1,
85
+ action: { type: "allow" },
86
+ condition: {
87
+ urlFilter: "*",
88
+ resourceTypes: ["script", "stylesheet", "xmlhttprequest", "image"],
89
+ initiatorDomains: [v[0]],
90
+ },
91
+ };
92
+ });
93
+
94
+ chrome.declarativeNetRequest.updateDynamicRules({
95
+ addRules,
96
+ removeRuleIds: previousRules,
97
+ });
98
+ }
99
+
100
+ function isWhitelisted(tab) {
101
+ if (typeof settings.whitelistedDomains[tab.hostname] != "undefined") {
102
+ return true;
103
+ }
104
+
105
+ for (const i in tab.host_levels) {
106
+ if (typeof settings.whitelistedDomains[tab.host_levels[i]] != "undefined") {
107
+ return true;
108
+ }
109
+ }
110
+
111
+ return false;
112
+ }
113
+
114
+ function getWhitelistedDomain(tab) {
115
+ if (typeof settings.whitelistedDomains[tab.hostname] != "undefined") {
116
+ return tab.hostname;
117
+ }
118
+
119
+ for (const i in tab.host_levels) {
120
+ if (typeof settings.whitelistedDomains[tab.host_levels[i]] != "undefined") {
121
+ return tab.host_levels[i];
122
+ }
123
+ }
124
+
125
+ return false;
126
+ }
127
+
128
+ async function toggleWhitelist(tab) {
129
+ if (tab.url.indexOf("http") != 0 || !tabList[tab.id]) {
130
+ return;
131
+ }
132
+
133
+ if (tabList[tab.id].whitelisted) {
134
+ // const hostname = getWhitelistedDomain(tabList[tab.id]);
135
+ delete settings.whitelistedDomains[tabList[tab.id].hostname];
136
+ } else {
137
+ settings.whitelistedDomains[tabList[tab.id].hostname] = true;
138
+ }
139
+ chrome.storage.local.set({ settings }, function () {
140
+ for (const i in tabList) {
141
+ if (tabList[i].hostname == tabList[tab.id].hostname) {
142
+ tabList[i].whitelisted = !tabList[tab.id].whitelisted;
143
+ }
144
+ }
145
+ });
146
+ if (isManifestV3) {
147
+ await updateWhitelistRules();
148
+ }
149
+ }
150
+
151
+ // Maintain tab list
152
+
153
+ function getPreparedTab(tab) {
154
+ tab.hostname = false;
155
+ tab.whitelisted = false;
156
+ tab.host_levels = [];
157
+
158
+ if (tab.url) {
159
+ tab.hostname = getHostname(tab.url, true);
160
+
161
+ if (tab.hostname) {
162
+ const parts = tab.hostname.split(".");
163
+
164
+ for (let i = parts.length; i >= 2; i--) {
165
+ tab.host_levels.push(parts.slice(-1 * i).join("."));
166
+ }
167
+
168
+ tab.whitelisted = isWhitelisted(tab);
169
+ }
170
+ }
171
+
172
+ return tab;
173
+ }
174
+
175
+ function onCreatedListener(tab) {
176
+ tabList[tab.id] = getPreparedTab(tab);
177
+ }
178
+
179
+ function onUpdatedListener(tabId, changeInfo, tab) {
180
+ if (changeInfo.status) {
181
+ tabList[tab.id] = getPreparedTab(tab);
182
+ }
183
+ }
184
+
185
+ function onRemovedListener(tabId) {
186
+ if (tabList[tabId]) {
187
+ delete tabList[tabId];
188
+ }
189
+ }
190
+
191
+ async function recreateTabList(magic) {
192
+ tabList = {};
193
+ let results;
194
+ if (isManifestV3) {
195
+ results = await chrome.tabs.query({});
196
+ } else {
197
+ results = await new Promise((resolve, reject) => {
198
+ chrome.tabs.query({}, (result) => {
199
+ if (chrome.runtime.lastError) reject(chrome.runtime.lastError);
200
+ resolve(result);
201
+ });
202
+ });
203
+ }
204
+ results.forEach(onCreatedListener);
205
+
206
+ if (magic) {
207
+ for (const i in tabList) {
208
+ if (tabList.hasOwnProperty(i)) {
209
+ doTheMagic(tabList[i].id);
210
+ }
211
+ }
212
+ }
213
+ }
214
+
215
+ chrome.tabs.onCreated.addListener(onCreatedListener);
216
+ chrome.tabs.onUpdated.addListener(onUpdatedListener);
217
+ chrome.tabs.onRemoved.addListener(onRemovedListener);
218
+
219
+ // chrome.runtime.onStartup.addListener(async () => await initialize(true));
220
+ chrome.runtime.onInstalled.addListener(
221
+ async () => await initialize(false, true)
222
+ );
223
+
224
+ // URL blocking
225
+
226
+ function blockUrlCallback(d) {
227
+ // Cached request: find the appropriate tab
228
+ // TODO: parse rules.json for this function.
229
+
230
+ if (d.tabId == -1 && d.initiator) {
231
+ // const hostname = getHostname(d.initiator, true);
232
+ for (const tabId in tabList) {
233
+ if (tabList[tabId].hostname == getHostname(d.initiator, true)) {
234
+ d.tabId = parseInt(tabId);
235
+ break;
236
+ }
237
+ }
238
+ }
239
+
240
+ if (tabList[d.tabId]?.whitelisted ?? false) {
241
+ setDisabledBadge(d.tabId);
242
+ return { cancel: false };
243
+ }
244
+
245
+ if (tabList[d.tabId] && d.url) {
246
+ const cleanURL = d.url.split("?")[0];
247
+
248
+ // To shorten the checklist, many filters are grouped by keywords
249
+
250
+ for (const group in blockUrls.common_groups) {
251
+ if (d.url.indexOf(group) > -1) {
252
+ const groupFilters = blockUrls.common_groups[group];
253
+
254
+ for (const i in groupFilters) {
255
+ if (
256
+ (groupFilters[i].q && d.url.indexOf(groupFilters[i].r) > -1) ||
257
+ (!groupFilters[i].q && cleanURL.indexOf(groupFilters[i].r) > -1)
258
+ ) {
259
+ // Check for exceptions
260
+
261
+ if (groupFilters[i].e && tabList[d.tabId].host_levels.length > 0) {
262
+ for (const level in tabList[d.tabId].host_levels) {
263
+ for (const exception in groupFilters[i].e) {
264
+ if (
265
+ groupFilters[i].e[exception] ==
266
+ tabList[d.tabId].host_levels[level]
267
+ ) {
268
+ return { cancel: false };
269
+ }
270
+ }
271
+ }
272
+ }
273
+ setSuccessBadge(d.tabId);
274
+ return { cancel: true };
275
+ }
276
+ }
277
+ }
278
+ }
279
+
280
+ // Check ungrouped filters
281
+
282
+ const groupFilters = blockUrls.common;
283
+
284
+ for (const i in groupFilters) {
285
+ if (
286
+ (groupFilters[i].q && d.url.indexOf(groupFilters[i].r) > -1) ||
287
+ (!groupFilters[i].q && cleanURL.indexOf(groupFilters[i].r) > -1)
288
+ ) {
289
+ // Check for exceptions
290
+
291
+ if (groupFilters[i].e && tabList[d.tabId].host_levels.length > 0) {
292
+ for (const level in tabList[d.tabId].host_levels) {
293
+ for (const exception in groupFilters[i].e) {
294
+ if (
295
+ groupFilters[i].e[exception] ==
296
+ tabList[d.tabId].host_levels[level]
297
+ ) {
298
+ return { cancel: false };
299
+ }
300
+ }
301
+ }
302
+ }
303
+ setSuccessBadge(d.tabId);
304
+ return { cancel: true };
305
+ }
306
+ }
307
+
308
+ // Site specific filters
309
+
310
+ if (d.tabId > -1 && tabList[d.tabId].host_levels.length > 0) {
311
+ for (const level in tabList[d.tabId].host_levels) {
312
+ if (blockUrls.specific[tabList[d.tabId].host_levels[level]]) {
313
+ const rules = blockUrls.specific[tabList[d.tabId].host_levels[level]];
314
+
315
+ for (const i in rules) {
316
+ if (d.url.indexOf(rules[i]) > -1) {
317
+ setSuccessBadge(d.tabId);
318
+ return { cancel: true };
319
+ }
320
+ }
321
+ }
322
+ }
323
+ }
324
+ }
325
+
326
+ return { cancel: false };
327
+ }
328
+ if (!isManifestV3) {
329
+ chrome.webRequest.onBeforeRequest.addListener(
330
+ blockUrlCallback,
331
+ {
332
+ urls: ["http://*/*", "https://*/*"],
333
+ types: ["script", "stylesheet", "xmlhttprequest"],
334
+ },
335
+ ["blocking"]
336
+ );
337
+
338
+ chrome.webRequest.onHeadersReceived.addListener(
339
+ function (d) {
340
+ if (tabList[d.tabId]) {
341
+ d.responseHeaders.forEach(function (h) {
342
+ if (h.name == "Content-Type" || h.name == "content-type") {
343
+ xmlTabs[d.tabId] = h.value.indexOf("/xml") > -1;
344
+ }
345
+ });
346
+ }
347
+
348
+ return { cancel: false };
349
+ },
350
+ { urls: ["http://*/*", "https://*/*"], types: ["main_frame"] },
351
+ ["blocking", "responseHeaders"]
352
+ );
353
+ }
354
+ // Reporting
355
+
356
+ function reportWebsite(info, tab, anon, issueType, notes, callback) {
357
+ if (tab.url.indexOf("http") != 0 || !tabList[tab.id]) {
358
+ return;
359
+ }
360
+
361
+ const hostname = getHostname(tab.url);
362
+
363
+ if (hostname.length == 0) {
364
+ return;
365
+ }
366
+
367
+ if (tabList[tab.id].whitelisted) {
368
+ return chrome.notifications.create("report", {
369
+ type: "basic",
370
+ title: chrome.i18n.getMessage("reportSkippedTitle", hostname),
371
+ message: chrome.i18n.getMessage("reportSkippedMessage"),
372
+ iconUrl: "icons/48.png",
373
+ });
374
+ }
375
+ if (!anon) {
376
+ chrome.tabs.create({
377
+ url: `https://github.com/OhMyGuus/I-Dont-Care-About-Cookies/issues/new?assignees=OhMyGuus&labels=Website+request&template=website_request.yml&title=%5BREQ%5D%3A+${encodeURIComponent(
378
+ hostname
379
+ )}&url=${encodeURIComponent(hostname)}&version=${encodeURIComponent(
380
+ chrome.runtime.getManifest().version
381
+ )}&browser=${encodeURIComponent(getBrowserAndVersion())}`,
382
+ });
383
+ } else {
384
+ fetch("https://api.istilldontcareaboutcookies.com/api/report", {
385
+ method: "POST",
386
+ headers: {
387
+ "Content-Type": "application/json",
388
+ },
389
+ body: JSON.stringify({
390
+ issueType,
391
+ notes,
392
+ url: tab.url,
393
+ browser: getBrowserAndVersion(),
394
+ language:
395
+ navigator.language || Intl.DateTimeFormat().resolvedOptions().locale,
396
+ extensionVersion: chrome.runtime.getManifest().version,
397
+ }),
398
+ })
399
+ .then((response) => response.json())
400
+ .then((response) => {
401
+ if (
402
+ response &&
403
+ !response.error &&
404
+ !response.errors &&
405
+ response.responseURL
406
+ ) {
407
+ chrome.tabs.create({
408
+ url: response.responseURL,
409
+ });
410
+ callback({ error: false });
411
+ } else {
412
+ callback({ error: true });
413
+ }
414
+ })
415
+ .catch(() => {
416
+ callback({ error: true });
417
+ });
418
+ }
419
+ }
420
+
421
+ function getBrowserAndVersion() {
422
+ const useragent = navigator.userAgent;
423
+ if (useragent.includes("Firefox")) {
424
+ return useragent.match(/Firefox\/([0-9]+[\S]+)/)[0].replace("/", " ");
425
+ } else if (useragent.includes("Chrome")) {
426
+ if (navigator.userAgentData.brands.length > 2) {
427
+ const { brand, version } = navigator.userAgentData.brands[1];
428
+ return brand + " " + version;
429
+ }
430
+ }
431
+ return "Other";
432
+ }
433
+
434
+ // Adding custom CSS/JS
435
+
436
+ function activateDomain(hostname, tabId, frameId) {
437
+ if (!cachedRules[hostname]) {
438
+ cachedRules[hostname] = rules[hostname] || {};
439
+ }
440
+
441
+ if (!cachedRules[hostname]) {
442
+ return false;
443
+ }
444
+
445
+ const cachedRule = cachedRules[hostname];
446
+ let status = false;
447
+
448
+ // cached_rule.s = Custom css for webpage
449
+ // cached_rule.c = Common css for webpage
450
+ // cached_rule.j = Common js for webpage
451
+
452
+ if (typeof cachedRule.s != "undefined") {
453
+ insertCSS({ tabId, frameId: frameId || 0, css: cachedRule.s });
454
+ status = true;
455
+ }
456
+
457
+ if (typeof cachedRule.c != "undefined") {
458
+ insertCSS({ tabId, frameId: frameId || 0, css: commons[cachedRule.c] });
459
+ status = true;
460
+ }
461
+
462
+ if (typeof cachedRule.j != "undefined") {
463
+ executeScript({
464
+ tabId,
465
+ frameId,
466
+ file: `/data/js/${commonJSHandlers[cachedRule.j]}.js`,
467
+ });
468
+ status = true;
469
+ }
470
+
471
+ if (status) {
472
+ setSuccessBadge(tabId);
473
+ }
474
+
475
+ return status;
476
+ }
477
+
478
+ function doTheMagic(tabId, frameId, anotherTry) {
479
+ if (!tabList[tabId] || tabList[tabId].url.indexOf("http") != 0) {
480
+ return;
481
+ }
482
+
483
+ if (tabList[tabId].whitelisted) {
484
+ setDisabledBadge(tabId);
485
+ return;
486
+ }
487
+
488
+ // Common CSS rules
489
+ insertCSS(
490
+ { tabId, frameId: frameId || 0, file: "/data/css/common.css" },
491
+ function () {
492
+ // A failure? Retry.
493
+ if (chrome.runtime.lastError) {
494
+ console.log(chrome.runtime.lastError);
495
+
496
+ const currentTry = anotherTry || 1;
497
+
498
+ if (currentTry == 10) {
499
+ return;
500
+ }
501
+ if (currentTry > 5) {
502
+ setTimeout(() => doTheMagic(tabId, frameId || 0, currentTry + 1));
503
+ } else {
504
+ doTheMagic(tabId, frameId || 0, currentTry + 1);
505
+ }
506
+ return;
507
+ }
508
+
509
+ // Common social embeds
510
+ executeScript({ tabId, frameId, file: "/data/js/embedsHandler.js" });
511
+
512
+ if (activateDomain(tabList[tabId].hostname, tabId, frameId || 0)) {
513
+ return;
514
+ }
515
+
516
+ for (const level in tabList[tabId].host_levels) {
517
+ if (
518
+ activateDomain(tabList[tabId].host_levels[level], tabId, frameId || 0)
519
+ ) {
520
+ return true;
521
+ }
522
+ }
523
+
524
+ // Common JS rules when custom rules don't exist
525
+ executeScript({
526
+ tabId,
527
+ frameId,
528
+ file: "/data/js/0_defaultClickHandler.js",
529
+ });
530
+ }
531
+ );
532
+ }
533
+
534
+ chrome.webNavigation.onCommitted.addListener(async (tab) => {
535
+ if (tab.frameId > 0) {
536
+ return;
537
+ }
538
+ if (!initialized) {
539
+ await initialize();
540
+ }
541
+
542
+ tabList[tab.tabId] = getPreparedTab(tab);
543
+
544
+ doTheMagic(tab.tabId);
545
+ });
546
+
547
+ chrome.webNavigation.onCompleted.addListener(async function (tab) {
548
+ if (!initialized) {
549
+ await initialize();
550
+ }
551
+ if (tab.frameId > 0 && tab.url != "about:blank") {
552
+ doTheMagic(tab.tabId, tab.frameId);
553
+ }
554
+ });
555
+
556
+ // Toolbar menu
557
+
558
+ chrome.runtime.onMessage.addListener((request, info, sendResponse) => {
559
+ initialize().then(() => {
560
+ let responseSend = false;
561
+ if (typeof request == "object") {
562
+ if (request.tabId && tabList[request.tabId]) {
563
+ if (request.command == "get_active_tab") {
564
+ const response = { tab: tabList[request.tabId] };
565
+
566
+ if (response.tab.whitelisted) {
567
+ response.tab.hostname = getWhitelistedDomain(
568
+ tabList[request.tabId]
569
+ );
570
+ }
571
+ sendResponse(response);
572
+ responseSend = true;
573
+ } else if (request.command == "toggle_extension") {
574
+ toggleWhitelist(tabList[request.tabId]);
575
+ } else if (request.command == "report_website") {
576
+ reportWebsite(
577
+ info,
578
+ tabList[request.tabId],
579
+ request.anon,
580
+ request.issueType,
581
+ request.notes,
582
+ sendResponse
583
+ );
584
+ responseSend = true;
585
+ } else if (request.command == "refresh_page") {
586
+ executeScript({
587
+ tabId: request.tabId,
588
+ func: () => {
589
+ window.location.reload();
590
+ },
591
+ });
592
+ }
593
+ } else {
594
+ if (request.command == "open_options_page") {
595
+ chrome.tabs.create({
596
+ url: chrome.runtime.getURL("/data/options.html"),
597
+ });
598
+ }
599
+ }
600
+ } else if (request == "update_settings") {
601
+ updateSettings();
602
+ }
603
+ if (!responseSend) {
604
+ sendResponse();
605
+ }
606
+ });
607
+
608
+ return true;
609
+ });
610
+
611
+ function insertCSS(injection, callback) {
612
+ const { tabId, css, file, frameId } = injection;
613
+
614
+ if (isManifestV3) {
615
+ chrome.scripting.insertCSS(
616
+ {
617
+ target: { tabId: tabId, frameIds: [frameId || 0] },
618
+ css: css,
619
+ files: file ? [file] : undefined,
620
+ origin: "USER",
621
+ },
622
+ callback
623
+ );
624
+ } else {
625
+ chrome.tabs.insertCSS(
626
+ tabId,
627
+ {
628
+ file,
629
+ code: css,
630
+ frameId: frameId || 0,
631
+ runAt: xmlTabs[tabId] ? "document_idle" : "document_start",
632
+ cssOrigin: "user",
633
+ },
634
+ callback
635
+ );
636
+ }
637
+ }
638
+
639
+ function executeScript(injection, callback) {
640
+ const { tabId, func, file, frameId } = injection;
641
+ if (isManifestV3) {
642
+ // manifest v3
643
+ chrome.scripting.executeScript(
644
+ {
645
+ target: { tabId, frameIds: [frameId || 0] },
646
+ files: file ? [file] : undefined,
647
+ func,
648
+ },
649
+ callback
650
+ );
651
+ } else {
652
+ // manifest v2
653
+ chrome.tabs.executeScript(
654
+ tabId,
655
+ {
656
+ file,
657
+ frameId: frameId || 0,
658
+ code: func == undefined ? undefined : "(" + func.toString() + ")();",
659
+ runAt: xmlTabs[tabId] ? "document_idle" : "document_end",
660
+ },
661
+ callback
662
+ );
663
+ }
664
+ }
665
+
666
+ async function loadCachedRules() {
667
+ // TODO: Load cached rules for V3 to improve speed (Requires testing to see if this actually is faster for v3)
668
+ cachedRules = {};
669
+ }
670
+
671
+ async function initialize(checkInitialized, magic) {
672
+ if (checkInitialized && initialized) {
673
+ return;
674
+ }
675
+ loadCachedRules();
676
+ await updateSettings();
677
+ await recreateTabList(magic);
678
+ initialized = true;
679
+ }
680
+
681
+ initialize();