PenguinMod stylish single-tabbed addons

Makes the addons page open in a stylish iframe instead of in a new tab.

  1. // ==UserScript==
  2. // @name PenguinMod stylish single-tabbed addons
  3. // @namespace https://studio.penguinmod.com
  4. // @version 2025-01-25
  5. // @description Makes the addons page open in a stylish iframe instead of in a new tab.
  6. // @author Pooiod7
  7. // @match https://studio.penguinmod.com/editor.html
  8. // @match https://studio.penguinmod.com
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=penguinmod.com
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. setInterval(() => {
  17. const AddonsButton = Array.from(document.querySelectorAll('div')).find(btn => {
  18. const div = btn.querySelector('div');
  19. const span = div?.querySelector('span');
  20. if (span?.textContent.trim() === 'Addons') {
  21. return btn;
  22. }
  23. });
  24. const existingButton = document.getElementById("StylishAddonsButton");
  25.  
  26. if (AddonsButton && !existingButton) {
  27. const newAddonsButton = AddonsButton.cloneNode(true);
  28. newAddonsButton.id = "StylishAddonsButton";
  29. AddonsButton.parentNode.replaceChild(newAddonsButton, AddonsButton);
  30.  
  31. newAddonsButton.addEventListener("click", function(event) {
  32. event.preventDefault();
  33. event.stopImmediatePropagation();
  34.  
  35. if (document.getElementById("widgetoverlay")) return;
  36.  
  37. const overlay = document.createElement('div');
  38. overlay.style.position = 'fixed';
  39. overlay.style.top = '0';
  40. overlay.style.left = '0';
  41. overlay.style.width = '100%';
  42. overlay.style.height = '100%';
  43. overlay.style.backgroundColor = 'rgba(0, 195, 255, 0.7)';
  44. overlay.style.zIndex = '9999';
  45. overlay.id = "widgetoverlay";
  46.  
  47. const wrapper = document.createElement('div');
  48. wrapper.style.position = 'absolute';
  49. wrapper.style.top = "50%";
  50. wrapper.style.left = "50%";
  51. wrapper.style.transform = 'translate(-50%, -50%)';
  52. wrapper.style.border = '4px solid rgba(255, 255, 255, 0.25)';
  53. wrapper.style.borderRadius = '13px';
  54. wrapper.style.padding = '0px';
  55. wrapper.style.width = '70vw';
  56. wrapper.style.height = '80vh';
  57.  
  58. const modal = document.createElement('div');
  59. modal.style.backgroundColor = 'var(--ui-primary, white)';
  60. modal.style.padding = '0px';
  61. modal.style.borderRadius = '10px';
  62. modal.style.width = '100%';
  63. modal.style.height = '100%';
  64. modal.style.textAlign = 'center';
  65.  
  66. wrapper.appendChild(modal);
  67.  
  68. const title = document.createElement('div');
  69. title.style.position = 'absolute';
  70. title.style.top = '0';
  71. title.style.left = '0';
  72. title.style.width = '100%';
  73. title.style.height = '50px';
  74. title.style.backgroundColor = 'rgb(0, 195, 255)';
  75. title.style.display = 'flex';
  76. title.style.justifyContent = 'center';
  77. title.style.alignItems = 'center';
  78. title.style.color = 'white';
  79. title.style.fontSize = '24px';
  80. title.style.borderTopLeftRadius = '10px';
  81. title.style.borderTopRightRadius = '10px';
  82. title.innerHTML = "Addons";
  83.  
  84. const iframe = document.createElement('iframe');
  85. iframe.src = '/addons.html';
  86. iframe.style.width = '100%';
  87. iframe.style.height = `calc(100% - 50px)`;
  88. iframe.style.marginTop = '50px';
  89. iframe.style.border = 'none';
  90. iframe.style.borderBottomLeftRadius = '10px';
  91. iframe.style.borderBottomRightRadius = '10px';
  92. modal.appendChild(iframe);
  93.  
  94. const closeButton = document.createElement('div');
  95. closeButton.setAttribute('aria-label', 'Close');
  96. closeButton.classList.add('close-button_close-button_lOp2G', 'close-button_large_2oadS');
  97. closeButton.setAttribute('role', 'button');
  98. closeButton.setAttribute('tabindex', '0');
  99. closeButton.innerHTML = '<img class="close-button_close-icon_HBCuO" src="data:image/svg+xml,%3Csvg%20data-name%3D%22Layer%201%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%207.48%207.48%22%3E%3Cpath%20d%3D%22M3.74%206.48V1M1%203.74h5.48%22%20style%3D%22fill%3Anone%3Bstroke%3A%23fff%3Bstroke-linecap%3Around%3Bstroke-linejoin%3Around%3Bstroke-width%3A2px%22%2F%3E%3C%2Fsvg%3E">';
  100. closeButton.style.position = 'absolute';
  101. closeButton.style.top = '50%';
  102. closeButton.style.right = '10px';
  103. closeButton.style.transform = 'translateY(-50%)';
  104. closeButton.style.zIndex = '1000';
  105. closeButton.addEventListener('click', () => {
  106. document.body.removeChild(overlay);
  107. });
  108. title.appendChild(closeButton);
  109.  
  110. modal.appendChild(title);
  111. overlay.appendChild(wrapper);
  112. document.body.appendChild(overlay);
  113.  
  114. overlay.addEventListener('click', (e) => {
  115. if (e.target === overlay) {
  116. document.body.removeChild(overlay);
  117. }
  118. });
  119. });
  120. }
  121. }, 1000);
  122. })();