您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Filters Hacker News Show submissions to only show open-source projects, removes clutter, and re-ranks items.
- // ==UserScript==
- // @name Hacker News Show HN Open Source Filter
- // @namespace http://tampermonkey.net/
- // @version 0.4
- // @description Filters Hacker News Show submissions to only show open-source projects, removes clutter, and re-ranks items.
- // @author sm18lr88 (https://github.com/sm18lr88)
- // @license MIT
- // @match https://news.ycombinator.com/show
- // @match https://news.ycombinator.com/show*
- // @grant none
- // ==/UserScript==
- (function() {
- 'use strict';
- const OPEN_SOURCE_HOSTS = [
- "github.com",
- "gitlab.com",
- "bitbucket.org",
- "sourceforge.net",
- "github.io",
- "codeberg.org",
- // Add more known open-source hosting domain suffixes if needed
- ];
- /**
- * Removes the "Show HN: " prefix from titles.
- */
- function removeShowHnPrefix() {
- const titles = document.querySelectorAll('#hnmain .titleline > a');
- titles.forEach(title => {
- if (title.textContent.startsWith('Show HN: ')) {
- title.textContent = title.textContent.replace('Show HN: ', '');
- }
- });
- }
- /**
- * Checks if a URL points to a known open-source repository or project page.
- * @param {string} urlString - The URL to check.
- * @returns {boolean} True if it's considered an open-source link, false otherwise.
- */
- function isRepoLink(urlString) {
- if (!urlString) return false;
- try {
- const url = new URL(urlString); // Handles absolute URLs
- const hostname = url.hostname.toLowerCase();
- // Check if the hostname or a parent domain is in our list
- if (OPEN_SOURCE_HOSTS.some(host => hostname === host || hostname.endsWith('.' + host))) {
- return true;
- }
- } catch (e) {
- // Likely a relative URL (e.g., "item?id=...") or invalid.
- // These are not considered direct open-source repo links.
- return false;
- }
- return false;
- }
- /**
- * Filters submissions to keep only those linking to open-source projects.
- * Removes the submission row, its subtext row, and its spacer row if not open source.
- */
- function filterSubmissions() {
- const submissions = document.querySelectorAll('#hnmain tr.athing.submission');
- submissions.forEach(submissionRow => {
- const titleLink = submissionRow.querySelector('.titleline > a');
- if (titleLink) {
- const url = titleLink.href;
- if (!isRepoLink(url)) {
- const subtextRow = submissionRow.nextElementSibling; // This is the row with score, user, comments
- const spacerRow = subtextRow ? subtextRow.nextElementSibling : null; // This is the <tr class="spacer">
- submissionRow.remove();
- if (subtextRow) {
- subtextRow.remove();
- }
- // Ensure spacerRow is indeed a spacer before removing
- if (spacerRow && spacerRow.classList.contains('spacer')) {
- spacerRow.remove();
- }
- }
- }
- });
- }
- /**
- * Removes unnecessary clutter from the page, like the intro "rules" div and footer links.
- */
- function removePageClutter() {
- // Remove the "Please read the Show HN rules..." div
- // This div is a child of a TD and contains a link to 'showhn.html'
- const allTdDivs = document.querySelectorAll('#hnmain td > div');
- allTdDivs.forEach(div => {
- if (div.querySelector('a[href="showhn.html"]') && div.textContent.includes("Please read the Show HN rules")) {
- div.remove();
- }
- });
- // Remove the footer yclinks (Guidelines, FAQ, Lists, API, etc.)
- const yclinksSpan = document.querySelector('span.yclinks');
- if (yclinksSpan) {
- // Optionally remove the <br> tags and Search form if the whole center block is to be cleaned.
- // For now, just removing the yclinks span itself.
- yclinksSpan.remove();
- // If you want to remove the surrounding <center> tag that also contains the search bar:
- // const centerContainer = yclinksSpan.closest('center');
- // if (centerContainer) centerContainer.remove();
- }
- }
- /**
- * Re-numbers the rank of the remaining visible items.
- */
- function updateRanks() {
- const remainingRanks = document.querySelectorAll('#hnmain tr.athing.submission .rank');
- remainingRanks.forEach((rankSpan, index) => {
- rankSpan.textContent = `${index + 1}.`;
- });
- }
- // --- Execute the functions ---
- removeShowHnPrefix();
- filterSubmissions();
- removePageClutter();
- updateRanks();
- })();