Launchpad bug tags helper

LP bugs tags helper

目前为 2017-08-30 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Launchpad bug tags helper
  3. // @namespace https://launchpad.net/~julian-liu
  4. // @version 0.3
  5. // @description LP bugs tags helper
  6. // @author Julian Liu
  7. // @match https://bugs.launchpad.net/*/+filebug
  8. // @connect cedelivery.access.ly
  9. // @grant GM_xmlhttpRequest
  10. // ==/UserScript==
  11.  
  12. function interceptorSetup() {
  13. // override submit handling
  14. HTMLFormElement.prototype.real_submit = HTMLFormElement.prototype.submit;
  15. HTMLFormElement.prototype.submit = interceptor;
  16.  
  17. document.getElementById('filebug-form').addEventListener('submit', function(e) {
  18. // stop the form from submitting
  19. e.preventDefault();
  20.  
  21. interceptor(e);
  22. }, true);
  23. }
  24.  
  25. function interceptor(e) {
  26. var frm = e ? e.target : this;
  27.  
  28. tagNode = frm.elements['field.tags'];
  29.  
  30. if (tagNode.value.length === 0) {
  31. var check = confirm('No tags entered. Are you sure to submit this bug without any tag?');
  32. if (!check) {
  33. return;
  34. }
  35. }
  36. // submit default is prevented, so we add new submit node instead
  37. submitNode = document.createElement('input');
  38. submitNode.name = 'field.actions.submit_bug';
  39. submitNode.type = 'text';
  40. submitNode.value = 'Submit Bug Report';
  41. frm.appendChild(submitNode);
  42. HTMLFormElement.prototype.real_submit.apply(frm);
  43. }
  44.  
  45. function addTagStyle() {
  46. var menuStyle = `
  47. #wrap {
  48. width: 100px;
  49. height: 50px;
  50. padding-bottom: 10px;
  51. margin: 0; /* Ensures there is no space between sides of the screen and the menu */
  52. z-index: 1; /* Makes sure that your menu remains on top of other page elements */
  53. background-color: GhostWhite;
  54. }
  55. .navbar {
  56. height: 50px;
  57. padding: 0;
  58. padding-bottom: 10px;
  59. margin: 0;
  60. border-right: 1px solid #fafaff;
  61. z-index: 12;
  62. }
  63. .navbar li {
  64. padding-bottom: 10px;
  65. height: auto;
  66. width: 100px; /* Each menu item is 100px wide */
  67. /*float: left; This lines up the menu items horizontally */
  68. object-position: top;
  69. text-align: center; /* All text is placed in the center of the box */
  70. list-style: none; /* Removes the default styling (bullets) for the list */
  71. font: normal bold 12px/1.2em Arial, Verdana, Helvetica;
  72. padding: 0;
  73. margin: 0;
  74. background-color: GhostWhite;
  75. }
  76. .navbar a {
  77. padding: 18px 0; /* Adds a padding on the top and bottom so the text appears centered vertically */
  78. border-left: 1px solid #fafaff; /* Creates a border in a slightly lighter shade of blue than the background. Combined with the right border, this creates a nice effect. */
  79. border-right: 1px solid #fafaff; /* Creates a border in a slightly darker shade of blue than the background. Combined with the left border, this creates a nice effect. */
  80. text-decoration: none; /* Removes the default hyperlink styling. */
  81. color: #000; /* Text color is black */
  82. display: block;
  83. }
  84. .navbar li:hover, a:hover {
  85. background-color: #e5f3ff;
  86. }
  87. .navbar li ul {
  88. display: none; /* Hides the drop-down menu */
  89. margin: 0; /* Aligns drop-down box underneath the menu item */
  90. padding: 0; /* Aligns drop-down box underneath the menu item */
  91. margin-left: 100px;
  92. float:left;
  93. margin-top: -45px;
  94. height: 0;
  95. }
  96. .navbar li:hover ul {
  97. display: block; /* Displays the drop-down box when the menu item is hovered over */
  98. z-index: 12;
  99. padding-left: 1px;
  100. }
  101. .navbar li ul li {
  102. background-color: #e1e1e7;
  103. width: 150px;
  104. font: normal 12px/1.2em Arial, Verdana, Helvetica;
  105. }
  106. .navbar li ul li a {
  107. border-left: 1px solid #0026ff;
  108. border-right: 1px solid #0026ff;
  109. border-top: 1px solid #0026ff;
  110. z-index: 1001;
  111. }
  112. .navbar li ul li:hover {
  113. background-color: #d1d7e8;
  114. z-index: 1000;
  115. }
  116. .checkedmark:before {
  117. content: '✓';
  118. }
  119. `;
  120.  
  121. var css = document.createElement("style");
  122. css.type = "text/css";
  123. css.innerHTML = menuStyle;
  124. document.body.appendChild(css);
  125. }
  126.  
  127. function toggleTagValue(tag) {
  128. var tagNode = document.getElementById('filebug-form').elements['field.tags'];
  129. var liNode = document.getElementById('taglist.' + tag);
  130.  
  131. if (tagNode.value.indexOf(tag) !== -1) {
  132. tagNode.value = tagNode.value.replace(' ' + tag, '');
  133. tagNode.value = tagNode.value.replace(tag, '');
  134. liNode.className = '';
  135. }
  136. else {
  137. tagNode.value = tagNode.value + ' ' + tag;
  138. liNode.className = 'checkedmark';
  139. }
  140. }
  141.  
  142. function insertAfter(newNode, referenceNode) {
  143. referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
  144. }
  145.  
  146. function readExternalTags(url, callback) {
  147. GM_xmlhttpRequest({
  148. method: "GET",
  149. url: url,
  150. onload: function (response) {
  151. if (response.status == 200) {
  152. callback(response.responseText);
  153. }
  154. }
  155. });
  156. }
  157.  
  158. function tagList() {
  159. // ?q= to avoid cache
  160. var extTagUrl = 'https://cedelivery.access.ly/tag.json?q=';
  161. var pubTags = {
  162. ihv: ['ihv-amd', 'ihv-broadcom', 'ihv-intel', 'ihv-nvidia', 'ihv-realtek', 'ihv-related'],
  163. status: ['task', 'staging', 'waiting', 'cqa', 'cqa-verified']
  164. };
  165. var tagDiv = document.createElement('div');
  166. tagDiv.id = 'wrap';
  167. var ulLevel1 = document.createElement('ul');
  168. ulLevel1.className = 'navbar';
  169. ulLevel1.id = 'navbartop';
  170. tagDiv.appendChild(ulLevel1);
  171.  
  172. function appendCategory(tagData) {
  173. var topNode = document.getElementById('navbartop');
  174.  
  175. Object.keys(tagData).forEach(function(key, index) {
  176. var liCategory = document.createElement('li');
  177. topNode.appendChild(liCategory);
  178. liCategory.innerHTML = liCategory.innerHTML + key + ' →';
  179.  
  180. var ulLevel2 = document.createElement('ul');
  181. for (var i = 0; i < tagData[key].length; i++) {
  182. var liItem = document.createElement('li');
  183. ulLevel2.appendChild(liItem);
  184. liItem.innerHTML = liItem.innerHTML + tagData[key][i];
  185. liItem.id = 'taglist.' + tagData[key][i];
  186. (function(value){
  187. liItem.addEventListener("click", function() {
  188. toggleTagValue(value);
  189. }, false);})(tagData[key][i]);
  190. }
  191. liCategory.appendChild(ulLevel2);
  192. });
  193. }
  194.  
  195. document.getElementById('filebug-form').elements['field.tags'].size = '40';
  196.  
  197. var targetNode = document.getElementById('filebug-form').elements['field.tags'].parentNode.parentNode.parentNode;
  198. insertAfter(tagDiv, targetNode);
  199. appendCategory(pubTags);
  200. addTagStyle();
  201.  
  202. readExternalTags(extTagUrl, function(text){
  203. var data = JSON.parse(text);
  204. appendCategory(data);
  205. });
  206. }
  207.  
  208. (function() {
  209. 'use strict';
  210.  
  211. //debugger;
  212. tagList();
  213. interceptorSetup();
  214. })();