Medium to Freedium on New Tab + Full-Screen Overlay

Add a button that opens freedium page in a new tab + full-screen overlay iframe with close button

// ==UserScript==
// @name         Medium to Freedium on New Tab + Full-Screen Overlay
// @namespace    https://greasyfork.org/users/1470715
// @icon         https://icons.duckduckgo.com/ip3/medium.com.ico
// @version      1.4
// @description  Add a button that opens freedium page in a new tab + full-screen overlay iframe with close button
// @author       cattishly6060
// @match        https://*/*
// @grant        GM_addStyle
// @grant        GM_openInTab
// @license      MIT
// @run-at       document-end
// @noframes
// ==/UserScript==

(function() {
  'use strict';

  // Guard flag to prevent multiple executions
  if (window.hasMediumEnhancerRun) return;
  window.hasMediumEnhancerRun = true;

  // Use requestIdleCallback for better performance
  function init() {
    const ogSiteName = document.querySelector('meta[property="og:site_name"]')?.content;
    if (ogSiteName !== 'Medium') return;

    // Add custom styles
    GM_addStyle(`
    .floatingButtonContainer {
      position: fixed;
      right: 20px;
      top: 50%;
      transform: translateY(-50%);
      display: flex;
      flex-direction: column;
      gap: 10px;
      z-index: 9999;
    } 
    
    .btn {
      transform: translateY(-50%);
      background: #0942a3;
      color: white;
      border: none;
      border-radius: 50%;
      width: 50px;
      height: 50px;
      font-size: 20px;
      cursor: pointer;
      box-shadow: 0 2px 10px rgba(0,0,0,0.2);
      transition: all 0.3s ease;
    }

    .btn:hover {
      background: #3367d6;
      transform: translateY(-50%) scale(1.1);
    }

    #iframeOverlay {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: white;
      z-index: 9999;
      display: none;
    }

    #iframeContainer {
      position: relative;
      width: 100%;
      height: 100%;
    }

    #closeIframe {
      position: absolute;
      top: 15px;
      right: 25px; /* Increased from 10px to avoid scrollbar */
      z-index: 10000;
      background: #a20001;
      color: white;
      border: none;
      border-radius: 50%;
      width: 40px; /* Increased from 30px */
      height: 40px; /* Increased from 30px */
      font-size: 22px; /* Increased from 16px */
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      box-shadow: 0 2px 5px rgba(0,0,0,0.2);
    }

    #closeIframe:hover {
      background: #cc0000;
      transform: scale(1.1);
    }

    #iframeContent {
      width: 100%;
      height: 100%;
      border: none;
    }
  `);

    // Create button group
    const buttonGroup = document.createElement('div');
    buttonGroup.classList.add('floatingButtonContainer');
    buttonGroup.style.cssText = '';

    // Create overlay button
    const overlayButton = document.createElement('button');
    overlayButton.className = 'btn';
    overlayButton.textContent = '🔓';
    overlayButton.title = 'Open freedium page in overlay';
    buttonGroup.appendChild(overlayButton);

    // Create open new tab button
    const newTabButton = document.createElement('button');
    newTabButton.className = 'btn';
    newTabButton.textContent = '↗️';
    newTabButton.title = 'Open freedium page in new tab';
    buttonGroup.appendChild(newTabButton);
    document.body.appendChild(buttonGroup);

    // Create overlay container
    const overlay = document.createElement('div');
    overlay.id = 'iframeOverlay';

    const container = document.createElement('div');
    container.id = 'iframeContainer';

    const closeButton = document.createElement('button');
    closeButton.id = 'closeIframe';
    closeButton.innerHTML = '×';
    closeButton.title = 'Close overlay';

    const iframe = document.createElement('iframe');
    iframe.id = 'iframeContent';

    container.appendChild(closeButton);
    container.appendChild(iframe);
    overlay.appendChild(container);
    document.body.appendChild(overlay);

    // Function to replace host in URL
    function replaceHost(url, newHost) {
      try {
        const urlObj = new URL(url);
        urlObj.host = newHost;
        return urlObj.toString();
      } catch (e) {
        console.error("Error processing URL:", e);
        return url;
      }
    }

    // Button click handler
    overlayButton.addEventListener('click', function () {
      const url = replaceHost(window.location.href, 'freedium.cfd');
      if (url) {
        iframe.src = url;
        overlay.style.display = 'block';
        document.body.style.overflow = 'hidden'; // Prevent scrolling on main page
      }
    });

    newTabButton.addEventListener('click', function () {
      const url = replaceHost(window.location.href, 'freedium.cfd');
      GM_openInTab(url, {active: true});
    });

    // Close button handler
    closeButton.addEventListener('click', function () {
      overlay.style.display = 'none';
      iframe.src = '';
      document.body.style.overflow = ''; // Restore scrolling
    });

    // Close when clicking outside iframe (optional)
    overlay.addEventListener('click', function (e) {
      if (e.target === overlay) {
        overlay.style.display = 'none';
        iframe.src = '';
        document.body.style.overflow = '';
      }
    });
  }

  // More efficient than load event for most cases
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init, { once: true });
  } else {
    // If already loaded, run immediately but yield to browser
    requestIdleCallback(init);
  }
})();