Gitlab, open file in phpstorm

add a link to phpstorm in gitlab ci merge requests files

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

  1. // ==UserScript==
  2. // @name Gitlab, open file in phpstorm
  3. // @namespace micoli.phpstorm.openlinks
  4. // @version 0.8
  5. // @description add a link to phpstorm in gitlab ci merge requests files
  6. // @author You
  7. // @match https://gitlab.com/*
  8. // ==/UserScript==
  9.  
  10. (function () {
  11. // defaults write com.google.Chrome URLWhitelist -array "phpstorm://*
  12. 'use strict';
  13. let config = {};
  14. let linkCounter = 0;
  15.  
  16. document.querySelectorAll('a[href*="redirectFromReferer"]').forEach((link)=> {
  17. link.href = link.href+'?referer='+window.location.href
  18. });
  19.  
  20. const project = $('nav.breadcrumbs ul.js-breadcrumbs-list li a')[1].pathname;
  21.  
  22. const loadPreferences = function () {
  23. if (!window.localStorage.getItem('openInPhpStormSettings')) {
  24. return {};
  25. }
  26. config = JSON.parse(window.localStorage.getItem('openInPhpStormSettings'));
  27. }
  28.  
  29. const savePreferences = function () {
  30. window.localStorage.setItem('openInPhpStormSettings', JSON.stringify(config))
  31. removeLinks();
  32. setLinks();
  33. }
  34.  
  35. const icon = function (color) {
  36. return `
  37. <svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 128 128" width="16" height="16">
  38. <path d="M61,87H35a2,2,0,0,0,0,4H61a2,2,0,0,0,0-4Z"/>
  39. <path fill="${color || '#A12681'}" d="M52.32,42.24a5.52,5.52,0,0,0-2-2.14,5.82,5.82,0,0,0-3.09-.82H41V50.57h6.88A4.71,4.71,0,0,0,51.64,49,5.81,5.81,0,0,0,53,45,5.91,5.91,0,0,0,52.32,42.24Zm0,0a5.52,5.52,0,0,0-2-2.14,5.82,5.82,0,0,0-3.09-.82H41V50.57h6.88A4.71,4.71,0,0,0,51.64,49,5.81,5.81,0,0,0,53,45,5.91,5.91,0,0,0,52.32,42.24ZM114.15,70.4l11.77-11.59a7.87,7.87,0,0,0,1.93-6.73L114.23,17.82a7.78,7.78,0,0,0-4.75-5.09L85.06,8.27A7.08,7.08,0,0,0,83,8a8.92,8.92,0,0,0-5,1.48l-9.51,7-1.35-4A7.73,7.73,0,0,0,62,7.87L26,.12A5.62,5.62,0,0,0,24.77,0a7.84,7.84,0,0,0-5.41,2.2L2.08,20.91a9,9,0,0,0-2,6.83L11.87,92.1a5,5,0,0,0,4.7,3.9H25v3a4,4,0,0,0,4,4h8.37l.76,6.32a7.18,7.18,0,0,0,4.24,5.35l34.85,12.9a7.87,7.87,0,0,0,2.69.43,9.17,9.17,0,0,0,4.5-1.1l41.53-25a4.33,4.33,0,0,0,1.6-5.62ZM80.4,12.7A5.08,5.08,0,0,1,83,12c.47,0,25.41,4.61,25.41,4.61a4,4,0,0,1,1.88,2.14l.07.28.1.27L124,53.21a4.12,4.12,0,0,1-.87,2.75L112.23,66.68,103,48.83V29a4,4,0,0,0-4-4H63.8ZM73.73,51.21l-3.14-.67a27.09,27.09,0,0,1-4.89-1.22,8.8,8.8,0,0,1-3.24-2.12,5.26,5.26,0,0,1-1.46-4,6,6,0,0,1,2.5-5.34,12,12,0,0,1,7-1.87,15.4,15.4,0,0,1,4.76.68,15.86,15.86,0,0,1,4.14,2.1l.11.09-2,2.82a.45.45,0,0,0,0,.09.62.62,0,0,1-.22-.11A14.76,14.76,0,0,0,73.77,40a9.55,9.55,0,0,0-7.1.16A3.05,3.05,0,0,0,64.84,43a2.66,2.66,0,0,0,1,2.11,5.17,5.17,0,0,0,2,1c.51.16,1.48.4,2.9.72L72,47a29.44,29.44,0,0,1,5,1.36,7,7,0,0,1,2.79,2.07A6.18,6.18,0,0,1,81,54.57,6.45,6.45,0,0,1,78.59,60a11.2,11.2,0,0,1-7.07,2,16.38,16.38,0,0,1-10.41-3.35L61,58.56s1.91-2.93,1.91-2.93a.57.57,0,0,1,.19.1,17,17,0,0,0,4.08,2.08c3.48,1.26,6.41,1,8.24-.17a3.41,3.41,0,0,0,1.74-2.92C77.16,53.56,76.58,52,73.73,51.21ZM25,29V92H16.57a1,1,0,0,1-.76-.62L4,27a5.08,5.08,0,0,1,1-3.39L22.29,4.92A3.91,3.91,0,0,1,24.77,4c.18,0,36.4,7.78,36.4,7.78a3.86,3.86,0,0,1,2.2,2L65.14,19l-8.06,6H29A4,4,0,0,0,25,29ZM41,61.91s0,.08-.09.09H37.1a.13.13,0,0,1-.1-.09V36.17A.38.38,0,0,1,37,36a.41.41,0,0,1,.16,0H47a11.27,11.27,0,0,1,5.31,1.2,8.57,8.57,0,0,1,3.46,3.26,9.56,9.56,0,0,1,.07,9.11,7.82,7.82,0,0,1-3.31,3.09A12,12,0,0,1,47,53.85H41Zm82.91,36.56-41.53,25a5.22,5.22,0,0,1-2.44.53,3.9,3.9,0,0,1-1.3-.18l-34.85-12.9a3.35,3.35,0,0,1-1.66-2.08L41.4,103H99a4,4,0,0,0,4-4V57.54l21,40.58A.37.37,0,0,1,123.88,98.47ZM51.64,49A5.81,5.81,0,0,0,53,45a5.91,5.91,0,0,0-.67-2.8,5.52,5.52,0,0,0-2-2.14,5.82,5.82,0,0,0-3.09-.82H41V50.57h6.88A4.71,4.71,0,0,0,51.64,49Z"/>
  40. </svg>`
  41. };
  42.  
  43. const phpStormMimeLink = function(link){
  44. const prefix = config[project] || '';
  45. document.location = `phpstorm://open?file=${prefix}${link}`;
  46. };
  47.  
  48. document.phpStormRestApiLink = function (link) {
  49. const prefix = config[project] || '';
  50. const hrefLink = `http://localhost:63342/api/file?file=${prefix}${link}`;
  51. const linkWindow = window.open(hrefLink,'autoOpen');
  52. setTimeout(function(){
  53. linkWindow.close();
  54. },1000);
  55. };
  56.  
  57. const openLinkInHiddenForm = function (action,parameters) {
  58. let hiddenDiv = document.getElementById('phpstorm-autoform');
  59.  
  60. if (hiddenDiv){
  61. hiddenDiv.parentNode.removeChild(hiddenDiv);
  62. }
  63. console.log(action);
  64. document.querySelector('body').insertAdjacentHTML('beforeEnd',
  65. `<form id='phpstorm-autoform' action="${action}" target="_hiddenTarget" method='GET'>
  66. <input name="file" value="${parameters.file}"/>
  67. <iframe name="_hiddenTarget" width="0" height="0"></iframe>
  68. </form>
  69. `);
  70.  
  71. document.getElementById('phpstorm-autoform').submit();
  72. };
  73.  
  74. const setLinks = function () {
  75. document.querySelectorAll('.diff-file').forEach(function (divDiffFile) {
  76. let jsEditInPhpStormButtonFound = false;
  77. let linkCounter = 0;
  78. divDiffFile.querySelectorAll('button[data-testid="diff-file-copy-clipboard"]').forEach( function (buttonClipboard) {
  79. const fileUrl = JSON.parse(buttonClipboard.getAttribute('data-clipboard-text'))['text'];
  80.  
  81. divDiffFile.querySelectorAll('.js-edit-in-phpstorm').forEach(function (buttonEditInPhpStorm) {
  82. if (buttonEditInPhpStorm.getAttribute('data-link') === fileUrl) {
  83. jsEditInPhpStormButtonFound = true;
  84. }
  85. });
  86.  
  87. if (jsEditInPhpStormButtonFound) {
  88. return;
  89. }
  90.  
  91. linkCounter++;
  92. const jsEditInPhpStormId = `js-edit-in-phpstorm-${divDiffFile.id}-${linkCounter}`;
  93. buttonClipboard
  94. .insertAdjacentHTML('afterend', `
  95. <div
  96. id="${jsEditInPhpStormId}"
  97. title="Edit file in phpStorm"
  98. data-link="${fileUrl}"
  99. class="btn btn-transparent js-edit-in-phpstorm"
  100. style="margin-top: -6px;"
  101. >
  102. ${icon()}
  103. </div>
  104. `);
  105.  
  106. document.getElementById(jsEditInPhpStormId).addEventListener('click',function(event){
  107. document.phpStormRestApiLink(event.currentTarget.dataset.link);
  108. });
  109. });
  110. });
  111.  
  112. document.querySelectorAll('.js-edit-in-phpstorm').forEach(function (buttonEditInPhpStorm) {
  113. let buttonClipboardFound = false;
  114. buttonEditInPhpStorm.parentNode.querySelectorAll('.diff-file button[data-testid="diff-file-copy-clipboard"]').forEach( function (buttonClipboard) {
  115. const fileUrl = JSON.parse(buttonClipboard.getAttribute('data-clipboard-text'))['text'];
  116. if(buttonEditInPhpStorm.getAttribute('data-link') === fileUrl) {
  117. buttonClipboardFound = true;
  118. }
  119. });
  120. if(!buttonClipboardFound) {
  121. buttonEditInPhpStorm.remove();
  122. }
  123. });
  124. }
  125.  
  126. const removeLinks = function () {
  127. document.querySelectorAll('.js-edit-in-phpstorm').forEach(function (v) {
  128. v.parentElement.removeChild(v);
  129. });
  130. document.querySelectorAll('.file-header-content .file-title-name').forEach(function (v) {
  131. v.class = v.class.replace(/rgx-add-phpstorm-done/, '');
  132. });
  133. }
  134.  
  135. const isConfigurationValid = function () {
  136. try {
  137. JSON.parse(document.getElementById("open-in-phpstorm-map").value);
  138. return true;
  139. } catch (e) {
  140. return false;
  141. }
  142. };
  143.  
  144. const togglePref = function () {
  145. var element = document.getElementById('open-in-phpstorm-settings');
  146. element.style.display = element.style.display == 'none' ? 'inline-block' : 'none'
  147. if (element.style.display == 'inline-block') {
  148. document.getElementById("open-in-phpstorm-map").value = JSON.stringify(config);
  149. }
  150. };
  151.  
  152. const initPreferenceButton = function () {
  153. document.querySelector('.alert-wrapper').insertAdjacentHTML('afterEnd', `
  154.  
  155. <div class="container-fluid">
  156. <div
  157. class="row"
  158. id="open-in-phpstorm-settings"
  159. style="display:none;width:600px;"
  160. >
  161. <div class="form-group col-md-9">
  162. <label class="label-bold" for="open-in-phpstorm-map">
  163. "Open in phpstorm" project association
  164. </label>
  165. <textarea class="form-control" rows="3" maxlength="650" id="open-in-phpstorm-map" name="open-in-phpstorm-settings"></textarea>
  166. </div>
  167. <div class="form-group col-md-9">
  168. <pre>{"${project}":"/home/src/localpath/"}</pre>
  169. <button
  170. id="js-btn-save-in-phpstorm-settings"
  171. class="btn btn-secondary"
  172. style="float:left;"
  173. >
  174. Save ${icon('#919191')} Preferences
  175. </button>
  176. </div>
  177. </div>
  178. </div>
  179. `);
  180.  
  181. document.querySelector('.dropdown-menu.dropdown-menu-right .current-user').parentNode.insertAdjacentHTML('afterend', `
  182. <li >
  183. <a title="PhpStorm Settings" id="js-btn-open-in-phpstorm-settings" data-qa-selector="open_in_phpstorm_settings_link" href="#">${icon('#919191')} "Open in PhpStorm" Settings</a>
  184. </li>
  185. `);
  186.  
  187. document.getElementById('js-btn-open-in-phpstorm-settings').addEventListener('click', function () {
  188. togglePref();
  189. return false;
  190. });
  191.  
  192. document.getElementById('js-btn-save-in-phpstorm-settings').addEventListener('click', function () {
  193. if (isConfigurationValid()) {
  194. togglePref();
  195. config = JSON.parse(document.getElementById("open-in-phpstorm-map").value);
  196. savePreferences();
  197. }
  198. return false;
  199. });
  200. };
  201.  
  202.  
  203. console.log('started');
  204. loadPreferences();
  205. setLinks();
  206. window.setTimeout(initPreferenceButton, 50);
  207. window.setInterval(setLinks, 1500);
  208. })();