Copy gerrit CR query link

Add a copy button to copy the gerrit link querying CR

当前为 2023-07-06 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Copy gerrit CR query link
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description Add a copy button to copy the gerrit link querying CR
  6. // @author Jackie
  7. // @match https://gerrit.mot.com*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=mot.com
  9. // @run-at document-end
  10. // @grant GM.addStyle
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. let action = ()=>{
  17. sleep(100).then(()=>{
  18. addButtons();
  19. });
  20. }
  21. //action();
  22. sleep(200).then(()=>{
  23. let c = document.getElementById("gerrit_header");
  24. observeDOM(c, /*onAdd*/ action, /*onRemove*/ action);
  25. });
  26. })();
  27.  
  28. function addButtons() {
  29. console.log(`=======================addButtons`)
  30. let btnCopyCrQueryLink = createButton("CopyQueryLink");
  31. btnCopyCrQueryLink.onclick = () => {
  32. let msg = "CR not found!"
  33. let crDiv = document.getElementsByClassName("com-google-gerrit-client-change-CommitBox_BinderImpl_GenCss_style-text")[0];
  34. if(crDiv && crDiv.firstElementChild){
  35. msg = "https://gerrit.mot.com/#/q/" + crDiv.firstElementChild.text;
  36. }
  37. navigator.clipboard.writeText(msg);
  38. showSnackbar(msg);
  39. }
  40. let parent = document.getElementsByClassName("com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-infoLineHeaderButtons")[0];
  41. if(parent) {
  42. parent.appendChild(btnCopyCrQueryLink);
  43. }
  44. }
  45.  
  46. function showSnackbar(msg) {
  47. let snackbar = getSnackbar();
  48. snackbar.className = "show";
  49. setTimeout(function(){
  50. snackbar.className = snackbar.className.replace("show", "");
  51. }, 1500);
  52. }
  53.  
  54. function getSnackbar() {
  55. let snackbar = document.getElementById('snackbar');
  56. if(!snackbar) {
  57. snackbar = document.createElement("div");
  58. snackbar.id="snackbar";
  59. snackbar.innerHTML="Copied succesfully"
  60. document.getElementsByClassName('screen')[0].appendChild(snackbar);
  61. GM.addStyle(`
  62. #snackbar {
  63. visibility: hidden;
  64. min-width: 250px;
  65. margin-left: -125px;
  66. background-color: #333;
  67. color: #fff;
  68. text-align: center;
  69. border-radius: 2px;
  70. padding: 16px;
  71. position: fixed;
  72. z-index: 1;
  73. left: 50%;
  74. top: 50px;
  75. font-size: 17px;
  76. }
  77.  
  78. #snackbar.show {
  79. visibility: visible;
  80. -webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
  81. animation: fadein 0.5s, fadeout 0.5s 2.5s;
  82. }
  83.  
  84. @-webkit-keyframes fadein {
  85. from {top: 0; opacity: 0;}
  86. to {top: 50px; opacity: 1;}
  87. }
  88.  
  89. @keyframes fadein {
  90. from {top: 0; opacity: 0;}
  91. to {top: 50px; opacity: 1;}
  92. }
  93.  
  94. @-webkit-keyframes fadeout {
  95. from {top: 50px; opacity: 1;}
  96. to {top: 0; opacity: 0;}
  97. }
  98.  
  99. @keyframes fadeout {
  100. from {top: 50px; opacity: 1;}
  101. to {top: 0; opacity: 0;}
  102. }
  103. `);
  104. }
  105. return snackbar;
  106. }
  107.  
  108. function createButton(text) {
  109. let button = createElement(
  110. {
  111. name:"button",
  112. class:"com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-highlight",
  113. }
  114. );
  115. button.type = "button";
  116. button.title = text;
  117. let div = document.createElement('div');
  118. div.innerHTML=text;
  119. button.appendChild(div);
  120. return button;
  121. }
  122.  
  123. function createElement(info) {
  124. if(!info.name) return undefined;
  125. let element = document.createElement(info.name);
  126. if(info.innerHTML) element.innerHTML = info.innerHTML;
  127. if(info.class) {
  128. /*if(info.class.__proto__ == String.prototype) {
  129. element.classList.add(info.class);
  130. } else {
  131. for (let cls of info.class) {
  132. element.classList.add(cls);
  133. }
  134. }*/
  135. element.classList.add(info.class);
  136. }
  137. return element;
  138. }
  139.  
  140. function sleep (time) {
  141. return new Promise((resolve) => setTimeout(resolve, time));
  142. }
  143.  
  144. const observeDOM = (function () {
  145. let MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
  146. let eventListenerSupported = window.addEventListener;
  147.  
  148. return function (obj, onAddCallback, onRemoveCallback) {
  149. if (MutationObserver) {
  150. // define a new observer
  151. let mutationObserver = new MutationObserver(function (mutations, observer) {
  152. if (mutations[0].addedNodes.length && onAddCallback != undefined) {
  153. onAddCallback();
  154. }
  155. });
  156. // have the observer observe foo for changes in children
  157. mutationObserver.observe(obj, { attributes: true, childList: true, subtree: true });
  158. } else if (eventListenerSupported) {
  159. obj.addEventListener('DOMNodeInserted', onAddCallback, false);
  160. }
  161. };
  162. })();