MDA linkedin improvements

my linkedin improvements started 2025-01-11

当前为 2025-01-23 提交的版本,查看 最新版本

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