Microsoft Store Direct Download

Adds direct download links to Microsoft Store when browsing apps.

  1. // ==UserScript==
  2. // @name Microsoft Store Direct Download
  3. // @name:it Download diretto dal Microsoft Store
  4. // @namespace StephenP
  5. // @version 2.0.2.1
  6. // @description Adds direct download links to Microsoft Store when browsing apps.
  7. // @description:it Aggiunge i link per il download diretto dal Microsoft Store quando si naviga tra le applicazioni.
  8. // @author StephenP
  9. // @grant GM.xmlHttpRequest
  10. // @connect rg-adguard.net
  11. // @match https://apps.microsoft.com/*
  12. // @match https://apps.microsoft.com/*
  13. // @contributionURL https://buymeacoffee.com/stephenp_greasyfork
  14. // ==/UserScript==
  15. var dlBtn;
  16. (function(){
  17. setInterval(checkReload, 1000);
  18. })();
  19. function checkReload(){
  20. let moreBtn=querySelectorAllShadows(".buy-box-container");
  21. if((moreBtn.length>0)&&(querySelectorAllShadows("#dlBtn").length==0)){
  22. /*const origDlBtn=querySelectorAllShadows("sl-button[href^=ms-windows-store]",moreBtn[0]);
  23. console.log(origDlBtn);*/
  24. dlBtn = document.createElement("DIV");
  25. dlBtn.id="dlBtn";
  26. dlBtn.setAttribute("aria-label","Download from AdGuard Store");
  27. dlBtn.style.background="#00a686";
  28. dlBtn.style.font="initial";
  29. dlBtn.style.textAlign="center";
  30. dlBtn.style.borderRadius="var(--sl-input-border-radius-large)";
  31. dlBtn.style.marginTop="0.5em";
  32. dlBtn.innerText="";
  33. dlBtn.appendChild(document.createElement("P"));
  34. dlBtn.firstChild.innerText="\u25bc";
  35. dlBtn.addEventListener("click",function(){openLink(document.location.href,"url")});
  36. moreBtn[0].appendChild(dlBtn);
  37. }
  38. }
  39. function openLink(id,type){
  40. try{
  41. dlBtn.firstChild.innerText="...";
  42. var link="type="+type+"&url="+id+"&ring=RP&lang=it-IT";
  43. GM.xmlHttpRequest({
  44. method: "POST",
  45. url: "https://store.rg-adguard.net/api/GetFiles",
  46. data: link,
  47. headers: {
  48. "Content-Type": "application/x-www-form-urlencoded"
  49. },
  50. onload: function(response) {
  51. dlBtn.firstChild.innerText="\u25bc";
  52. try{
  53. var oldTable=querySelectorAllShadows("#linkTable");
  54. oldTable[0].parentNode.removeChild(oldTable[0]);
  55. var oldMsg=querySelectorAllShadows("#messageFromServer");
  56. oldMsg[0].parentNode.removeChild(oldMsg[0]);
  57. }
  58. catch(err){
  59. console.log(err);
  60. }
  61. try{
  62. output(response,type);
  63. }
  64. catch(err){
  65. console.log(err);
  66. if(type==="ProductId"){
  67. output(err,type);
  68. }
  69. else{
  70. let newId=querySelectorAllShadows("[product-id]")[0].getAttribute("product-id");
  71. openLink(newId,"ProductId");
  72. }
  73. }
  74. }
  75. });
  76. }
  77. catch(err){
  78. console.log(err);
  79. if(type==="ProductId"){
  80. output(err,type);
  81. }
  82. else{
  83. let newId=querySelectorAllShadows("[product-id]")[0].getAttribute("product-id");
  84. openLink(newId,"ProductId");
  85. }
  86. }
  87. }
  88. function output(response,type){
  89. var linkTable = document.createElement("div");
  90. linkTable.innerHTML=response.responseText;
  91. var justTable=linkTable.getElementsByTagName("TABLE")[0];
  92. var messageFromServer=linkTable.getElementsByTagName("P")[0];
  93. messageFromServer.id="messageFromServer";
  94. messageFromServer.style.fontWeight="bold";
  95. if(justTable!==undefined){
  96. justTable.id="linkTable";
  97. const rows=justTable.getElementsByTagName("TR");
  98. for(let row of rows){
  99. if(row.firstChild.firstChild){
  100. if(row.firstChild.firstChild.innerText.match(/\.appx$|\.appxbundle$|\.msix$|\.msixbundle$/)){
  101. row.style.fontWeight="bold";
  102. }
  103. }
  104. }
  105. let pNl=querySelectorAllShadows("sl-card");
  106. if(pNl.length>0){
  107. const pN=pNl[0].parentNode;
  108. pN.insertBefore(justTable, pN.querySelector("sl-card"));
  109. justTable.style.marginTop="2em";
  110. messageFromServer.style.color="green";
  111. pN.insertBefore(messageFromServer, pN.querySelector("sl-card"));
  112. }
  113.  
  114. }
  115. else if((justTable===undefined)&&(type==="url")){
  116. let newId=querySelectorAllShadows("[product-id]")[0].getAttribute("product-id");
  117. openLink(newId,"ProductId");
  118. }
  119. else{
  120. messageFromServer.style.color="red";
  121. dlBtn.parentNode.parentNode.parentNode.appendChild(messageFromServer);
  122. }
  123. }
  124.  
  125.  
  126. //The following function has been taken from https://stackoverflow.com/questions/38701803/how-to-get-element-in-user-agent-shadow-root-with-javascript
  127. /**
  128. * Finds all elements in the entire page matching `selector`, even if they are in shadowRoots.
  129. * Just like `querySelectorAll`, but automatically expand on all child `shadowRoot` elements.
  130. * @see https://stackoverflow.com/a/71692555/2228771
  131. */
  132. function querySelectorAllShadows(selector, el = document.body) {
  133. // recurse on childShadows
  134. const childShadows = Array.from(el.querySelectorAll('*')).
  135. map(el => el.shadowRoot).filter(Boolean);
  136.  
  137. // console.log('[querySelectorAllShadows]', selector, el, `(${childShadows.length} shadowRoots)`);
  138.  
  139. const childResults = childShadows.map(child => querySelectorAllShadows(selector, child));
  140.  
  141. // fuse all results into singular, flat array
  142. const result = Array.from(el.querySelectorAll(selector));
  143. return result.concat(childResults).flat();
  144. }