Hide Unsplash+ photos and related mentions on unsplash.com
// ==UserScript==
// @name Hide Unsplash+ Content
// @namespace http://tampermonkey.net/
// @version 1.3
// @description Hide Unsplash+ photos and related mentions on unsplash.com
// @author KosherKale
// @match https://unsplash.com/*
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const selectors = {
// Navigation and promotional content
promoContent: [
'a[href*="/plus"]',
'div[data-test="related-promo-banner"]',
'nav a[href*="unsplash.com/plus"]',
'button[data-test="nav-bar-plus-button"]',
'.js-plus-info-modal',
'[data-test="paywall-modal"]'
],
// Photo grid and images
photoContent: [
// Target figures/photos with plus icons or locked download buttons
'figure:has(button:has(svg[title*="plus"]))',
'figure:has(.js-plus-tag)',
'figure:has(a[href*="/plus"])',
// Target the entire photo card if it contains plus content
'div[data-test="photo-grid-masonry-item"]:has(button:has(svg[title*="plus"]))',
'div[data-test="photo-grid-masonry-item"]:has(.js-plus-tag)',
// Target direct plus promotion containers
'div[data-test="plus-photos-modal"]',
'div[data-test="plus-upsell"]'
]
};
function hideElements() {
// Combine all selectors
const allSelectors = [...selectors.promoContent, ...selectors.photoContent];
// Hide elements matching our selectors
allSelectors.forEach(selector => {
try {
document.querySelectorAll(selector).forEach(element => {
// Hide the element and its parent figure/container if it exists
element.style.display = 'none';
const parentFigure = element.closest('figure, div[data-test="photo-grid-masonry-item"]');
if (parentFigure) {
parentFigure.style.display = 'none';
}
});
} catch (e) {
console.debug(`Selector "${selector}" failed:`, e);
}
});
// Additional check for locked content indicators
document.querySelectorAll('figure, div[data-test="photo-grid-masonry-item"]').forEach(element => {
const hasLockIcon = element.querySelector('svg[aria-label*="lock"], svg[title*="lock"]');
const hasPlusButton = element.querySelector('button:has(svg[title*="plus"])');
if (hasLockIcon || hasPlusButton) {
element.style.display = 'none';
}
});
}
// Run on initial load
hideElements();
// Create observer for dynamic content
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.addedNodes.length) {
hideElements();
}
});
});
// Start observing document for dynamic changes
observer.observe(document.body, {
childList: true,
subtree: true
});
// Also run on URL changes (for single page app navigation)
let lastUrl = location.href;
new MutationObserver(() => {
const url = location.href;
if (url !== lastUrl) {
lastUrl = url;
hideElements();
}
}).observe(document, { subtree: true, childList: true });
})();