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
+32 -30
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) {
// Find all links containing this job ID
const links = document.querySelectorAll(`a[href*="/jobs/view/${currentJobId}"]`); const links = document.querySelectorAll(`a[href*="/jobs/view/${currentJobId}"]`);
for (const link of links) { for (const link of links) {
const text = link.innerText.trim(); const text = (link.textContent || '').trim();
// Filter out empty or obviously wrong texts // Filter out empty or obviously wrong texts (like "Save", "Easy Apply")
if (plausibleTitle(text) && !text.includes('Easy Apply') && !text.includes('Save')) { if (text && plausibleTitle(text) && !text.includes('Easy Apply') && !text.includes('Save')) {
data.jobTitle = text; data.jobTitle = text;
break; break;
} }
} }
} }
// 2. Fallback: Try known selectors
if (!data.jobTitle) {
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',
]);
// If we grabbed garbage, reset it
if (data.jobTitle && !plausibleTitle(data.jobTitle)) {
data.jobTitle = '';
}
} }
// Preferred fallback 2: the browser tab title. LinkedIn sets it to // 3. Last Resort Fallback: Browser tab title
// "(N) Job Title | Company | LinkedIn" on every job page, it is not part of
// the React DOM that keeps getting restructured, and it cannot pick up a
// stray card heading. This is far more reliable than guessing at headings,
// so it runs before the DOM scan, not after it.
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