Greasy Fork

Magazine Pop-up

Show magazine subscription information on hover

目前为 2023-06-28 提交的版本。查看 最新版本

// ==UserScript==
// @name        Magazine Pop-up
// @namespace   Violentmonkey Scripts
// @match       https://kbin.social/*
// @grant       GM_getValue
// @version     1.0
// @author      -
// @license MIT
// @description Show magazine subscription information on hover
// ==/UserScript==

// Select all magazine URL elements
let magazineURLs = document.querySelectorAll('a.magazine-inline');


// Create a pop-up element to display the sidebar information
const popUp = document.createElement('div');
popUp.className = 'pop-up';
popUp.style.zIndex = '9999'; // Set the desired z-index value

// Apply box styling to the pop-up element
popUp.style.border = '1px solid #363434'; // Customize the border style
popUp.style.backgroundColor = '#2c2c2c'; // Customize the background color
popUp.style.padding = '10px'; // Customize the padding
popUp.style.width = '440px';
popUp.style.height = '165px';
popUp.style.borderRadius = '8px';
popUp.style.overflow = 'none'; // Add this line to enable scrolling

// Add event listener to prevent scroll event propagation
popUp.addEventListener('scroll', (event) => {
  event.stopPropagation();
});

// Adjust the spacing within the pop-up content
popUp.style.lineHeight = '1.0'; // Reduce line height to make content closer
popUp.style.margin = '0'; // Remove margin to reduce spacing

// Adjust the spacing for specific elements within the pop-up
popUp.querySelectorAll('p').forEach((paragraph) => {
  paragraph.style.margin = '0 0 10px'; // Adjust margin as desired
});

popUp.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach((heading) => {
  heading.style.margin = '0 0 5px'; // Adjust margin as desired
});

popUp.querySelectorAll('ul, ol').forEach((list) => {
  list.style.margin = '0 0 5px'; // Adjust margin as desired
});

popUp.querySelectorAll('li').forEach((listItem) => {
  listItem.style.margin = '0 0 5px'; // Adjust margin as desired
});

// Function to fetch sidebar information for a given URL
async function fetchSidebarInfo(url) {
  const cachedContent = GM_getValue(url); // Check if content is cached

  if (cachedContent) {
    return cachedContent;
  } else {
    try {
      const response = await fetch(url);
      const html = await response.text();
      const parser = new DOMParser();
      const doc = parser.parseFromString(html, 'text/html');
      const sidebarElement = doc.querySelector('section.magazine.section'); // Adjust the selector based on the structure of the sidebar on the page
      const sidebarHTML = sidebarElement.innerHTML;

      // Cache the sidebar content
      GM_setValue(url, sidebarHTML);

      return sidebarHTML;
    } catch (error) {
      console.error('Error fetching sidebar information:', error);
      return null;
    }
  }
}

