Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name chotot.com Advanced Search
- // @namespace https://greasyfork.org/en/users/85671-jcunews
- // @version 1.2.3
- // @license MIT
- // @author jcunews
- // @description Based on https://openuserjs.org/scripts/icetbr/Shopee_Advanced_Search
- // @match https://www.chotot.com/*
- // @grant none
- // ==/UserScript==
- const
- $ = (selector, parent = document) => parent.querySelector(selector),
- $$ = (selector, parent = document) => Array.from(parent.querySelectorAll(selector)),
- el = (name, attrs) => Object.assign(document.createElement(name), attrs),
- toBase64 = svg => `data:image/svg+xml;base64,${window.btoa(svg)}`,
- toSearcheable = string => string
- .trim()
- .toLowerCase()
- .normalize('NFD')
- .replace(/\p{Diacritic}/gu, ''),
- isBrazil = () => window.location.hostname.endsWith('.br');
- const split = value => value ? value.split(' ') : [];
- const filterIconSvg = `
- <svg width="26px" height="26px" viewBox="0 0 21 21" xmlns="http://www.w3.org/2000/svg">
- <g stroke="currentColor">
- <path d="m4.5 7.5h12"/>
- <path d="m6.5 10.5h8"/>
- <path d="m8.5 13.5h4"/>
- </g>
- </svg>`;
- let prevUrl;
- const filter = ($searchedWordsInput, $excludedWordsInput) => () => {
- const $products = $$('div[class*="OrderFilter_orderFilter__"]+.list-view div[class*="ListAds_ListAds__"]>ul>div[role="button"],div[class*="OrderFilter_orderFilter__"]+.list-view div[class*="AdItem_item__"]');
- if (prevUrl && (location.href !== prevUrl)) {
- const match = location.href.match(/\/mua-ban\?q=([^&]+)/);
- if (match && localStorage.searchedWords && ($searchedWordsInput.value !== localStorage.searchedWords)) {
- setTimeout(() => $searchedWordsInput.value = localStorage.searchedWords, 0);
- }
- }
- prevUrl = location.href;
- const searchedWords = split(toSearcheable($searchedWordsInput.value));
- const excludedWords = split(toSearcheable($excludedWordsInput.value));
- localStorage.excludedWords = $excludedWordsInput.value;
- const lacksAllSearchedWords = element => !searchedWords.every(w => element.dataset.searcheableText.includes(w));
- const hasAnyExcludedWords = element => excludedWords.some(w => element.dataset.searcheableText.includes(w));
- const withSearcheableText = el => {
- el.dataset.searcheableText = toSearcheable(el.querySelector('h3[class*="commonStyle_adTitle__"],div[class*="commonStyle_adTitleGrid__"]')?.textContent ?? '');
- return el;
- };
- const toggleHidden = (count, el) => {
- if (lacksAllSearchedWords(el) || hasAnyExcludedWords(el)) {
- el.style.display = 'none';
- count++;
- } else {
- el.style.display = 'block';
- }
- return count;
- };
- const $loadedProducts = $products
- .map(withSearcheableText)
- .filter(p => p.dataset.searcheableText);
- const hiddenCount = $loadedProducts.reduce(toggleHidden, 0);
- const excludedMsg = excludedWords.length ? ` -'${excludedWords.join(' ')}'` : '';
- console.log(`${$products.length} products, ${$loadedProducts.length} loaded, ${hiddenCount} hidden for '${searchedWords.join(' ')}'${excludedMsg}`);
- document.querySelectorAll('div[class*="Paging_pagingItem__"]>a').forEach(a => {
- a.href = a.href.replace(/\bq=[^&]+/, 'q=' + encodeURIComponent($searchedWordsInput.value.trim()))
- });
- };
- let filterProducts;
- const enable = () => {
- const $searchBar = window?.__inputItemProps?.parentNode;
- if (!$searchBar || $searchBar.querySelector('#excludedWords')) return;
- console.log('chotot filter enabled');
- const $searchedWordsInput = __inputItemProps;
- $searchedWordsInput.addEventListener("input", () => {
- localStorage.searchedWords = $searchedWordsInput.value;
- });
- localStorage.searchedWords = $searchedWordsInput.value;
- const $excludedWordsInput = el('input', {
- id: 'excludedWords',
- placeholder: isBrazil() ? 'excluir palavras' : 'exclude words',
- value: localStorage.excludedWords || "",
- onkeyup: function(e) { if (e.key === 'Enter') filterProducts(); }
- });
- filterProducts = filter($searchedWordsInput, $excludedWordsInput);
- const $filterButton = el('button', {
- type: 'button',
- onclick: filterProducts,
- style: `
- background: no-repeat url(${toBase64(filterIconSvg)});
- padding: 13px;
- margin-top: 3px;
- margin-right: 4em;
- border: none;
- `,
- });
- $searchBar.appendChild($excludedWordsInput);
- $excludedWordsInput.parentNode.firstElementChild.style.width = "auto";
- $excludedWordsInput.previousElementSibling.style.paddingRight = ".5em";
- $searchBar.appendChild($filterButton);
- };
- const observer = new MutationObserver(() => {
- enable();
- filterProducts && filterProducts();
- });
- observer.observe(document.body, { childList: true, subtree: true });
Add Comment
Please, Sign In to add comment