Displays alternative articles from free sources using Google News
Ekde
// ==UserScript==
// @name The Information | Find Alternative Articles
// @namespace http://your.namespace
// @version 1.0
// @description Displays alternative articles from free sources using Google News
// @author UniverseDev
// @license MIT
// @match https://www.theinformation.com/articles/*
// @grant GM.xmlHttpRequest
// ==/UserScript==
(function() {
'use strict';
function stripHtml(html) {
const tmp = document.createElement('div');
tmp.innerHTML = html;
return (tmp.textContent || tmp.innerText || '').trim();
}
const pageTitle = document.title;
const articleTitle = pageTitle.split(' | ')[0];
const rssUrl = `https://news.google.com/rss/search?q=${encodeURIComponent(articleTitle)}`;
const container = document.createElement('div');
container.style.cssText = `
position: fixed;
top: 150px;
right: 10px;
width: 300px;
max-height: 80vh;
overflow-y: auto;
background: white;
padding: 15px;
font-family: Arial, sans-serif;
z-index: 9999;
`;
container.innerHTML = '<h3 style="margin: 0 0 15px 0; color: #000; font-size: 18px; font-weight: bold;">Alternative Articles</h3><p style="margin: 0; color: #666;">Loading...</p>';
document.body.appendChild(container);
GM.xmlHttpRequest({
method: 'GET',
url: rssUrl,
onload: function(response) {
const xmlText = response.responseText;
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlText, 'text/xml');
const items = xmlDoc.querySelectorAll('item');
const articles = Array.from(items)
.map(item => ({
title: item.querySelector('title')?.textContent || '',
url: item.querySelector('link')?.textContent || '',
description: item.querySelector('description')?.textContent || '',
source: item.querySelector('source')?.textContent || 'Unknown',
date: item.querySelector('pubDate')?.textContent || ''
}))
.filter(article => !article.source.toLowerCase().includes('the information'))
.slice(0, 10);
if (articles.length === 0) {
container.innerHTML = '<h3 style="margin: 0 0 15px 0; color: #000; font-size: 18px; font-weight: bold;">Alternative Articles</h3><p style "margin: 0; color: #666;">No articles found.</p>';
} else {
const articlesHtml = articles.map(article => `
<div style="margin-bottom: 20px;">
<a href="${article.url}" target="_blank" style="display: block; color: #000; font-weight: bold; font-size: 16px; text-decoration: none; margin-bottom: 5px;">${article.title}</a>
${article.description ? `<p style="margin: 0 0 5px 0; color: #333; font-size: 14px; line-height: 1.4;">${stripHtml(article.description)}</p>` : ''}
<small style="color: #666; font-size: 12px;">${article.source} - ${article.date ? new Date(article.date).toLocaleDateString() : 'Unknown date'}</small>
</div>
`).join('');
container.innerHTML = `
<h3 style="margin: 0 0 15px 0; color: #000; font-size: 18px; font-weight: bold;">Alternative Articles <a href="#" style="float: right; font-size: 14px; color: #666; text-decoration: none;" id="close-alternatives">✕</a></h3>
${articlesHtml}
`;
container.querySelector('#close-alternatives').addEventListener('click', (e) => {
e.preventDefault();
container.style.display = 'none';
});
const links = container.querySelectorAll('a');
links.forEach(link => {
link.addEventListener('mouseover', () => link.style.textDecoration = 'underline');
link.addEventListener('mouseout', () => link.style.textDecoration = 'none');
});
}
},
onerror: function(error) {
container.innerHTML = '<h3 style="margin: 0 0 15px 0; color: #000; font-size: 18px; font-weight: bold;">Alternative Articles</h3><p style="margin: 0; color: #666;">Error loading articles.</p>';
console.error('GM.xmlHttpRequest Error:', error);
}
});
})();