您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
Extract and manage company names from job listings on LinkedIn job search, with immediate blocking and interactive UI for managing blocked companies.
// ==UserScript== // @name Company Name Extractor with Block List (Enhanced) // @namespace http://tampermonkey.net/ // @version 1.3 // @description Extract and manage company names from job listings on LinkedIn job search, with immediate blocking and interactive UI for managing blocked companies. // @author Daniel Gleason // @match https://www.linkedin.com/jobs/* // @require https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.2/awesomplete.min.js // @grant GM_setValue // @grant GM_getValue // @license MIT // ==/UserScript== (function() { 'use strict'; let isUIOpen = false; // Flag to track if UI is already open let modalContent; // Reference to the modal content // Function to extract and handle job postings based on company block list function handleJobPostings() { const jobPostings = document.querySelectorAll('div[data-job-id]'); jobPostings.forEach(jobPosting => { const companyNameElement = jobPosting.querySelector('span.job-card-container__primary-description'); if (companyNameElement) { const companyName = companyNameElement.innerText.trim(); if (isCompanyBlocked(companyName)) { // Company is blocked, remove the job posting div jobPosting.remove(); } } }); } // Function to check if a company is blocked function isCompanyBlocked(companyName) { const blockedCompanies = getBlockedCompanies(); return blockedCompanies.includes(companyName); } // Function to retrieve blocked companies from storage function getBlockedCompanies() { const blockedCompaniesJSON = GM_getValue('blockedCompanies', '[]'); return JSON.parse(blockedCompaniesJSON); } // Function to save blocked companies to storage function saveBlockedCompanies(blockedCompanies) { const blockedCompaniesJSON = JSON.stringify(blockedCompanies); GM_setValue('blockedCompanies', blockedCompaniesJSON); } // Function to add a company to block list function addCompanyToBlockList(companyName) { let blockedCompanies = getBlockedCompanies(); blockedCompanies.push(companyName.trim()); saveBlockedCompanies(blockedCompanies); // Immediately remove job postings for the newly blocked company const jobPostings = document.querySelectorAll('div[data-job-id]'); jobPostings.forEach(jobPosting => { const companyNameElement = jobPosting.querySelector('span.job-card-container__primary-description'); if (companyNameElement) { const postingCompanyName = companyNameElement.innerText.trim(); if (postingCompanyName === companyName.trim()) { jobPosting.remove(); // Remove the job posting } } }); updateBlockedCompaniesTable(); // Update table after adding a new company } // Function to remove a company from block list function removeCompanyFromBlockList(companyName) { let blockedCompanies = getBlockedCompanies(); const index = blockedCompanies.indexOf(companyName.trim()); if (index !== -1) { blockedCompanies.splice(index, 1); saveBlockedCompanies(blockedCompanies); updateBlockedCompaniesTable(); // Update table after removing a company } } // Function to update the displayed table of blocked companies function updateBlockedCompaniesTable() { const table = document.getElementById('blockedCompaniesTable'); if (!table) return; const blockedCompanies = getBlockedCompanies(); // Clear existing table rows table.innerHTML = ''; // Add rows for each blocked company blockedCompanies.forEach(companyName => { const row = table.insertRow(); const nameCell = row.insertCell(); nameCell.textContent = companyName; const actionCell = row.insertCell(); const removeButton = document.createElement('button'); removeButton.textContent = 'X'; removeButton.style.color = 'red'; removeButton.style.cursor = 'pointer'; removeButton.addEventListener('click', () => { removeCompanyFromBlockList(companyName); }); actionCell.appendChild(removeButton); }); } // Function to display the blocked companies UI function displayBlockedCompaniesUI() { if (isUIOpen) { return; // Prevent opening UI more than once } const blockedCompanies = getBlockedCompanies(); // Create a table to display blocked companies const table = document.createElement('table'); table.id = 'blockedCompaniesTable'; // Set table id for easy access table.style.borderCollapse = 'collapse'; table.style.marginTop = '20px'; // Add header row const headerRow = table.insertRow(); const nameHeader = headerRow.insertCell(); nameHeader.textContent = 'Company Name'; const actionHeader = headerRow.insertCell(); actionHeader.textContent = 'Action'; // Add rows for each blocked company blockedCompanies.forEach(companyName => { const row = table.insertRow(); const nameCell = row.insertCell(); nameCell.textContent = companyName; const actionCell = row.insertCell(); const removeButton = document.createElement('button'); removeButton.textContent = 'X'; removeButton.style.color = 'red'; removeButton.style.cursor = 'pointer'; removeButton.addEventListener('click', () => { removeCompanyFromBlockList(companyName); }); actionCell.appendChild(removeButton); }); // Create input field for adding new company to block list const inputContainer = document.createElement('div'); inputContainer.style.marginTop = '10px'; inputContainer.style.display = 'flex'; inputContainer.style.alignItems = 'center'; const addCompanyInput = document.createElement('input'); addCompanyInput.placeholder = 'Enter company name'; addCompanyInput.style.marginRight = '10px'; inputContainer.appendChild(addCompanyInput); const addButton = document.createElement('button'); addButton.textContent = 'Add to Block List'; addButton.style.cursor = 'pointer'; addButton.style.backgroundColor = '#007bff'; // Blue background color addButton.style.color = 'white'; // White text color addButton.style.border = 'none'; // No border addButton.style.borderRadius = '4px'; // Rounded corners addButton.style.padding = '8px 16px'; // Padding addButton.addEventListener('click', () => { const newCompanyName = addCompanyInput.value.trim(); if (newCompanyName !== '') { addCompanyToBlockList(newCompanyName); addCompanyInput.value = ''; // Clear input field } }); inputContainer.appendChild(addButton); // Display the table and input field in a modal modalContent = document.createElement('div'); modalContent.style.position = 'fixed'; modalContent.style.top = '50px'; modalContent.style.left = '50px'; modalContent.style.padding = '20px'; modalContent.style.backgroundColor = 'white'; modalContent.style.border = '1px solid black'; modalContent.style.zIndex = '9999'; modalContent.style.cursor = 'move'; // Make the modal draggable modalContent.appendChild(table); modalContent.appendChild(inputContainer); // Add close button const closeButton = document.createElement('button'); closeButton.textContent = 'Close'; closeButton.style.marginTop = '10px'; closeButton.style.cursor = 'pointer'; closeButton.style.backgroundColor = '#dc3545'; // Red background color closeButton.style.color = 'white'; // White text color closeButton.style.border = 'none'; // No border closeButton.style.borderRadius = '4px'; // Rounded corners closeButton.style.padding = '8px 16px'; // Padding closeButton.addEventListener('click', () => { modalContent.remove(); isUIOpen = false; // Reset flag when UI is closed }); modalContent.appendChild(closeButton); document.body.appendChild(modalContent); isUIOpen = true; // Set flag to indicate UI is open // Make the modal draggable let isDragging = false; let offsetX, offsetY; modalContent.addEventListener('mousedown', startDrag); modalContent.addEventListener('mouseup', endDrag); function startDrag(e) { isDragging = true; offsetX = e.clientX - modalContent.getBoundingClientRect().left; offsetY = e.clientY - modalContent.getBoundingClientRect().top; } function endDrag() { isDragging = false; } document.addEventListener('mousemove', e => { if (isDragging) { modalContent.style.left = `${e.clientX - offsetX}px`; modalContent.style.top = `${e.clientY - offsetY}px`; } }); // Initialize Awesomplete autocomplete for input field const awesomplete = new Awesomplete(addCompanyInput, { list: getUniqueCompanyNames(), // Autocomplete with unique company names }); // Handle Enter key press to add company to block list addCompanyInput.addEventListener('keydown', event => { if (event.keyCode === 13) { event.preventDefault(); const newCompanyName = addCompanyInput.value.trim(); if (newCompanyName !== '') { addCompanyToBlockList(newCompanyName); addCompanyInput.value = ''; // Clear input field } } }); } // Function to get unique company names from job postings function getUniqueCompanyNames() { const jobPostings = document.querySelectorAll('span.job-card-container__primary-description'); const companyNames = new Set(); jobPostings.forEach(companyNameElement => { const companyName = companyNameElement.innerText.trim(); companyNames.add(companyName); }); return Array.from(companyNames); } // Add button to display blocked companies UI const showBlockedCompaniesButton = document.createElement('button'); showBlockedCompaniesButton.textContent = 'View Blocked Companies'; showBlockedCompaniesButton.style.position = 'fixed'; showBlockedCompaniesButton.style.top = '20px'; showBlockedCompaniesButton.style.right = '20px'; showBlockedCompaniesButton.style.zIndex = '9999'; showBlockedCompaniesButton.style.backgroundColor = '#28a745'; // Green background color showBlockedCompaniesButton.style.color = 'white'; // White text color showBlockedCompaniesButton.style.border = 'none'; // No border showBlockedCompaniesButton.style.borderRadius = '4px'; // Rounded corners showBlockedCompaniesButton.style.padding = '8px 16px'; // Padding showBlockedCompaniesButton.style.cursor = 'pointer'; showBlockedCompaniesButton.addEventListener('click', displayBlockedCompaniesUI); document.body.appendChild(showBlockedCompaniesButton); // Immediately block any existing job postings for companies in the block list handleJobPostings(); })();