// ==UserScript== // @name Instacart Ad Remover // @namespace https://greasyfork.org/users/1354160 // @version 72.0.0.260916 // @description Blocks those nasty Instacart ads on various pages, including in search, store home page, user home page, cart, etc. Also removes dynamically inserted promo blocks. // @downloadURL https://raw.githubusercontent.com/LanikSJ/userscripts/main/instacart-ad-remover.js // @updateURL https://raw.githubusercontent.com/LanikSJ/userscripts/main/instacart-ad-remover.js // @homepageURL https://laniksj.github.io/userscripts // @author LanikSJ // @license MIT // @match https://*.instacart.ca/* // @match https://*.instacart.com/* // @grant GM_addStyle // ==/UserScript== (function () { 'use strict'; /* global unsafeWindow */ unsafeWindow.Element.prototype._attachShadow = unsafeWindow.Element.prototype.attachShadow; unsafeWindow.Element.prototype.attachShadow = function () { return this._attachShadow({ mode: "open" }); }; function waitForKeyElements(selectorOrFunction, callback, waitOnce, interval, maxIntervals) { if (typeof waitOnce === "undefined") { waitOnce = true; } if (typeof interval === "undefined") { interval = 300; } if (typeof maxIntervals === "undefined") { maxIntervals = -1; } var targetNodes = typeof selectorOrFunction === "function" ? selectorOrFunction() : document.querySelectorAll(selectorOrFunction); var targetsFound = targetNodes && targetNodes.length > 0; if (targetsFound) { targetNodes.forEach(function (targetNode) { var attrAlreadyFound = "data-userscript-alreadyFound"; var alreadyFound = targetNode.getAttribute(attrAlreadyFound) || false; if (!alreadyFound) { var cancelFound = callback(targetNode); if (cancelFound) { targetsFound = false; } else { targetNode.setAttribute(attrAlreadyFound, true); } } }); } if (maxIntervals !== 0 && !(targetsFound && waitOnce)) { maxIntervals -= 1; setTimeout(function () { waitForKeyElements(selectorOrFunction, callback, waitOnce, interval, maxIntervals); }, interval); } } let sponsoredTexts = ["promoted", "sponsoreed", "sponsored", "spaahnserd", "spawhnserd", "spawnserd", "spaunsered", "spaunserd", "spauncered", "spauncerd", "spohnserd", "spohncerd", "spohncered", "spawncerd", "spawncered"] function isSponsored(elem) { if (!elem) return false; const sponsored = elem.querySelector('*[data-cfp-eligible]'); return Boolean(sponsored); } function isSponsoredImg(img) { if (!img) return false; const attrs = Array.from(img.attributes); const isSponsored = attrs.find(({ value }) => sponsoredTexts.find(txt => value.toLowerCase().includes(txt))); return Boolean(isSponsored); } function individualItems(jNode) { let li = jNode.closest('li') if (isSponsored(li)) { let parent = li.parentNode; if (parent.tagName === 'DIV') { parent.style.display = 'none' } else { li.style.display = 'none'; } } } function undesiredElement(jNode) { jNode.style.display = 'none' } function blockAdsInSearch() { // var lists = document.querySelectorAll('#store-wrapper .e-1yrpusx:not([style*="display:none"]):not([style*="display: none"]) > ul') let [head, ...tail] = [].filter.call(document.querySelectorAll('#store-wrapper .e-1yrpusx:not([style*="display:none"]):not([style*="display: none"]) > ul'), function (elem) { return elem.querySelector('div[aria-label="Product"]') }); // lists.filter(list => list.querySelector('div[aria-label="Product"]') !== null) if (head) { let mainList = head let otherLists = tail.map(node => node.querySelectorAll('li')) otherLists.forEach(itemList => itemList.forEach(item => mainList.append(item))) tail.forEach(node => node.style.display = "none") mainList.childNodes.forEach(item => { if (isSponsored(item)) { item.style.display = 'none'; } }) } } function blockAdsInCart(jNode) { let div = jNode if (div.innerHTML.indexOf('Suggested items') !== -1) { div.style.display = 'none' } } function defaultTip(jNode) { const spans = jNode.querySelectorAll('span'); const otherSpan = [...spans].filter(span => span.innerHTML === 'Other')[0] if (otherSpan) { let otherBtn = otherSpan.closest('button') otherBtn.click() const tipDiv = document.querySelector('div[aria-label="Say thanks with a tip"]') tipDiv.querySelector('#radio-base-option-4').click() const otherInput = tipDiv.querySelector('input[placeholder="Other amount"]') otherInput.focus(); waitForKeyElements('div[aria-label="Say thanks with a tip"] button:has(span)', function (jNode) { const btn = jNode if (btn.innerText.includes('Continue')) { btn.click() } }, false) } } function sponsoredCarousel(jNode) { let elem = jNode function traverseAncestors(node) { if (node) { if (node.tagName === 'DIV') { // let spans = node.querySelectorAll('span') // let sponsoredSpans = [...spans].filter(span => span.innerHTML == ' nsored') let imgs = node.querySelectorAll('img') let sponsoredImgs = [...imgs].filter(img => isSponsoredImg(img)) let individualSponsored = isSponsored(node) let scrollbars = node.querySelectorAll('.u-noscrollbar') if ((sponsoredImgs.length > 0) && (!individualSponsored) && (scrollbars.length === 1)) { console.log(node) node.style.display = 'none'; } else if (scrollbars.length > 1) { return; } else { traverseAncestors(node.parentNode); } } else traverseAncestors(node.parentNode) } } if (!window.location.href.endsWith('homeTabForYou')) { traverseAncestors(elem.parentNode) } } function sponsoredPlacement(jNode) { let node = jNode let imgs = node.querySelectorAll('img') let sponsoredImgs = [...imgs].filter(img => isSponsoredImg(img)) if ((sponsoredImgs.length > 0)) { node.style.display = 'none'; } } function continueToNext(jNode) { let span = jNode if (span.innerText === 'Continue to checkout') { setTimeout(function () { span.closest('button').click(); }, 500); } } waitForKeyElements('#store-wrapper div[aria-label="Product"]', blockAdsInSearch, false); waitForKeyElements('#store ul li div[aria-label="Product"] > div', individualItems, false); waitForKeyElements('#store-wrapper div[data-testid="regimen-section"]', undesiredElement, false); waitForKeyElements('#cart-body > div', blockAdsInCart, false); waitForKeyElements('#store-wrapper div[aria-label="Treatment Tracker modal"]', undesiredElement, false) // offer banner at bottom waitForKeyElements('#store div[aria-label="announcement"]', undesiredElement, false) waitForKeyElements('#store-wrapper div[aria-label="Tip Options"]', defaultTip, false) waitForKeyElements('#store-wrapper .u-noscrollbar', sponsoredCarousel, false) waitForKeyElements('footer span', continueToNext, false) waitForKeyElements('#storefront-placements-content article', sponsoredPlacement, false) waitForKeyElements('#store-wrapper article', sponsoredPlacement, false) waitForKeyElements('#store-wrapper div[role="region"] > section', sponsoredPlacement, false) waitForKeyElements('div[data-testid="recommendations-placements-feed"]', undesiredElement, false) // ---- Dynamically inserted promo blocks (merged from instacart-ad-remover.js) ---- function removeAdBlocks() { // Target elements inside unified data placement containers const targetBlocks = document.querySelectorAll('div[data-placements="unified"] > div'); targetBlocks.forEach(block => { // Check if the block contains a brand promo link or section if (block.querySelector('a[href*="/brands/"]') || block.querySelector('section')) { block.remove(); } }); } // Run initially removeAdBlocks(); // Observe page updates to catch dynamically loaded ads (debounced via rAF) let rafScheduled = false; function scheduleRemoveAdBlocks() { if (rafScheduled) return; rafScheduled = true; requestAnimationFrame(() => { rafScheduled = false; removeAdBlocks(); }); } function startAdBlockObserver() { new MutationObserver(scheduleRemoveAdBlocks).observe(document.body, { childList: true, subtree: true }); } if (document.body) { startAdBlockObserver(); } else { document.addEventListener('DOMContentLoaded', startAdBlockObserver, { once: true }); } })();