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();
})();