Auto-deploy: 2026-06-05 22:42:18
This commit is contained in:
@@ -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 {
|
||||
// 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();
|
||||
|
||||
Reference in New Issue
Block a user