MDA linkedin improvements

my linkedin improvements started 2025-01-11

  1. // ==UserScript==
  2. // @name MDA linkedin improvements
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.5.7
  5. // @description my linkedin improvements started 2025-01-11
  6. // @author mr-d-r
  7. // @license MIT
  8. // @match http*://*.linkedin.com/*
  9. // @grant GM_addStyle
  10. // @require https://update.greasyfork.org/scripts/524553/1525219/MDA%20library.js
  11. // ==/UserScript==
  12.  
  13. // update check 27.01.2025
  14.  
  15. (function() {
  16. 'use strict';
  17. var dbg=0, aa, bb;
  18.  
  19. if( window.location.hostname.match("merchantpool1") ) { log(`${GM.info.script.name}: ${window.location.hostname} skipped !!!`); return; }
  20. console.log("\n", "\n", `${GM.info.script.name}: start ${window.location.hostname} debug=${(typeof dbg == "undefined") ? "absent" : dbg} MDAlib=${(typeof MDAlib == "undefined") ? "absent" : MDAlib}` );
  21.  
  22. // end of script
  23.  
  24.  
  25. function myActions (caller) { var a, b, fn=fnName();
  26. log(`${fn}(${caller}) @${window.location.hostname}: start`);
  27. click_ShowMore();
  28.  
  29. qSA(".ad-banner").forEach(item =>{
  30. item.remove(); log(`ad had been removed`); //if( item?.style?.display && item?.style?.display != 'none' ) item.style.display='none'; log(`ad had been hidden`);
  31. });
  32. qSA("div[id='sub-frame-error']").forEach(item =>{ item?.remove(); log(`sub-frame-error removed`); });
  33.  
  34. qSA("article.mb3").forEach(item =>{
  35. if( a=qS("use[href='#close-small']") ) { a.parentNode.parentNode.click(); log(`linkedin app AD found - closed`); }
  36. });
  37.  
  38. // WORKS, вроде реально норм, но под настроение еще искать более точные критерии для рекламы
  39. document.querySelectorAll(".relative > div[id*='ember']").forEach(i =>{
  40. i.querySelectorAll("span[aria-hidden='true']").forEach(j =>{
  41. if( j.textContent == "Promoted" ) {
  42. a=i.querySelector(".update-components-actor__image"); // ADs title
  43. console.log("promoted1 - removed", a?.ariaLabel);
  44. i.remove(); // j.textContent=`${j.textContent}_Removed!!!`; i.style.display='none'; // i.remove();
  45. }
  46. });
  47. i.querySelectorAll(".update-components-actor__sub-description-button-text").forEach(j =>{
  48. if( j.textContent.match(/Book an appointment/i) ) {
  49. console.log("Book an appointment - removed", a?.ariaLabel);
  50. i.remove(); // j.textContent=`${j.textContent}_Removed!!!`; i.style.display='none'; // i.remove();
  51. }
  52. });
  53. });
  54.  
  55. // например если .update-components-header__text-view сразу <span> и сразу href="https://www.linkedin.com/company/*"
  56. document.querySelectorAll(".relative > div[id*='ember']").forEach(i =>{
  57. i.querySelectorAll(".update-components-actor__container [href*='/company']").forEach(j =>{ // document.querySelectorAll(".update-components-actor__container [href*='/company']")[10].href
  58. console.log("promoted2 - removed", j?.href);
  59. i.remove();
  60. });
  61. });
  62.  
  63. /* 2finish
  64. document.querySelectorAll(".relative > z&*&^*&^*^zxzx").forEach(i =>{
  65. i.querySelectorAll(".update-components-actor__meta-link [href*='/company']").forEach(j =>{ // document.querySelectorAll(".update-components-actor__container [href*='/company']")[10].href
  66. console.log("promoted22 - removed", j?.href);
  67. i.remove();
  68. });
  69. });
  70. */
  71.  
  72.  
  73. } // myActions()
  74.  
  75.  
  76. window.addEventListener('load', function() { var fn=fnName();
  77. ttout(300, ()=>{ myActions(`onLoad`); });
  78. ttout(2500, ()=>{ myActions(`onLoad`); });
  79.  
  80. // ttout(onLOADlckTMOUT, ()=>{ onLOADlck=false; }); // 3000 ms IMPORTANT !!!
  81. }); // window.addEventListener('load'...) // onload
  82.  
  83.  
  84. window.navigation.addEventListener("navigate", (event) => { // https://stackoverflow.com/questions/6390341/how-to-detect-if-url-has-changed-after-hash-in-javascript
  85. });
  86.  
  87.  
  88. window.addEventListener('keydown', (e) => { // window.addEventListener("keyup", async (e) => {
  89. var a, b, aa, bb, cc, c1, c2; // if(dbg) log("parent " +e.code);
  90. if( anyActiveInput() ) { log(`on ${e.code}: active input detected`); return; }
  91.  
  92. switch (e.code) { // see https://www.freecodecamp.org/news/javascript-keycode-list-keypress-event-key-codes/
  93. case "KeyA":
  94. //log(`KeyA: clicked`);
  95. myActions(`onKeyA`); // chk upd 111 222 333 444 555
  96. e.preventDefault();
  97. break;
  98. case "KeyE": // Endorse
  99. if (e.ctrlKey || e.altKey || e.shiftKey) break;
  100. aa=document.querySelectorAll(".artdeco-button__text").length;
  101. cc=0; document.querySelectorAll(".artdeco-button__text").forEach(item => {
  102. if(item.textContent.match(/Endorse\n/)) { console.log(item); cc++; item.click(); } ;
  103. });
  104. c1=0; document.querySelectorAll(".artdeco-button__text").forEach(item => {
  105. if(item.textContent.match(/Endorse\n/)) { c1++; } ;
  106. });
  107. c2=0; document.querySelectorAll(".artdeco-button__text").forEach(item => {
  108. if(item.textContent.match(/Endorse\n/)) { c2++; } ;
  109. });
  110. log(`KeyE: endorse clicked: ${cc}, endorse left: ${c1}, endorsed found: ${c2}`);
  111. e.preventDefault();
  112. break;
  113. case "KeyM": // чаще всего кнопка "Show more feed updates" показывается при запущенном devtool !!!
  114. if (e.ctrlKey || e.altKey || e.shiftKey) break;
  115. log(`KeyM: "Show more feed updates"`);
  116. document.querySelectorAll(".display-flex").forEach(item => {
  117. a=item.querySelector(".artdeco-button__text");
  118. if (a) b=a.innerText;
  119. if (b) console.log("bbb", b == "Show more feed updates");
  120. if( b == "Show more feed updates") {
  121. console.log(a); a.parentNode.click(); // WORKS, но орет Uncaught TypeError: Cannot read properties of null (reading 'parentNode') !!!
  122. }
  123. });
  124. e.preventDefault();
  125. break;
  126.  
  127. } // end of switch
  128. return;
  129. }); // end of window.addEventListener("keydown", (e) =>
  130.  
  131.  
  132. var onScrollLOCK=false, onScrollTMOUT=300, scrollBefore = 0, tickCURR, tickPROC;
  133. window.addEventListener('scroll',function(e){ // !!! https://stackoverflow.com/questions/4670834/capturing-the-scroll-down-event
  134. const scrolled = window.scrollY;
  135. var a, procCNT=0;
  136.  
  137. if( onScrollLOCK ) return; onScrollLOCK=true; ttout(onScrollTMOUT, ()=>{ onScrollLOCK=false; });
  138.  
  139. //if( ! onLoadDONE ) return;
  140.  
  141. if(scrollBefore > scrolled){
  142. console.log("ScrollUP");
  143. scrollBefore = scrolled;
  144. //Desired action
  145. } else {
  146. scrollBefore = scrolled;
  147. //console.log("ScrollDOWN");
  148. // tickCURR, tickPROC - MUST BE GLOBAL !!!
  149. tickCURR=Date.now();
  150. if (!tickPROC) tickPROC=setInterval(function () { // если быстро нажали Ctrl +/- несколько раз подряд, то отработать только последнее
  151. let cu=Date.now();
  152. procCNT++;
  153. if ((cu-tickCURR) < 300) { if(dbg && dbg>5) console.log("interv: <600 - skip"); }
  154. else { clearInterval(tickPROC); tickPROC=null; // log("finally fire on scrollDOWN 557732" +procCNT);
  155. myActions(`onScrollDOWN`);
  156. }
  157. }, 600);
  158. }
  159.  
  160. }) // 'scroll'
  161.  
  162. function click_ShowMore () {
  163. if( a=qS(".jobs-description__footer-button[aria-expanded='false']") ) { log(`${window.location.hostname} "See more" clicked`); a.click(); }
  164. //else log(`${window.location.hostname} "See more" is not found`);
  165.  
  166. qSA(".artdeco-button").forEach(item => {
  167. let x=item?.textContent;
  168. if( x.match(/Show more/) ) if( ! x.match(/Show more feed updates/) ) {
  169. console.log(`Show more COULD BE clicked: ${x}`); // item.click();
  170. } ;
  171. });
  172. } // click_ShowMore()
  173. })();
  174.