Greasy Fork is available in English.

Copy Job Description

Copy LinkedIn Job Description

  1. // ==UserScript==
  2. // @name Copy Job Description
  3. // @namespace http://tampermonkey.net/
  4. // @version 2024-06-13
  5. // @description Copy LinkedIn Job Description
  6. // @author You
  7. // @match https://www.linkedin.com/jobs/view/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=linkedin.com
  9. // @grant GM_setClipboard
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. const currentUrl = window.location.href;
  17. const jobLink = `[Job Link](${currentUrl})`;
  18. const company = document.querySelector('.job-details-jobs-unified-top-card__company-name').innerText;
  19. const jobTitle = document.querySelector('.job-details-jobs-unified-top-card__job-title').innerText;
  20. const jobHeader = `## ${jobTitle} - ${company}`;
  21.  
  22. const headingElement = document.querySelector('h2.text-heading-large');
  23.  
  24. const removeEmptyLines = (input) => {
  25. return input.split('\n').filter(line => line.trim() !== '').join('\n');
  26. };
  27.  
  28. const parseElementToMarkdown = (element) => {
  29. let markdownText = '';
  30.  
  31. element.childNodes.forEach(child => {
  32. if (child.nodeType === Node.TEXT_NODE) {
  33. markdownText += child.textContent.trim();
  34. } else if (child.nodeType === Node.ELEMENT_NODE) {
  35. switch (child.tagName.toLowerCase()) {
  36. case 'strong':
  37. markdownText += `**${child.textContent.trim()}**\n`;
  38. break;
  39. case 'li':
  40. markdownText += `- ${child.textContent.trim()}\n`;
  41. break;
  42. default:
  43. markdownText += parseElementToMarkdown(child) + '\n';
  44. break;
  45. }
  46. }
  47. });
  48.  
  49. return markdownText;
  50. };
  51.  
  52. if (headingElement) {
  53. const container = document.createElement('div');
  54. container.style.display = 'flex';
  55. container.style.alignItems = 'center';
  56. container.style.justifyContent = 'space-between';
  57.  
  58. headingElement.parentNode.insertBefore(container, headingElement);
  59. container.appendChild(headingElement);
  60.  
  61. const button = document.createElement('button');
  62. button.innerText = 'copy job description';
  63. button.className = 'artdeco-button';
  64. button.style.marginLeft = '10px';
  65.  
  66. button.addEventListener('click', () => {
  67. const descriptionContainer = document.querySelector('.jobs-description__content');
  68.  
  69. if (descriptionContainer) {
  70. const mt4Element = descriptionContainer.querySelector('.mt4');
  71.  
  72. if (mt4Element) {
  73. let textToCopy = parseElementToMarkdown(mt4Element);
  74.  
  75. textToCopy = removeEmptyLines(textToCopy);
  76.  
  77. textToCopy = jobHeader + '\n' + jobLink + '\n' + textToCopy;
  78.  
  79. GM_setClipboard(textToCopy.trim(), { mimetype: 'text/plain' });
  80. alert('Job description copied to clipboard!');
  81. } else {
  82. alert('No mt4 element found in job description.');
  83. }
  84. } else {
  85. alert('No job description found.');
  86. }
  87. });
  88.  
  89. container.appendChild(button);
  90. }
  91. })();