Greasy Fork

Greasy Fork is available in English.

Magazine Pop-up

Show magazine subscription information on hover

当前为 2023-06-28 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==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();