// Function to show the pop-up
function showPopUp(magazineURL) {

  // Clear any existing content in the pop-up
  popUp.innerHTML = '';

  // Get the URL from the magazine link
  const url = magazineURL.getAttribute('href');

  // Fetch the sidebar information for the URL
  fetchSidebarInfo(url)
    .then((sidebarHTML) => {
      if (sidebarHTML) {
        // Create a temporary container element to manipulate the sidebar content
        const tempContainer = document.createElement('div');
        tempContainer.innerHTML = sidebarHTML;

        // Remove the title name from the magazine
        const titleElement = tempContainer.querySelector('h3');
        if (titleElement) {
          titleElement.parentNode.removeChild(titleElement);
        }
        const contentElement = tempContainer.querySelector('.magazine__description');
        if (contentElement) {
          contentElement.parentNode.removeChild(contentElement);
        }
                const addElement = tempContainer.querySelector('.mb-2');
        if (addElement) {
          addElement.parentNode.removeChild(addElement);
        }
        const tagsElement = tempContainer.querySelector('.mt-3');
        if (tagsElement) {
          tagsElement.parentNode.removeChild(tagsElement);
        }
         const metaElement = tempContainer.querySelector('.meta');
        if (metaElement) {
          metaElement.parentNode.removeChild(metaElement);
        }
          const rulesElement = tempContainer.querySelector('.magazine__rules');
        if (rulesElement) {
          rulesElement.parentNode.removeChild(rulesElement);
        }
// Move the magazine's image figure to the top of the pop-up
const figureElement = tempContainer.querySelector('img');
if (figureElement) {
  figureElement.style.maxWidth = '145px'; // Adjust the desired maximum width for the image
  figureElement.style.width = 'auto'; // Allow the image to resize while maintaining aspect ratio
  figureElement.style.borderRadius = '8px'; // Add border radius to the image

  const popUpContent = document.createElement('div');
  popUpContent.className = 'pop-up-content';
  popUpContent.style.display = 'flex'; // Enable flexbox layout
  popUpContent.style.alignItems = 'flex-start'; // Align items at the top

// Move the magazine header and subscribe section to the right of the image
const headerElement = tempContainer.querySelector('header');
const magazineName = tempContainer.querySelector('.magazine__name');
const subscribeElement = tempContainer.querySelector('.magazine__subscribe');
if (headerElement || magazineName || subscribeElement) {
  const infoWrapper = document.createElement('div');
  infoWrapper.style.display = 'flex'; // Enable flexbox layout
  infoWrapper.style.flexDirection = 'column'; // Stack items vertically
  infoWrapper.style.marginLeft = '25px'; // Add margin to the left side of the header and subscribe sections
  infoWrapper.style.marginTop = '-25px'; // Add margin to the left side of the header and subscribe sections
  infoWrapper.style.alignItems = 'center'; // Center items vertically
  infoWrapper.style.gap = '5px'; // Adjust the desired spacing between the header and subscribe sections

  if (headerElement) {
    headerElement.style.textAlign = 'center'; // Center align the header
    headerElement.style.fontFamily = 'Arial, sans-serif'; // Adjust the font family
    headerElement.style.fontSize = '12.5px'; // Adjust the font size
    headerElement.style.marginBottom = '-10px'; // Adjust the negative margin bottom value to move the figure higher
    infoWrapper.appendChild(headerElement);
  }

if (magazineName) {
  magazineName.style.fontFamily = 'Arial, sans-serif'; // Adjust the font family
  magazineName.style.fontSize = '13.5px'; // Adjust the font size
  magazineName.style.overflow = 'hidden'; // Add this line to hide the overflowed text
  magazineName.style.textOverflow = 'ellipsis'; // Add this line to display ellipsis (...) for overflowed text
  magazineName.style.whiteSpace = 'auto'; // Add this line to prevent line wrapping


  infoWrapper.appendChild(magazineName);
}

  if (subscribeElement) {
    subscribeElement.style.marginTop = '0'; // Remove the margin at the top of the subscribe section
    subscribeElement.style.fontFamily = 'Arial, sans-serif'; // Adjust the font family
    subscribeElement.style.fontSize = '10px'; // Adjust the font size
    infoWrapper.appendChild(subscribeElement);
  }

  popUpContent.appendChild(figureElement);
  popUpContent.appendChild(infoWrapper);
} else {
  popUpContent.appendChild(figureElement);
}



  popUp.appendChild(popUpContent);

}

        // Append the modified sidebar information to the pop-up
        popUp.innerHTML += tempContainer.innerHTML;

        // Position the pop-up element relative to the magazine URL
        const magazineURLRect = magazineURL.getBoundingClientRect();
        const popUpHeight = popUp.offsetHeight;
        const popUpWidth = popUp.offsetWidth;

        let popUpTop, popUpLeft;

        if (magazineURLRect.bottom + popUpHeight > window.innerHeight) {
          popUpTop = magazineURLRect.top - popUpHeight;
        } else {
          popUpTop = magazineURLRect.bottom;
        }

        if (magazineURLRect.left + popUpWidth > window.innerWidth) {
          popUpLeft = window.innerWidth - popUpWidth;
        } else {
          popUpLeft = magazineURLRect.left;
        }

        // Apply the calculated position to the pop-up element
        popUp.style.position = 'fixed';
        popUp.style.top = `${popUpTop}px`;
        popUp.style.left = `${popUpLeft}px`;

        // Add the pop-up element to the document body
        document.body.appendChild(popUp);

        // Apply fade-in animation to the pop-up
        popUp.style.opacity = '0';
        popUp.style.transition = 'opacity 0.3s';

        requestAnimationFrame(() => {
          popUp.style.opacity = '1';
        });
      }
    })
    .catch((error) => {
      console.error('Error fetching sidebar information:', error);
    });
}



// Function to hide the pop-up
function hidePopUp() {
  // Check if the cursor is still inside the pop-up
  if (popUp.matches(':hover')) {
    return;
  }

  // Apply fade-out animation to the pop-up
  popUp.style.opacity = '0';
  popUp.style.transition = 'opacity 0.3s';

  // Remove the pop-up element from the document body after the animation ends
  setTimeout(() => {
    document.body.removeChild(popUp);
  }, 1000);
}

// Function to attach hover functionality to the magazine URLs
function attachHoverFunctionality() {
  magazineURLs.forEach((magazineURL) => {
    let hideTimeout; // Variable to store the timeout ID

    // Add event listener to show the pop-up when hovering over the magazine URL or the pop-up itself
    magazineURL.addEventListener('mouseenter', () => {
      // Clear the timeout if it exists (to prevent premature hiding)
      clearTimeout(hideTimeout);

      // Set a timeout of 1000ms (1 second) before showing the pop-up
      hideTimeout = setTimeout(() => {
        showPopUp(magazineURL);
      }, 2000);
    });

   // Add event listener to hide the pop-up when the cursor leaves the magazine URL or the pop-up itself
magazineURL.addEventListener('mouseleave', () => {
  // Clear the timeout to prevent the pop-up from appearing
  clearTimeout(hideTimeout);

  // Check if the cursor is still inside the pop-up
  const isCursorInsidePopUp = popUp.matches(':hover');

  // Set a delay of 1000ms (1 second) before hiding the pop-up if the cursor is not inside the pop-up
  if (!isCursorInsidePopUp) {
    hideTimeout = setTimeout(() => {
      hidePopUp();
    }, 1000);
  }
});
  });

  // Add event listener to hide the pop-up when the cursor leaves the pop-up
  popUp.addEventListener('mouseleave', () => {
    // Set a delay of 1000ms (1 second) before hiding the pop-up
    setTimeout(() => {
      hidePopUp();
    }, 1000);
  });
}

// Function to observe changes in the page and attach hover functionality to new magazine URLs
function observePageChanges() {
  const observer = new MutationObserver(() => {
    magazineURLs = document.querySelectorAll('a.magazine-inline');
    attachHoverFunctionality();
  });

  const config = { childList: true, subtree: true };
  observer.observe(document.body, config);
}

// Call the function to attach hover functionality to existing magazine URLs
attachHoverFunctionality();

// Call the function to observe page changes and attach hover functionality to newly added magazine URLs
observePageChanges();