Auto-deploy: 2026-08-05 16:35:29
This commit is contained in:
+36
-13
@@ -66,25 +66,48 @@
|
|||||||
'.topcard__title',
|
'.topcard__title',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Fallback: find any h1 in the job details area
|
// LinkedIn renders screen-reader-only headings throughout its chrome
|
||||||
|
// ("0 notifications", "1 new message"). They are real <h2> elements with
|
||||||
|
// real text, so any document-wide heading scan will happily return one as
|
||||||
|
// the job title. Require the element to be visibly rendered and to not look
|
||||||
|
// like navigation furniture.
|
||||||
|
function isVisible(el) {
|
||||||
|
if (!el || !el.offsetParent) return false;
|
||||||
|
if (el.closest('[aria-hidden="true"]')) return false;
|
||||||
|
const cls = el.className && el.className.baseVal !== undefined
|
||||||
|
? el.className.baseVal
|
||||||
|
: String(el.className || '');
|
||||||
|
return !/visually-hidden|sr-only|a11y-text/.test(cls);
|
||||||
|
}
|
||||||
|
|
||||||
|
const NAV_NOISE = /notification|message|invitation|my network|feed update|search|premium|^\d+\s|jobs|people|similar|featured|recommended/i;
|
||||||
|
|
||||||
|
function plausibleTitle(text) {
|
||||||
|
return text.length > 4 && text.length < 100 && !NAV_NOISE.test(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: a heading inside the job detail panel only — never page-wide.
|
||||||
if (!data.jobTitle) {
|
if (!data.jobTitle) {
|
||||||
const jobPanel = document.querySelector('.scaffold-layout__detail-column, .jobs-search__job-details, .job-view-layout');
|
const jobPanel = document.querySelector(
|
||||||
|
'.scaffold-layout__detail-column, .jobs-search__job-details, .job-view-layout, ' +
|
||||||
|
'.jobs-details, [class*="jobs-unified-top-card"], main'
|
||||||
|
);
|
||||||
if (jobPanel) {
|
if (jobPanel) {
|
||||||
const h1 = jobPanel.querySelector('h1');
|
for (const h of jobPanel.querySelectorAll('h1, h2')) {
|
||||||
if (h1 && h1.textContent.trim()) data.jobTitle = h1.textContent.trim();
|
const text = h.textContent.trim();
|
||||||
|
if (isVisible(h) && plausibleTitle(text)) {
|
||||||
|
data.jobTitle = text;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last resort: any bold h2 in main area
|
// Last resort: the browser tab title, which LinkedIn formats as
|
||||||
|
// "(N) Job Title | Company | LinkedIn". Still better than a nav label.
|
||||||
if (!data.jobTitle) {
|
if (!data.jobTitle) {
|
||||||
const allH2 = document.querySelectorAll('h2');
|
const m = document.title.match(/^(?:\(\d+\)\s*)?(.+?)\s*\|/);
|
||||||
for (const h of allH2) {
|
if (m && plausibleTitle(m[1].trim())) data.jobTitle = m[1].trim();
|
||||||
const text = h.textContent.trim();
|
|
||||||
if (text.length > 4 && text.length < 100 && !text.match(/jobs|people|similar|featured/i)) {
|
|
||||||
data.jobTitle = text;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Company Name
|
// ── Company Name
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user