perfectionist-plugins 2.4.5 → 2.4.7

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.
@@ -78,16 +78,11 @@ function installArrayFilter() {
78
78
  return owned;
79
79
  });
80
80
  if (!changed) return result;
81
- filterStats.array = (filterStats.array || 0) + 1;
82
- filterStats.source = "array";
83
- filterStats.lastIn = result.length;
84
- filterStats.lastOut = kept.length;
85
81
  return kept;
86
82
  };
87
83
  wrapped.__perfSkinFilter = FILTER_VERSION;
88
84
  proto.filter = wrapped;
89
85
  }
90
- const filterStats = (globalThis.__perfSkinFilterStats ??= { carousel: 0, source: "", lastIn: 0, lastOut: 0 });
91
86
  let rawFetch = (typeof window !== "undefined" && window.fetch && window.fetch.__perfOriginalFetch) || null;
92
87
  let clientSkinOrder = [];
93
88
 
@@ -127,8 +122,6 @@ function filterSkinList(list) {
127
122
  })
128
123
  .filter(isOwnedSkin);
129
124
  if (filtered.length !== list.length) changed = true;
130
- filterStats.lastIn = list.length;
131
- filterStats.lastOut = filtered.length;
132
125
  return changed ? filtered : null;
133
126
  }
134
127
 
