Greasy Fork is available in English.

NewsNow Filter

Filter NewsNow articles by phrase/topic

// ==UserScript==
// @name         NewsNow Filter
// @namespace    https://www.newsnow.co.uk/
// @version      1.4
// @license      GPLv3
// @description  Filter NewsNow articles by phrase/topic
// @author       xdpirate
// @match        https://*.newsnow.co.uk/*
// @match        https://*.newsnow.com/*
// @match        https://*.newsnow.it/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=newsnow.co.uk
// @run-at       document-end
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_addStyle
// ==/UserScript==

if(window.self !== window.top) {
    throw "NNF: Not in topmost frame, bye";
}

window.setTimeout(function() {
    GM_addStyle(`
        #NNFToggleButton {
            cursor: pointer;
        }

        #NNFBlacklistArea {
            background-color: black;
            color: white;
            font-family: monospace;
        }

        #NNFOuterDiv {
            float: left;
            background-color: black;
            color: white;
            padding: 5px;
            border: 1px solid white;
            border-radius: 10px;
            z-index: 2147483647;
            position: absolute;
            top: 100px;
            left: 100px;
        }

        #NNFCloseButton {
            cursor: pointer;
        }

        .hidden {
            display: none;
        }
        
        #NNFFilterLog {
            width: 100%;
            height: 100px;
            font-size: 10px;
        }
    `);

    let blacklist = GM_getValue("blacklist", ["Elon Musk", "Donald Trump"]);

    let empty = false;
    if(blacklist.length == 0 || (blacklist.length == 1 && blacklist[0] == "") || blacklist == undefined || blacklist == null) {
        empty = true;
    }

    let regexStr = "[.+]?(";
    if(!empty) {
        for(let j = 0; j < blacklist.length; j++) {
            // Don't start with a pipe
            if(j > 0) { 
                regexStr = regexStr + "|";
            }
            regexStr = regexStr + blacklist[j].replaceAll(".","\\.");
        }
    }
    regexStr = regexStr + ")[.+]?";

    let regex = new RegExp(regexStr, "i");

    let newBox = document.createElement("div");
    newBox.innerHTML = `
        <div id="NNFOuterDiv" class="hidden">
            <div id="NNFInnerDiv">
                <span id="NNFCloseButton" title="Close">❌</span> <b>NewsNow Filter</b><br />
                Comma-separated list of blacklisted titles or topics:<br />
                <textarea id="NNFBlacklistArea" rows="10" cols="80">${blacklist}</textarea><br />
                <small><a href="#" onclick="document.getElementById('NNFFilterLogDiv').classList.toggle('hidden');">Filter log</a></small><br />
                <div id="NNFFilterLogDiv" class="hidden">
                    <textarea id="NNFFilterLog" readonly></textarea>
                </div><br />
                <input type="button" value="Save and reload" id="NNFSaveButton"></input>
            <div>
        </div>
    `;

    document.body.append(newBox);

    document.getElementById("NNFCloseButton").onclick = function() {
        document.getElementById("NNFOuterDiv").classList.toggle("hidden");
    };

    document.getElementById("NNFBlacklistArea").onkeydown = function(e) {
        if (e.key === "Escape") {
            document.getElementById("NNFOuterDiv").classList.add("hidden");
        }
    };

    document.getElementById("NNFSaveButton").onclick = function() {
        GM_setValue("blacklist", document.getElementById("NNFBlacklistArea").value.split(","));
        location.reload();
    };

    let c = 0;
    if(!empty) {
        let results = document.querySelectorAll("div.hl > div.hl__inner"); 
        for(let i = 0; i < results.length; i++) {
            // NewsNow has some hidden duplicate elements of top stories, for some reason.
            // Check if the current element is visible, continue to next iteration if it's not.
            // It doesn't hurt to iterate the invisible ones, but it'll return a wrongful filter count
            if(results[i].offsetParent === null) { 
                continue;
            }

            let title = results[i].querySelector("a.hll").innerText;
            let categories = results[i].querySelectorAll("span.favtags > a.fav");
            
            if(regex.test(title)) {
                results[i].closest("div.hl").style.display = "none";
                c++;
                document.getElementById('NNFFilterLog').value += `Title match: "${title.match(regex)[1]}" found in "${title}"\n\n`;
                continue;
            }

            if(categories) {
                for(let j = 0; j < categories.length; j++) {
                    if(regex.test(categories[j].innerText)) {
                        results[i].closest("div.hl").style.display = "none";
                        c++;
                        document.getElementById('NNFFilterLog').value += `Category match: "${categories[j].innerText.match(regex)[1]}" found in "${categories[j].innerText}"\n\n`;
                        break;
                    }
                }
            }
        }
    }

    let pageTop = document.querySelector("h1.heading-1");

    if(!pageTop) {
        pageTop = document.querySelector("h2.heading-2");
    }

    let filterLink = document.createElement("div");
    
    filterLink.innerHTML = `<div style="cursor: pointer; border-radius: 10px; vertical-align: center; padding: 10px; background: #000; color: #fff; border: 2px solid #fff;">Filter (${c})</div>`;
    filterLink.onclick = function() {
        document.getElementById("NNFOuterDiv").classList.toggle("hidden");
    };
    pageTop.insertAdjacentElement("afterend", filterLink);
}, 1500);