Open As User Script

Opens gitlab or github files as a userscript on Violentmonkey

As of 2024-09-10. See the latest version.

  1. // ==UserScript==
  2. // @name Open As User Script
  3. // @namespace https://gitlab.com/Dwyriel
  4. // @version 0.4.0
  5. // @description Opens gitlab or github files as a userscript on Violentmonkey
  6. // @author Dwyriel
  7. // @license MIT
  8. // @match *://*gitlab.com/*
  9. // @match *://*github.com/*
  10. // @grant none
  11. // @run-at document-idle
  12. // @homepageURL https://gitlab.com/Dwyriel/Greasyfork-Scripts
  13. // ==/UserScript==
  14.  
  15. (function () {
  16. 'use strict';
  17. const svgHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 488.17122 451.46743"><path d="M347.40064,23.76436H235.12832V38.087h48.97474v179.7281s2.31016,59.13917-55.90521,61.91145c-58.21515,2.772-72.99988-8.31661-72.99988-8.31661s-22.40839-8.54745-24.32225-52.88553c-.11377-2.63311.29688-5.26269.29688-7.89823V38.087h34.65191V23.76436H53.55219V38.087H89.12811V221.98343c0,15.9756,4.41178,31.79326,13.51435,44.92192,12.01268,17.32595,23.44771,33.15023,76.58065,36.38441h42.05554c31.31612,0,60.68214-17.05513,74.58085-45.11808q.91684-1.85058,1.77536-3.80232a96.7686,96.7686,0,0,0,7.72129-38.97688V38.087h42.04449Z" transform="translate(-53.55219 -23.76436)"/><path d="M537.6011,350.10831S533.28894,308.218,465.525,286.65676c-30.90436-9.83307-50.66152-19.15388-63.01107-26.38433-15.55236-9.10566-25.98739-25.42652-26.20828-43.447-.499-40.71248,50.40925-44.13486,50.40925-44.13486,71.68709.49768,81.1559,26.73424,82.15193,36.788v21.73509h18.26168V159.90786c-71.98728-18.32707-129.9833-5.08244-129.9833-5.08244s-60.37134,16.633-62,80.08455,59.5359,78.85237,59.5359,78.85237c51.214,11.41934,76.77018,26.72628,89.33378,37.95014A45.49218,45.49218,0,0,1,498.085,376.84211c18.01935,90.13167-73.83422,79.22414-73.83422,79.22414-70.22783,1.848-70.84392-65.29958-70.84392-65.29958v-4.1582H335.1452v76.85015c78.72667,21.15788,143.89239,8.51718,160.1143,2.57148a101.02229,101.02229,0,0,1,10.39018-3.43365C558.64234,449.46956,537.6011,350.10831,537.6011,350.10831Z" transform="translate(-53.55219 -23.76436)"/></svg>`;
  18. const elementID_1 = "OaUS_g893n1g7f561nf_1";
  19. const elementID_2 = "OaUS_g893n1g7f561nf_2";
  20. const config = { attributes: true, childList: true, subtree: true };
  21. const svgDoc = new DOMParser().parseFromString(svgHTML, 'image/svg+xml');
  22. let mutationObs = null;
  23. function openUrl(url) {
  24. var newWindow = window.open(url, "File as UserScript");
  25. let intervalHandler = setInterval(() => {
  26. if (newWindow.closed) {
  27. clearInterval(intervalHandler);
  28. return;
  29. }
  30. newWindow.close();
  31. }, 1000);
  32. }
  33. function genUrlFromGitlab() {
  34. let url = window.location.toString().replace('blob', 'raw');
  35. return url.includes("?") ? `${url}&file=as/script.user.js` : `${url}?file=as/script.user.js`;
  36. }
  37. function gitlabCallback() {
  38. if (document.getElementById(elementID_1))
  39. return;
  40. let btnToClone = document.querySelector(`div[data-testid="default-actions-container"]`)?.querySelector("[title*='raw']");
  41. if (!btnToClone)
  42. return;
  43. let clonedNode = btnToClone.cloneNode(true);
  44. let clonedSVG = svgDoc.firstChild.cloneNode(true);
  45. let svg = clonedNode.children[0];
  46. clonedSVG.classList = svg.classList;
  47. svg.after(clonedSVG);
  48. svg.remove();
  49. clonedNode.id = elementID_1;
  50. clonedNode.removeAttribute('href');
  51. clonedNode.setAttribute('aria-label', "Open as Userscript");
  52. clonedNode.setAttribute('title', "Open as Userscript");
  53. clonedNode.onclick = function () { openUrl(genUrlFromGitlab()) };
  54. btnToClone.after(clonedNode);
  55. }
  56. function genUrlFromGithub() {
  57. let url = window.location.toString().replace('github.com', 'raw.githubusercontent.com').replace('blob/', '');
  58. return url.includes("?") ? `${url}&file=as/script.user.js` : `${url}?file=as/script.user.js`;
  59. }
  60. function githubCreateDesktopButton() {
  61. if (document.getElementById(elementID_1))
  62. return;
  63. let btnToClone = document.querySelectorAll('[class*="ButtonGroup"]')[0]?.parentNode.querySelector('[data-testid*="copy-raw"]');
  64. if (!btnToClone)
  65. return;
  66. let clonedNode = btnToClone.cloneNode(true);
  67. let clonedSVG = svgDoc.firstChild.cloneNode(true);
  68. let svg = clonedNode.children[0];
  69. clonedSVG.classList = svg.classList;
  70. clonedSVG.setAttribute('width', 16);
  71. clonedSVG.setAttribute('height', 16);
  72. svg.after(clonedSVG);
  73. svg.remove();
  74. clonedNode.id = elementID_1;
  75. clonedNode.removeAttribute('data-hotkey');
  76. clonedNode.removeAttribute('aria-describeby');
  77. clonedNode.setAttribute('aria-label', "Open as Userscript");
  78. clonedNode.setAttribute('title', "Open as Userscript");
  79. clonedNode.setAttribute('data-testid', "open-as-userscript");
  80. clonedNode.onclick = function () { openUrl(genUrlFromGithub()) };
  81. btnToClone.after(clonedNode);
  82. }
  83. function githubCreateMobileButton() {
  84. if (document.getElementById(elementID_2))
  85. return;
  86. let rawFileList = document.querySelectorAll('[class*="List__ListBox"]')[0]?.lastChild;
  87. if (!rawFileList)
  88. return;
  89. let listEntries = rawFileList.querySelectorAll('[class*="Link__StyledLink"]');
  90. if (listEntries.length == 0)
  91. return;
  92. let listEntry = listEntries[listEntries.length - 1].parentNode;
  93. let clonedNode = listEntry.cloneNode(true);
  94. clonedNode.id = elementID_2;
  95. clonedNode.firstChild.innerText = "As Userscript"
  96. clonedNode.firstChild.onclick = function () { openUrl(genUrlFromGithub()) };
  97. listEntry.after(clonedNode);
  98. }
  99. function githubCallbcak() {
  100. if (!document.getElementById(elementID_1))
  101. githubCreateDesktopButton();
  102. if (!document.getElementById(elementID_2))
  103. githubCreateMobileButton();
  104. }
  105. if (window.location.toString().includes("//gitlab.com/"))
  106. mutationObs = new MutationObserver(gitlabCallback);
  107. else if (window.location.toString().includes("//github.com/"))
  108. mutationObs = new MutationObserver(githubCallbcak);
  109. if (mutationObs)
  110. mutationObs.observe(document.body, config);
  111. })();