Skip to content

Instantly share code, notes, and snippets.

@frizz925
Last active June 29, 2023 22:20
Show Gist options
  • Save frizz925/a21211d0a257ec86173a9308b8391986 to your computer and use it in GitHub Desktop.
Save frizz925/a21211d0a257ec86173a9308b8391986 to your computer and use it in GitHub Desktop.
Userscript to remove TopAds from Tokopedia's search results
// ==UserScript==
// @name Tokopedia Remove TopAds
// @namespace http://tampermonkey.net/
// @version 0.2
// @description Remove those annoying TopAds from your search results!
// @author Izra Faturrahman <[email protected]>
// @match https://www.tokopedia.com/*
// @grant none
// @run-at document-start
// ==/UserScript==
'use strict';
(() => {
const forEach = (it, callback) => {
for (const key in it) {
if (!Object.prototype.hasOwnProperty.call(it, key)) {
continue;
}
if (callback(it[key], key) === false) {
break;
}
}
};
const cleanCache = (cache) => {
forEach(cache, (value, key) => {
if (!key.startsWith('$ROOT_QUERY.displayAds')) return;
value.data = [];
});
return cache;
};
let windowCache;
Object.defineProperty(window, '__cache', {
get: () => windowCache,
set: (cache) => {
windowCache = cleanCache(cache);
},
});
const filterProductResult = (result) => {
forEach(result.data, (res) => {
const data = res.data;
const products = data.products;
data.products = products.filter((product) => !product.ads.id);
});
return result;
};
const filterTopadsResult = (result) => {
forEach(result.data, (res) => {
res.data = [];
});
return result;
};
const filterFetchResponse = (response, filterMap) =>
response.json().then((result) => {
forEach(result, (res, idx) => {
const filter = filterMap[idx];
if (!filter) return;
result[idx] = filter(res);
});
return new Response(JSON.stringify(result), {
headers: response.headers,
status: response.status,
statusText: response.statusText,
});
});
const originalFetch = window.fetch;
const fetchInterceptor = (url, req) => {
if (url.indexOf('gql.tokopedia.com') < 0) {
return false;
}
const body = JSON.parse(req.body);
const filterMap = {};
forEach(body, (req, idx) => {
if (req.operationName.startsWith('Topads')) {
filterMap[idx] = filterTopadsResult;
} else if (req.operationName.startsWith('SearchProduct')) {
filterMap[idx] = filterProductResult;
}
});
return originalFetch(url, req).then((response) =>
filterFetchResponse(response, filterMap)
);
};
window.fetch = (url, req) => {
const res = fetchInterceptor(url, req);
return res === false ? originalFetch(url, req) : res;
};
const cleanupElements = () => {
const els = document.querySelectorAll('[data-testid="divProductWrapper"]');
forEach(els, (el) => {
const a = el.querySelector('a');
if (!a) return;
const href = a.getAttribute('href');
if (href.indexOf('ta.tokopedia.com') < 0) return;
const container = el.parentElement.parentElement;
container.parentElement.removeChild(container);
});
const cpm = document.querySelector('[data-testid="topadsCPMWrapper"]');
if (cpm) {
cpm.parentElement.removeChild(cpm);
}
};
window.addEventListener('DOMContentLoaded', cleanupElements);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment