Greasy Fork 支持简体中文。

Company Name Extractor with Block List (Enhanced)

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

})();