Auto-deploy: 2026-08-05 18:11:15

This commit is contained in:
Hamza-Ayed
2026-08-05 18:11:15 +03:00
parent ede306651f
commit 1fe694a23b
2 changed files with 44 additions and 42 deletions
+43 -41
View File
@@ -48,25 +48,6 @@
return ''; return '';
} }
// ── Job Title (many fallbacks)
data.jobTitle = trySelectors([
'.job-details-jobs-unified-top-card__job-title h1 a',
'.job-details-jobs-unified-top-card__job-title h1',
'.jobs-unified-top-card__job-title h1',
'.jobs-unified-top-card__job-title',
'.job-details-jobs-unified-top-card__job-title',
'h2.job-details-jobs-unified-top-card__job-title',
'.jobs-unified-top-card__job-title a',
'h1.t-24',
'h1.t-18',
'h1[class*="job-title"]',
'h2[class*="job-title"]',
'.t-24.t-bold',
'.top-card-layout__title',
'a[class*="topcard__title"]',
'.topcard__title',
]);
// LinkedIn's job panel is full of text that is neither navigation nor the // LinkedIn's job panel is full of text that is neither navigation nor the
// job title: screen-reader-only headings ("0 notifications"), and product // job title: screen-reader-only headings ("0 notifications"), and product
// furniture inside the detail column itself ("Are these results helpful?", // furniture inside the detail column itself ("Are these results helpful?",
@@ -98,33 +79,54 @@
return text.length > 4 && text.length < 100 && !NAV_NOISE.test(text); return text.length > 4 && text.length < 100 && !NAV_NOISE.test(text);
} }
// Preferred fallback 1: Extract from active job link using currentJobId // 1. Most Reliable Method: Extract from active job link using currentJobId
if (!data.jobTitle) { let currentJobId = new URLSearchParams(window.location.search).get('currentJobId');
let currentJobId = new URLSearchParams(window.location.search).get('currentJobId'); if (!currentJobId) {
if (!currentJobId) { const match = window.location.pathname.match(/\/jobs\/view\/(\d+)/);
const match = window.location.pathname.match(/\/jobs\/view\/(\d+)/); if (match) currentJobId = match[1];
if (match) currentJobId = match[1]; }
}
if (currentJobId) { if (currentJobId) {
const links = document.querySelectorAll(`a[href*="/jobs/view/${currentJobId}"]`); // Find all links containing this job ID
for (const link of links) { const links = document.querySelectorAll(`a[href*="/jobs/view/${currentJobId}"]`);
const text = link.innerText.trim(); for (const link of links) {
// Filter out empty or obviously wrong texts const text = (link.textContent || '').trim();
if (plausibleTitle(text) && !text.includes('Easy Apply') && !text.includes('Save')) { // Filter out empty or obviously wrong texts (like "Save", "Easy Apply")
data.jobTitle = text; if (text && plausibleTitle(text) && !text.includes('Easy Apply') && !text.includes('Save')) {
break; data.jobTitle = text;
} break;
} }
} }
} }
// Preferred fallback 2: the browser tab title. LinkedIn sets it to // 2. Fallback: Try known selectors
// "(N) Job Title | Company | LinkedIn" on every job page, it is not part of if (!data.jobTitle) {
// the React DOM that keeps getting restructured, and it cannot pick up a data.jobTitle = trySelectors([
// stray card heading. This is far more reliable than guessing at headings, '.job-details-jobs-unified-top-card__job-title h1 a',
// so it runs before the DOM scan, not after it. '.job-details-jobs-unified-top-card__job-title h1',
'.jobs-unified-top-card__job-title h1',
'.jobs-unified-top-card__job-title',
'.job-details-jobs-unified-top-card__job-title',
'h2.job-details-jobs-unified-top-card__job-title',
'.jobs-unified-top-card__job-title a',
'h1.t-24',
'h1.t-18',
'h1[class*="job-title"]',
'h2[class*="job-title"]',
'.t-24.t-bold',
'.top-card-layout__title',
'a[class*="topcard__title"]',
'.topcard__title',
]);
// If we grabbed garbage, reset it
if (data.jobTitle && !plausibleTitle(data.jobTitle)) {
data.jobTitle = '';
}
}
// 3. Last Resort Fallback: Browser tab title
if (!data.jobTitle) { if (!data.jobTitle) {
// The "(N)" prefix is LinkedIn's unread counter and can read "(99+)".
const m = document.title.match(/^(?:\(\d+\+?\)\s*)?(.+?)\s*[|·]/); const m = document.title.match(/^(?:\(\d+\+?\)\s*)?(.+?)\s*[|·]/);
if (m) { if (m) {
const candidate = m[1].trim(); const candidate = m[1].trim();
+1 -1
View File
File diff suppressed because one or more lines are too long