diff --git a/search_analyzer.js b/search_analyzer.js index ff1946e..b292827 100644 --- a/search_analyzer.js +++ b/search_analyzer.js @@ -78,6 +78,58 @@ return data; } + // ─── Find Cards Logic ────────────────────────────────────────────────────── + function findCards() { + let cards = []; + + // Method 1: Try common structural wrappers for search results + let listItems = Array.from(document.querySelectorAll('ul > li')); + let validListItems = listItems.filter(li => li.innerText.length > 20 && li.querySelector('img')); + if (validListItems.length > 0) { + cards = validListItems; + console.log('[LJA] Found cards via ul > li with images:', cards.length); + } + + // Method 2: Try finding elements containing headlines + if (cards.length === 0) { + let subtitles = document.querySelectorAll('.entity-result__primary-subtitle, [class*="subtitle"], .linked-area'); + let validSubtitles = Array.from(subtitles).filter(s => s.innerText.trim().length > 5); + if (validSubtitles.length > 0) { + let uniqueCards = new Set(); + validSubtitles.forEach(s => { + let container = s.closest('li') || s.closest('div[data-chameleon-result-urn]') || s.parentElement.parentElement.parentElement; + if (container) uniqueCards.add(container); + }); + cards = Array.from(uniqueCards); + console.log('[LJA] Found cards via subtitles:', cards.length); + } + } + + // Method 3: Deep heuristic using profile links + if (cards.length === 0) { + let profileLinks = Array.from(document.querySelectorAll('a[href*="/in/"]')).filter(a => a.innerText.trim().length > 3 && !a.querySelector('img')); + console.log('[LJA] Profile links found:', profileLinks.length); + + let uniqueCards = new Set(); + profileLinks.forEach(link => { + let container = link.parentElement; + let bestContainer = null; + for(let i = 0; i < 8; i++) { + if (!container) break; + if (container.innerText.length > 50 && container.querySelectorAll('button').length > 0) { + bestContainer = container; + } + container = container.parentElement; + } + if (bestContainer) uniqueCards.add(bestContainer); + }); + cards = Array.from(uniqueCards); + console.log('[LJA] Found cards via link heuristics:', cards.length); + } + + return Array.from(new Set(cards)); + } + // ─── Inject UI into Card ───────────────────────────────────────────────── function injectScanButton(cardEl) { if (cardEl.querySelector('.lja-scan-person-btn') || cardEl.querySelector('.lja-investor-result')) return; @@ -86,7 +138,6 @@ btn.className = 'lja-scan-person-btn'; btn.innerHTML = '🔍 Scan Investor'; - // Add some basic styling just in case CSS fails to load or apply correctly btn.style.margin = '10px 0'; btn.style.padding = '5px 15px'; btn.style.cursor = 'pointer'; @@ -95,10 +146,13 @@ btn.style.border = 'none'; btn.style.borderRadius = '5px'; btn.style.fontWeight = 'bold'; + btn.style.zIndex = '999'; + btn.style.position = 'relative'; - // Create a container for the result const resultContainer = document.createElement('div'); resultContainer.className = 'lja-result-wrapper'; + resultContainer.style.width = '100%'; + resultContainer.style.marginTop = '10px'; btn.addEventListener('click', async (e) => { e.stopPropagation(); @@ -106,15 +160,23 @@ await scanPerson(cardEl, btn, resultContainer); }); - // Try to append to actions area, if not just append at the end of the card + // Try to append to actions area const actionArea = cardEl.querySelector('.entity-result__actions, .search-result__actions'); if (actionArea) { actionArea.prepend(btn); + actionArea.appendChild(resultContainer); } else { - cardEl.appendChild(btn); + // Fallback: Find the name link and put it under it + const profileLink = Array.from(cardEl.querySelectorAll('a[href*="/in/"]')).find(a => a.innerText.trim().length > 0); + if (profileLink && profileLink.parentElement) { + profileLink.parentElement.appendChild(btn); + profileLink.parentElement.appendChild(resultContainer); + } else { + cardEl.appendChild(btn); + cardEl.appendChild(resultContainer); + } } - cardEl.appendChild(resultContainer); console.log('[LJA] Injected button for a profile:', extractPersonData(cardEl).name); } @@ -216,7 +278,6 @@ btn.innerHTML = '✨ Scan All Investors'; btn.title = 'Scan all loaded profiles on this page'; - // Robust styling for the Scan All button btn.style.margin = '20px auto'; btn.style.display = 'block'; btn.style.padding = '10px 20px'; @@ -230,9 +291,7 @@ btn.style.boxShadow = '0 4px 6px rgba(0,0,0,0.1)'; btn.addEventListener('click', async () => { - // Find all cards using our robust selector - const allLis = Array.from(document.querySelectorAll('li')); - const cards = allLis.filter(li => li.querySelector('a[href*="/in/"]')); + const cards = findCards(); if (cards.length === 0) { alert('No profiles found to scan.'); @@ -279,57 +338,8 @@ if (!window.location.href.includes('linkedin.com/search/results/')) return; console.log('[LJA] Attempting to find profile cards...'); - let cards = []; - - // Method 1: Try common structural wrappers for search results - let listItems = Array.from(document.querySelectorAll('ul > li')); - let validListItems = listItems.filter(li => li.innerText.length > 20 && li.querySelector('img')); - if (validListItems.length > 0) { - cards = validListItems; - console.log('[LJA] Found cards via ul > li with images:', cards.length); - } - - // Method 2: Try finding elements containing headlines - if (cards.length === 0) { - let subtitles = document.querySelectorAll('.entity-result__primary-subtitle, [class*="subtitle"], .linked-area'); - let validSubtitles = Array.from(subtitles).filter(s => s.innerText.trim().length > 5); - if (validSubtitles.length > 0) { - let uniqueCards = new Set(); - validSubtitles.forEach(s => { - let container = s.closest('li') || s.closest('div[data-chameleon-result-urn]') || s.parentElement.parentElement.parentElement; - if (container) uniqueCards.add(container); - }); - cards = Array.from(uniqueCards); - console.log('[LJA] Found cards via subtitles:', cards.length); - } - } - - // Method 3: Deep heuristic using profile links - if (cards.length === 0) { - let profileLinks = Array.from(document.querySelectorAll('a[href*="/in/"]')).filter(a => a.innerText.trim().length > 3 && !a.querySelector('img')); - console.log('[LJA] Profile links found:', profileLinks.length); - - let uniqueCards = new Set(); - profileLinks.forEach(link => { - let container = link.parentElement; - let bestContainer = null; - // Go up to 8 levels looking for a substantial block - for(let i = 0; i < 8; i++) { - if (!container) break; - // A good card container has significant text and usually buttons - if (container.innerText.length > 50 && container.querySelectorAll('button').length > 0) { - bestContainer = container; - } - container = container.parentElement; - } - if (bestContainer) uniqueCards.add(bestContainer); - }); - cards = Array.from(uniqueCards); - console.log('[LJA] Found cards via link heuristics:', cards.length); - } - - // Deduplicate cards just in case - cards = Array.from(new Set(cards)); + const cards = findCards(); + console.log('[LJA] processPage found cards:', cards.length); if (cards.length > 0) { injectScanAllButton();