GitHub Label Color Picker

A userscript that adds a color picker to the label color input

目前为 2021-02-21 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name GitHub Label Color Picker
  3. // @version 1.0.7
  4. // @description A userscript that adds a color picker to the label color input
  5. // @license MIT
  6. // @author Rob Garrison
  7. // @contributor darkred
  8. // @namespace https://github.com/Mottie
  9. // @include https://github.com/*
  10. // @run-at document-idle
  11. // @grant GM_addStyle
  12. // @grant GM_getValue
  13. // @grant GM_setValue
  14. // @grant GM_registerMenuCommand
  15. // @require https://greasyfork.org/scripts/23181-colorpicker/code/colorPicker.js?version=147862
  16. // @icon https://github.githubassets.com/pinned-octocat.svg
  17. // @supportURL https://github.com/Mottie/GitHub-userscripts/issues
  18. // ==/UserScript==
  19. /* global jsColorPicker */
  20. (() => {
  21. "use strict";
  22.  
  23. // GitHub-Dark changes "text-black" to #c0c0c0
  24. GM_addStyle(`
  25. div.cp-app { margin:0; z-index:10; }
  26. .js-new-label-color-icon { pointer-events:none; }
  27. .js-new-label-color-icon.text-black { color:#000 !important; }
  28. `);
  29.  
  30. function addPicker() {
  31. if ($(".js-new-label-color")) {
  32. jsColorPicker(".js-new-label-color-input", {
  33. customBG: "#222",
  34. noAlpha: true,
  35. renderCallback: function(colors) {
  36. let input = this && this.input;
  37. if (input) {
  38. updateSwatch(input, colors);
  39. }
  40. }
  41. });
  42. }
  43. }
  44.  
  45. function updateSwatch(input, colors) {
  46. let background = "#" + colors.HEX;
  47. input.value = background;
  48. let textColor = calcContrast(colors.HEX);
  49. // Update color swatch next to input
  50. let swatch = $(".js-new-label-color", input.closest("dd"));
  51. updateIcon(swatch, textColor);
  52. updateColors(swatch, background, textColor);
  53. // Update label preview
  54. swatch = $(
  55. ".js-label-preview .IssueLabel--big",
  56. input.closest(".table-list-item")
  57. );
  58. updateColors(swatch, background, textColor);
  59. }
  60.  
  61. function updateIcon(swatch, textColor) {
  62. let icon = $(".octicon", swatch);
  63. // !important set on these GitHub primer color definitions
  64. icon.classList.remove("text-white", "text-black");
  65. icon.classList.add("text-" + textColor);
  66. }
  67.  
  68. function updateColors(el, background, color) {
  69. el.style.backgroundColor = background;
  70. el.style.color = color;
  71. }
  72.  
  73. /* replace colorPicker storage */
  74. window.ColorPicker.docCookies = (key, val) => {
  75. if (typeof val === "undefined") {
  76. return GM_getValue(key);
  77. }
  78. GM_setValue(key, val);
  79. };
  80.  
  81. /* colorPickerMemosNoAlpha *MUST* follow this format
  82. "'rgba(83,25,231,1)','rgba(86,66,66,1)','rgba(22,20,223,1)'"
  83. */
  84. function convertColorsToRgba(values) {
  85. let result = [];
  86. // see http://stackoverflow.com/a/26196012/145346
  87. values
  88. .replace(/['"]/g, "")
  89. .split(/\s*,(?![^()]*(?:\([^()]*\))?\))\s*/g)
  90. .forEach(val => {
  91. let rgb = hexToRgb(val);
  92. if (rgb) {
  93. result.push(`'rgba(${rgb.r},${rgb.g},${rgb.b},1)'`);
  94. } else if (rgb === null && val.indexOf("rgba(") > -1) {
  95. // allow adding rgba() definitions
  96. result.push(`'${val}'`);
  97. }
  98. });
  99. return result.join(",");
  100. }
  101.  
  102. // Modified code from http://stackoverflow.com/a/5624139/145346
  103. function hexToRgb(hex) {
  104. let result,
  105. // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
  106. shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
  107. hex = hex.replace(shorthandRegex, (m, r, g, b) => {
  108. return r + r + g + g + b + b;
  109. });
  110. result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  111. return result ? {
  112. r: parseInt(result[1], 16),
  113. g: parseInt(result[2], 16),
  114. b: parseInt(result[3], 16)
  115. } : null;
  116. }
  117.  
  118. // Calculate contrasting text color for the given background color
  119. // https://24ways.org/2010/calculating-color-contrast/
  120. function calcContrast(hex) {
  121. const r = parseInt(hex.substr(0, 2), 16),
  122. g = parseInt(hex.substr(2, 2), 16),
  123. b = parseInt(hex.substr(4, 2), 16),
  124. yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
  125. return yiq >= 128 ? "black" : "white";
  126. }
  127.  
  128. function $(selector, el) {
  129. return (el || document).querySelector(selector);
  130. }
  131.  
  132. // Add GM options
  133. GM_registerMenuCommand(
  134. "Set label ColorPicker swatches (8 HEX or RGBA Max)",
  135. () => {
  136. const colors = GM_getValue("colorPickerMemosNoAlpha", "#000000,#ffffff"),
  137. val = prompt("Set label default colors (8 max):", colors);
  138. if (val !== null && typeof val === "string") {
  139. GM_setValue("colorPickerMemosNoAlpha", convertColorsToRgba(val));
  140. }
  141. }
  142. );
  143.  
  144. document.body.addEventListener("click", event => {
  145. // initialize if "Edit" or "New label" button clicked
  146. // because "Save changes" updates the entire item
  147. if (
  148. event.target && event.target.matches(".js-edit-label, .js-details-target")
  149. ) {
  150. addPicker();
  151. }
  152. });
  153. addPicker();
  154.  
  155. })();