Auto-deploy: 2026-05-17 02:26:43

This commit is contained in:
Hamza-Ayed
2026-05-17 02:26:43 +03:00
parent dfbb8b4023
commit c082b1861c

View File

@@ -228,28 +228,76 @@
function extractApplicationQuestions() { function extractApplicationQuestions() {
const questions = []; const questions = [];
const modal = document.querySelector('.artdeco-modal, .jobs-easy-apply-modal, #artdeco-modal-outlet');
if (!modal) return questions;
const labels = modal.querySelectorAll('label, legend');
const seen = new Set(); const seen = new Set();
labels.forEach(label => { // Strategy 1: Look inside known modal containers
let text = label.textContent.replace(/\*/g, '').replace(/Submit/i, '').trim(); const containers = document.querySelectorAll(
if (text && text.length > 5 && text.length < 200 && !seen.has(text)) { '.artdeco-modal, .jobs-easy-apply-modal, #artdeco-modal-outlet, ' +
seen.add(text); '.jobs-easy-apply-content, .jobs-easy-apply-form-section__grouping, ' +
'[data-test-modal], [role="dialog"]'
);
// Strategy 2: If no modal found, scan the full page
const searchRoots = containers.length > 0 ? containers : [document.body];
searchRoots.forEach(container => {
// Scan labels, legends, spans that look like question text
const candidates = container.querySelectorAll(
'label, legend, .fb-dash-form-element__label, ' +
'.jobs-easy-apply-form-element__label, ' +
'span.t-14, span.t-bold'
);
candidates.forEach(el => {
let text = el.textContent.replace(/\*/g, '').replace(/required/gi, '').trim();
// Remove "Select an option" and similar noise
text = text.replace(/Select an option/gi, '').replace(/Show less|Show more/gi, '').trim();
if (!text || text.length < 8 || text.length > 300 || seen.has(text.toLowerCase())) return;
// Only accept text that looks like a question or form label
const isQuestion = (
text.endsWith('?') ||
/^(how many|what|do you|are you|have you|will you|can you|would you|is your|describe|tell us)/i.test(text) ||
/salary|experience|education|degree|visa|relocat|notice period|start date|certif/i.test(text)
);
if (!isQuestion) return;
seen.add(text.toLowerCase());
// Detect input type from nearest form element
let inputType = 'text'; let inputType = 'text';
const parent = label.closest('div') || label.parentElement; const parent = el.closest('.fb-dash-form-element, .jobs-easy-apply-form-section__grouping, div') || el.parentElement;
if (parent.querySelector('select')) inputType = 'select'; if (parent) {
else if (parent.querySelector('input[type="radio"]')) inputType = 'radio'; if (parent.querySelector('select')) inputType = 'select';
else if (parent.querySelector('textarea')) inputType = 'textarea'; else if (parent.querySelector('input[type="radio"]')) inputType = 'radio';
else if (parent.querySelector('input[type="checkbox"]')) inputType = 'checkbox'; else if (parent.querySelector('textarea')) inputType = 'textarea';
else if (parent.querySelector('input[type="checkbox"]')) inputType = 'checkbox';
else if (parent.querySelector('input[type="number"]')) inputType = 'number';
}
questions.push({ question: text, type: inputType }); questions.push({ question: text, type: inputType });
} });
}); });
// Strategy 3: Last resort — scan ALL visible text for question patterns
if (questions.length === 0) {
const allSpans = document.querySelectorAll('span, label, legend, p');
allSpans.forEach(el => {
const text = el.textContent.replace(/\*/g, '').trim();
if (text && text.endsWith('?') && text.length > 10 && text.length < 200 && !seen.has(text.toLowerCase())) {
// Make sure this is a visible form question, not random page text
const rect = el.getBoundingClientRect();
if (rect.width > 0 && rect.height > 0 && rect.top > 0 && rect.top < window.innerHeight) {
seen.add(text.toLowerCase());
questions.push({ question: text, type: 'text' });
}
}
});
}
console.log('[LJA] Scraped questions:', questions);
return questions.slice(0, 15); return questions.slice(0, 15);
} }
@@ -586,7 +634,15 @@
const isArabic = /[\u0600-\u06FF]/.test(text); const isArabic = /[\u0600-\u06FF]/.test(text);
const rtlAttr = isArabic ? 'dir="rtl" style="text-align: right; padding-right: 15px;"' : ''; const rtlAttr = isArabic ? 'dir="rtl" style="text-align: right; padding-right: 15px;"' : '';
// For Q&A, show how many questions were detected
const qaHeader = (tab === 'qa' && jobData.questions)
? `<div style="background:rgba(108,99,255,0.2);padding:6px 10px;border-radius:6px;margin-bottom:10px;font-size:12px;color:#b0b0ff;">
🔍 Detected <strong>${jobData.questions.length}</strong> question(s) from Easy Apply form
</div>`
: '';
pane.innerHTML = ` pane.innerHTML = `
${qaHeader}
<div class="lja-result" ${rtlAttr}> <div class="lja-result" ${rtlAttr}>
${renderMarkdown(text)} ${renderMarkdown(text)}
</div> </div>
@@ -595,7 +651,7 @@
copyBtn.style.display = 'block'; copyBtn.style.display = 'block';
// Show auto-fill button for Q&A tab // Show auto-fill button for Q&A tab
if (tab === 'qa' && jobData.questions.length > 0) { if (tab === 'qa') {
const fillBtn = document.createElement('button'); const fillBtn = document.createElement('button');
fillBtn.className = 'lja-fill-btn'; fillBtn.className = 'lja-fill-btn';
fillBtn.textContent = '📝 Auto-fill Answers'; fillBtn.textContent = '📝 Auto-fill Answers';
@@ -804,7 +860,12 @@ Brief honest assessment of this opportunity for my profile`
} }
let filled = 0; let filled = 0;
const labels = document.querySelectorAll('.jobs-easy-apply-content label, .jobs-easy-apply-content legend, .jobs-easy-apply-content .fb-dash-form-element__label'); const labels = document.querySelectorAll(
'.jobs-easy-apply-content label, .jobs-easy-apply-content legend, ' +
'.artdeco-modal label, .artdeco-modal legend, ' +
'[role="dialog"] label, [role="dialog"] legend, ' +
'#artdeco-modal-outlet label, #artdeco-modal-outlet legend'
);
labels.forEach(label => { labels.forEach(label => {
const qText = label.textContent.trim().toLowerCase(); const qText = label.textContent.trim().toLowerCase();