// ==UserScript==
// @name יד2 - סינון סוכנויות, הוספת מפות ושליפת נתונים
// @namespace http://tampermonkey.net/
// @version 2.9
// @description מערכת סינון חכמה, שליפת נתונים עם מטמון מתקדם, חיווי טעינה וקישור למפות
// @author HAKOL-MILEMALA
// @match *://www.yad2.co.il/vehicles/*
// @match *://www.yad2.co.il/my-favorites*
// @updateURL https://raw.githubusercontent.com/HAKOL-MILEMALA/Detailed-Yad2-results/main/Detailed-Yad2-results.user.js
// @downloadURL https://raw.githubusercontent.com/HAKOL-MILEMALA/Detailed-Yad2-results/main/Detailed-Yad2-results.user.js
// @grant none
// ==/UserScript==
(function() {
'use strict';
console.log('[יד2 סקריפט] --- התחלת ריצת סקריפט: גרסה 2.8 ---');
let isFilterActive = localStorage.getItem('hideYad2Agencies') === 'true';
const carDataCache = new Map();
// ==========================================
// חלק 1: מנגנון סינון סוכנויות
// ==========================================
function toggleAgencies() {
if (window.location.href.includes('my-favorites')) return;
const allItems = document.querySelectorAll('a[data-listing-type]');
let hiddenCount = 0;
allItems.forEach(item => {
const listingType = item.getAttribute('data-listing-type') || '';
const isAgency = listingType.includes('agency') || item.querySelector('[class*="agencyName"]');
if (isAgency) {
item.style.display = isFilterActive ? 'none' : '';
if (isFilterActive) hiddenCount++;
}
});
if (isFilterActive && hiddenCount > 0) {
console.log(`[יד2 סקריפט] הוסתרו ${hiddenCount} רכבי סוכנויות.`);
}
}
function createCheckbox(container) {
if (document.getElementById('hide-agency-checkbox') || window.location.href.includes('my-favorites')) return;
const wrapper = document.createElement('div');
wrapper.style.cssText = 'display: flex; align-items: center; margin-right: auto; margin-left: 20px; padding: 5px 10px; background-color: #f5f5f5; border-radius: 5px; border: 1px solid #ccc;';
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = 'hide-agency-checkbox';
checkbox.style.cssText = 'cursor: pointer; margin-left: 8px; width: 16px; height: 16px;';
checkbox.checked = isFilterActive;
checkbox.addEventListener('change', (e) => {
isFilterActive = e.target.checked;
localStorage.setItem('hideYad2Agencies', isFilterActive);
console.log(`[יד2 סקריפט] סינון סוכנויות: ${isFilterActive ? 'פועל' : 'כבוי'}`);
toggleAgencies();
});
const label = document.createElement('label');
label.htmlFor = 'hide-agency-checkbox';
label.innerText = 'הסתר רכבי סוכנויות';
label.style.cssText = 'cursor: pointer; font-size: 14px; font-weight: bold; color: #333; margin: 0;';
wrapper.appendChild(checkbox);
wrapper.appendChild(label);
container.insertBefore(wrapper, container.childNodes[1] || container.firstChild);
console.log('[יד2 סקריפט] כפתור סינון סוכנויות נוסף בהצלחה.');
}
// ==========================================
// חלק 2: מנגנון שליפת נתונים
// ==========================================
function createDisplayElement(kmValue, locValue, descValue) {
const displayDiv = document.createElement('div');
displayDiv.className = 'yad2-extra-data-injected';
// הוסר חיתוך הטקסט - הכרטיסייה תתרחב כלפי מטה בהתאם לאורך הטקסט
displayDiv.style.cssText = 'margin-top: 8px; padding-top: 8px; border-top: 1px dashed #ccc; font-size: 14px; line-height: 1.5; color: #444; width: 100%; flex-basis: 100%; position: relative; z-index: 99;';
let locationHtml = `${locValue}`;
if (locValue !== 'לא צוין' && locValue.trim() !== '') {
const mapsUrl = `https://www.google.co.il/maps/dir//${encodeURIComponent(locValue.trim())}?hl=iw`;
locationHtml = `${locValue} 🗺️`;
}
displayDiv.innerHTML = `
ק"מ: ${kmValue}
מיקום: ${locationHtml}
פרטים: ${descValue}
`;
const mapLink = displayDiv.querySelector('.yad2-map-link');
if (mapLink) {
mapLink.addEventListener('click', (e) => {
e.stopPropagation();
});
}
return displayDiv;
}
async function processCarCard(card, url) {
const isFavoritesPage = window.location.href.includes('my-favorites');
// בעמוד המועדפים אנחנו בודקים את האבא של הכרטיסיה (כמו בעיצוב הישן) כדי לא לדרוס את המבנה
const containerToCheck = isFavoritesPage ? (card.closest('article') || card.parentNode) : card;
if (containerToCheck.querySelector('.yad2-extra-data-injected') || containerToCheck.querySelector('.yad2-loading-data')) return;
const cleanUrl = url.split('?')[0];
const loadingDiv = document.createElement('div');
loadingDiv.className = 'yad2-loading-data';
loadingDiv.style.cssText = 'margin-top: 8px; font-size: 13px; color: #888; font-style: italic; width: 100%; flex-basis: 100%;';
loadingDiv.innerHTML = '⏳ שולף נתונים...';
// פיצול ההזרקה: לוגיקה נפרדת למועדפים ולדף הראשי
if (isFavoritesPage) {
const favoritesTitlesSection = containerToCheck.querySelector('[class*="titlesSection"]');
if (favoritesTitlesSection) {
favoritesTitlesSection.appendChild(loadingDiv);
} else {
containerToCheck.appendChild(loadingDiv);
}
} else {
const mainPageInfoBox = card.querySelector('[data-testid="feed-item-info"]');
if (mainPageInfoBox) {
mainPageInfoBox.style.display = 'flex';
mainPageInfoBox.style.flexWrap = 'wrap';
mainPageInfoBox.appendChild(loadingDiv);
} else {
card.appendChild(loadingDiv);
}
}
if (!carDataCache.has(cleanUrl)) {
const fetchPromise = fetch(cleanUrl)
.then(async (response) => {
if (!response.ok) throw new Error(`Network response was not ok (${response.status})`);
const html = await response.text();
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
let kmValue = 'לא צוין', locValue = 'לא צוין', descValue = 'אין פרטים נוספים';
const kmCard = doc.querySelector('[data-testid="we-checked-km-card"]');
if (kmCard) {
const valElement = kmCard.querySelector('[data-testid="detail-card-value"]');
if (valElement) kmValue = valElement.textContent.trim();
}
const locElement = doc.querySelector('[data-testid="location"]');
if (locElement) locValue = locElement.textContent.trim();
const descElement = doc.querySelector('[data-testid="vehicle-description"]');
if (descElement) descValue = descElement.textContent.trim();
await new Promise(resolve => setTimeout(resolve, 500 + Math.random() * 1000));
return { kmValue, locValue, descValue };
})
.catch(error => {
console.error(`[יד2 סקריפט] שגיאה במשיכת נתונים עבור ${cleanUrl}:`, error);
return null;
});
carDataCache.set(cleanUrl, fetchPromise);
}
const data = await carDataCache.get(cleanUrl);
if (loadingDiv.parentNode) {
if (data) {
const displayDiv = createDisplayElement(data.kmValue, data.locValue, data.descValue);
loadingDiv.replaceWith(displayDiv);
} else {
loadingDiv.innerHTML = '❌ שגיאה בשליפת הנתונים';
loadingDiv.style.color = '#c00';
setTimeout(() => { if(loadingDiv.parentNode) loadingDiv.remove(); }, 3000);
}
}
}
function scanForCars() {
const itemCards = document.querySelectorAll('a[href*="item/"]');
let processedCount = 0;
const isFavoritesPage = window.location.href.includes('my-favorites');
for (let card of itemCards) {
const url = card.href;
if (url.includes('/item/')) {
const containerToCheck = isFavoritesPage ? (card.closest('article') || card.parentNode) : card;
if (!containerToCheck.querySelector('.yad2-extra-data-injected') && !containerToCheck.querySelector('.yad2-loading-data')) {
processCarCard(card, url);
processedCount++;
}
}
}
if (processedCount > 0) {
console.log(`[יד2 סקריפט] זוהו ${processedCount} רכבים חדשים, מתחיל בשליפה.`);
}
if (isFilterActive) {
toggleAgencies();
}
}
// ==========================================
// חלק 3: הפעלת הכלים והאזנה לשינויים
// ==========================================
let scanTimeout = null;
const observer = new MutationObserver((mutations) => {
const sortContainer = document.querySelector('[class*="sortAndTotalBox"]');
if (sortContainer && !document.getElementById('hide-agency-checkbox')) {
createCheckbox(sortContainer);
}
let shouldScan = false;
for (let mutation of mutations) {
if (mutation.addedNodes.length > 0) {
shouldScan = true;
break;
}
}
if (shouldScan) {
if (scanTimeout) clearTimeout(scanTimeout);
scanTimeout = setTimeout(() => {
scanForCars();
}, 300);
}
});
console.log('[יד2 סקריפט] מפעיל מאזין לשינויים בעמוד...');
observer.observe(document.body, { childList: true, subtree: true });
setTimeout(scanForCars, 1500);
})();