I don’t know if it’s just me - I go to great lengths to keep my fedi activity separate from my other internet activity, and I get REALLY mad when I’m browsing Lemmy, click something that I assume will take me to a local discussion (or meme, mostly,) and it opens some random external site - often one I’ve never even heard of - and now who knows what that site is doing, trying to do, cookies, etc., trying to link me and my referrer to my other activity (I do all my fedi stuff by VPN too, so it wouldn’t be by IP, but, they have ways) etc. etc.

As I couldn’t find anything already available, I finally got off my butt and just made something to prevent it. These files can be dumped in a local folder, and then under Chrome/Opera/anything-Chromium extensions, you can ‘enable developer options’, and then ‘load unpacked’. It’s SUPER simple, and works, you just need to customize your instance hostname. I thought it might be something at least one other person in this community has thought about and fought with, so I figured I’d share it here!

Edit: Seems to be working most of the time, but then starts failing and external sites load without a popup (granted I’m testing it HARD, and normally it’s just a one-off that I don’t catch is an external link with my eyeballs first) - not sure if/how to troubleshoot, but will try. Just be warned, it’s not flawless.

^ Seems to be fixed in latest version. ^

background.js - empty file, but required

content.js -

// List of allowed domains
const allowedDomains = ['lemmy.ml']; // You can add other domains here

// Function to check if the current domain is allowed
function isAllowedDomain() {
  const currentDomain = window.location.hostname;
  return allowedDomains.includes(currentDomain);
}

// Event handler for link clicks
function linkClickHandler(event) {
  const href = this.href;
  const currentDomain = window.location.hostname;

  if (new URL(href).hostname !== currentDomain) {
    event.preventDefault(); // Prevent default navigation
    const confirmation = confirm("You are about to leave " + currentDomain + ". Do you want to continue?");
    if (confirmation) {
      window.open(href, '_blank'); // Open in a new tab
    }
  }
}

// Attach link listeners
function addLinkListeners() {
  if (!isAllowedDomain()) return; // Only add listeners if on an allowed domain
  
  const links = document.querySelectorAll('a');
  
  links.forEach(link => {
    if (!link.dataset.listenerAdded) { // Check if listener is already added
      link.addEventListener('click', linkClickHandler);
      link.dataset.listenerAdded = true; // Mark this link as having the listener
    }
  });
}

// Initial listener setup
addLinkListeners();

// Create a MutationObserver to watch for changes in the DOM
const observer = new MutationObserver((mutations) => {
  mutations.forEach(mutation => {
    if (mutation.addedNodes.length) {
      addLinkListeners(); // Reattach listeners for new links
    }
  });
});

// Observe the body for child additions
observer.observe(document.body, {
  childList: true,
  subtree: true
});

manifest.json -

{
  "manifest_version": 3,
  "name": "Block External Links",
  "version": "1.1.2",
  "permissions": [
    "tabs",
    "activeTab"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"]
    }
  ]
}

Hope this is useful to someone!!

  • IndigoGolem@lemmy.world
    link
    fedilink
    arrow-up
    4
    ·
    1 day ago

    See also: Firefox tab containers (built in feature), Temporary Containers extension (makes a new temporary folder for cookies & cache every time you go to a new domain/subdomain), and uMatrix extension (block embedded anything from any source, by domain & subdomain).