@@ -153,8 +146,6 @@ function rewriteWebSocketFrame(text) {
153
146
  if (!payload || typeof payload !== "object" || typeof payload.uri !== "string") return null;
154
147
  if (payload.uri.split("?")[0] !== CAROUSEL_URI) return null;
155
148
  const kept = filterSkinList(payload.data);
156
- filterStats.carousel++;
157
- filterStats.source = "ws";
158
149
  recordClientOrder(kept ?? payload.data);
159
150
  if (!kept) return null;
160
151
  return JSON.stringify([frame[0], frame[1], Object.assign({}, payload, { data: kept })]);
@@ -235,7 +226,6 @@ function installFetchFilter() {
235
226
  const original = window.fetch;
236
227
  if (typeof original !== "function" || original.__perfSkinFilter === FILTER_VERSION) return;
237
228
  if (!rawFetch) rawFetch = original.__perfOriginalFetch || original;
238
- globalThis.__perfNativeFetch = rawFetch;
239
229
 
240
230
  const wrapped = function (input, init) {
241
231
  const url =
@@ -261,8 +251,6 @@ function installFetchFilter() {
261
251
  .catch(() => null)
262
252
  .then((json) => {
263
253
  const kept = filterSkinList(json);
264
- filterStats.carousel++;
265
- filterStats.source = "fetch";
266
254
  recordClientOrder(kept ?? json);
267
255
  if (!kept) return response;
268
256
  return new Response(JSON.stringify(kept), {
@@ -307,8 +295,6 @@ function installXhrFilter() {
307
295
  try {
308
296
  const json = JSON.parse(raw);
309
297
  const kept = filterSkinList(json);
310
- filterStats.carousel++;
311
- filterStats.source = "xhr";
312
298
  recordClientOrder(kept ?? json);
313
299
  if (kept) cache.filtered = JSON.stringify(kept);
314
300
  } catch {
@@ -442,10 +428,6 @@ function applyAll() {
442
428
  });
443
429
  }
444
430
 
445
- function applyAllGuarded() {
446
- applyAll();
447
- }
448
-
449
431
  let applyQueued = false;
450
432
 
451
433
  function scheduleApply() {
@@ -558,7 +540,7 @@ function resetState() {
558
540
  failure = null;
559
541
  sessionMisses = 0;
560
542
  championMisses = 0;
561
- applyAllGuarded();
543
+ applyAll();
562
544
  }
563
545
 
564
546
  function loadChampion(championId) {
@@ -579,7 +561,7 @@ function loadChampion(championId) {
579
561
  topLevelOrder = topLevel;
580
562
  ownedTopLevelIds = ownedTopLevel;
581
563
  carouselOrder = carouselIds.length > 0 ? carouselIds : inventoryOrder;
582
- applyAllGuarded();
564
+ applyAll();
583
565
  },
584
566
  (error) => {
585
567
  if (token !== requestToken) return;
@@ -618,7 +600,7 @@ function updateForSession(session, selection) {
618
600
  }
619
601
  }
620
602
 
621
- applyAllGuarded();
603
+ applyAll();
622
604
  }
623
605
 
624
606
  function scheduleRefresh() {
package/package.json CHANGED
@@ -1,40 +1,40 @@
1
- {
2
- "name": "perfectionist-plugins",
3
- "version": "2.4.5",
4
- "description": "Small plugins that fix the annoying parts of League of Legends champ select. Built for Pengu Loader.",
5
- "type": "module",
6
- "main": "perfectionist-utils.js",
7
- "exports": {
8
- ".": "./perfectionist-utils.js",
9
- "./perfectionist-utils.js": "./perfectionist-utils.js",
10
- "./ban-blocker.js": "./ban-blocker.js",
11
- "./hide-unowned-skins.js": "./hide-unowned-skins.js",
12
- "./unlock-profile-skins.js": "./unlock-profile-skins.js",
13
- "./auto-claimer.js": "./auto-claimer.js",
14
- "./auto-read.js": "./auto-read.js",
15
- "./better-client.js": "./better-client.js",
16
- "./dodge-helper.js": "./dodge-helper.js",
17
- "./auto-accept.js": "./auto-accept.js"
18
- },
19
- "files": [
20
- "perfectionist-utils.js",
21
- "ban-blocker.js",
22
- "hide-unowned-skins.js",
23
- "unlock-profile-skins.js",
24
- "auto-claimer.js",
25
- "auto-read.js",
26
- "better-client.js",
27
- "dodge-helper.js",
28
- "auto-accept.js"
29
- ],
30
- "repository": {
31
- "type": "git",
32
- "url": "git+https://github.com/SrKing-9812/Perfectionist-Plugins.git"
33
- },
34
- "keywords": [
35
- "pengu-loader",
36
- "league-of-legends",
37
- "plugin"
38
- ],
39
- "author": "Sr. King"
40
- }
1
+ {
2
+ "name": "perfectionist-plugins",
3
+ "version": "2.4.7",
4
+ "description": "Small plugins that fix the annoying parts of League of Legends champ select. Built for Pengu Loader.",
5
+ "type": "module",
6
+ "main": "perfectionist-utils.js",
7
+ "exports": {
8
+ ".": "./perfectionist-utils.js",
9
+ "./perfectionist-utils.js": "./perfectionist-utils.js",
10
+ "./ban-blocker.js": "./ban-blocker.js",
11
+ "./hide-unowned-skins.js": "./hide-unowned-skins.js",
12
+ "./unlock-profile-skins.js": "./unlock-profile-skins.js",
13
+ "./auto-claimer.js": "./auto-claimer.js",
14
+ "./auto-read.js": "./auto-read.js",
15
+ "./better-client.js": "./better-client.js",
16
+ "./dodge-helper.js": "./dodge-helper.js",
17
+ "./auto-accept.js": "./auto-accept.js"
18
+ },
19
+ "files": [
20
+ "perfectionist-utils.js",
21
+ "ban-blocker.js",
22
+ "hide-unowned-skins.js",
23
+ "unlock-profile-skins.js",
24
+ "auto-claimer.js",
25
+ "auto-read.js",
26
+ "better-client.js",
27
+ "dodge-helper.js",
28
+ "auto-accept.js"
29
+ ],
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/SrKing-9812/Perfectionist-Plugins.git"
33
+ },
34
+ "keywords": [
35
+ "pengu-loader",
36
+ "league-of-legends",
37
+ "plugin"
38
+ ],
39
+ "author": "Sr. King"
40
+ }
@@ -5,7 +5,7 @@ const PANEL_ID = "perfectionist-plugins-panel";
5
5
  const STYLE_ID = "perfectionist-plugins-style";
6
6
  const TAB_TITLE = "Perfectionism";
7
7
 
8
- export const version = "2.4.0";
8
+ export const version = "2.4.6";
9
9
 
10
10
  const PKG = "perfectionist-plugins";
11
11
  const CDN = "https://cdn.jsdelivr.net/npm";
@@ -30,7 +30,7 @@ const BUNDLED_MODULES = [
30
30
  id: "ban-blocker",
31
31
  file: "ban-blocker.js",
32
32
  name: "Ban Blocker",
33
- version: "3.6.0",
33
+ version: "3.6.2",
34
34
  description: "Adds a BLOCK button to your teammates in champ select. While a teammate is blocked, the champion they are about to ban is prepicked for you, so their ban can never land on it.",
35
35
  },
36
36
  {
@@ -44,22 +44,22 @@ const BUNDLED_MODULES = [
44
44
  id: "hide-unowned-skins",
45
45
  file: "hide-unowned-skins.js",
46
46
  name: "Hide Unowned Skins",
47
- version: "2.5.1",
47
+ version: "2.4.3",
48
48
  description: "In champ select, the skin carousel only shows the skins you own for the champion you picked.",
49
49
  },
50
50
  {
51
51
  id: "auto-accept",
52
52
  file: "auto-accept.js",
53
53
  name: "Auto Accept",
54
- version: "1.1.2",
55
- description: "Accepts the match for you when the ready check pops up. Add an optional delay, and switch it on or off from the lobby footer.",
54
+ version: "1.1.3",
55
+ description: "Accepts the match for you when the ready check pops up.",
56
56
  },
57
57
  {
58
58
  id: "dodge-helper",
59
59
  file: "dodge-helper.js",
60
60
  name: "Dodge Helper",
61
- version: "1.4.2",
62
- description: "Adds a button to leave champ select: DODGE in ranked Solo/Duo and Flex, with the estimated LP you will lose, and QUIT in every other mode.",
61
+ version: "1.4.3",
62
+ description: "Adds a DODGE/QUIT button to champ select, showing the LP and queue penalty for the next dodge.",
63
63
  },
64
64
  {
65
65
  id: "auto-claimer",
@@ -348,11 +348,11 @@ function findOption(entry, key) {
348
348
  return null;
349
349
  }
350
350
 
351
- function getOption(id, key) {
351
+ function getOption(id, key, fallback = false) {
352
352
  const entry = registry.get(id);
353
- const fallback = findOption(entry, key)?.default;
353
+ const fallbackValue = findOption(entry, key)?.default ?? fallback;
354
354
  const stored = state.options?.[id]?.[key];
355
- return stored === undefined ? Boolean(fallback) : Boolean(stored);
355
+ return stored === undefined ? Boolean(fallbackValue) : Boolean(stored);
356
356
  }
357
357
 
358
358
  function setOption(id, key, value, refresh = true) {
@@ -849,10 +849,23 @@ function refreshPanel() {
849
849
  requestAnimationFrame(() => applyScrollTop(next, top));
850
850
  }
851
851
 
852
+ function settingsNavScope() {
853
+ const title =
854
+ document.querySelector(".lol-settings-nav-title:not([data-perfectionist])") ??
855
+ document.querySelector(".lol-settings-nav-title");
856
+ return title?.closest("lol-uikit-scrollable") ?? title?.parentElement ?? null;
857
+ }
858
+
859
+ function navItems() {
860
+ const scope = settingsNavScope();
861
+ if (!scope) return [];
862
+ return [...scope.querySelectorAll('lol-uikit-navigation-item, [class*="settings-nav"]')];
863
+ }
864
+
852
865
  function setNavActive(activeNav) {
853
- for (const nav of document.querySelectorAll(".lol-settings-nav")) {
866
+ for (const nav of navItems()) {
854
867
  if (nav === activeNav) {
855
- nav.setAttribute("active", "true");
868
+ if (nav.getAttribute("active") !== "true") nav.setAttribute("active", "true");
856
869
  } else if (nav.hasAttribute("active")) {
857
870
  nav.removeAttribute("active");
858
871
  }
@@ -861,6 +874,26 @@ function setNavActive(activeNav) {
861
874
 
862
875
  let panelRequested = false;
863
876
  let syncTimer = null;
877
+ let navObserver = null;
878
+ let nativeActiveBeforeOpen = null;
879
+
880
+ function suppressNativeNavActive() {
881
+ const own = document.getElementById(NAV_ID);
882
+ if (!own) return;
883
+ if (!panelRequested) {
884
+ if (own.hasAttribute("active")) own.removeAttribute("active");
885
+ return;
886
+ }
887
+ for (const nav of navItems()) {
888
+ if (nav !== own && nav.hasAttribute("active")) nav.removeAttribute("active");
889
+ }
890
+ }
891
+
892
+ function watchNavActive() {
893
+ if (navObserver || !document.body) return;
894
+ navObserver = new MutationObserver(suppressNativeNavActive);
895
+ navObserver.observe(document.body, { subtree: true, attributes: true, attributeFilter: ["active"] });
896
+ }
864
897
 
865
898
  function startSync() {
866
899
  if (syncTimer === null) syncTimer = setInterval(keepPanelInSync, 300);
@@ -885,7 +918,11 @@ function openPanel() {
885
918
  if (existing) existing.remove();
886
919
  content.append(buildPanel());
887
920
 
888
- setNavActive(document.getElementById(NAV_ID));
921
+ const ownNav = document.getElementById(NAV_ID);
922
+ if (!nativeActiveBeforeOpen) {
923
+ nativeActiveBeforeOpen = navItems().find((nav) => nav !== ownNav && nav.hasAttribute("active")) ?? null;
924
+ }
925
+ setNavActive(ownNav);
889
926
  const currentTitle = document.querySelector(".lol-settings-title-current");
890
927
  if (currentTitle) currentTitle.textContent = TAB_TITLE.toUpperCase();
891
928
  }
@@ -897,7 +934,9 @@ function closePanel() {
897
934
  panel.remove();
898
935
  const options = document.querySelector(".lol-settings-content .lol-settings-options");
899
936
  if (options) options.style.display = "";
900
- setNavActive(null);
937
+ document.getElementById(NAV_ID)?.removeAttribute("active");
938
+ if (nativeActiveBeforeOpen?.isConnected) nativeActiveBeforeOpen.setAttribute("active", "true");
939
+ nativeActiveBeforeOpen = null;
901
940
  }
902
941
 
903
942
  function keepPanelInSync() {
@@ -905,6 +944,7 @@ function keepPanelInSync() {
905
944
  if (!content) {
906
945
  panelRequested = false;
907
946
  stopSync();
947
+ document.getElementById(NAV_ID)?.removeAttribute("active");
908
948
  return;
909
949
  }
910
950
  if (!panelRequested) {
@@ -923,12 +963,7 @@ function keepPanelInSync() {
923
963
  if (options && options.style.display !== "none") options.style.display = "none";
924
964
 
925
965
  const nav = document.getElementById(NAV_ID);
926
- if (nav) {
927
- for (const other of document.querySelectorAll(".lol-settings-nav")) {
928
- if (other !== nav && other.hasAttribute("active")) other.removeAttribute("active");
929
- }
930
- if (nav.getAttribute("active") !== "true") nav.setAttribute("active", "true");
931
- }
966
+ if (nav) setNavActive(nav);
932
967
 
933
968
  const title = document.querySelector(".lol-settings-title-current");
934
969
  if (title && title.textContent !== TAB_TITLE.toUpperCase()) title.textContent = TAB_TITLE.toUpperCase();
@@ -967,6 +1002,7 @@ function isDoneButton(target) {
967
1002
 
968
1003
  function installSettingsTab() {
969
1004
  addStyle(STYLE_ID, STYLE_CSS);
1005
+ watchNavActive();
970
1006
 
971
1007
  document.addEventListener(
972
1008
  "click",