Last active
June 29, 2023 22:20
-
-
Save frizz925/a21211d0a257ec86173a9308b8391986 to your computer and use it in GitHub Desktop.
Userscript to remove TopAds from Tokopedia's search results
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==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