Auto Replace Color with CSS Variable

try to take over the world

  1. // ==UserScript==
  2. // @name Auto Replace Color with CSS Variable
  3. // @namespace linghao.su
  4. // @version 0.6
  5. // @description try to take over the world
  6. // @author slh001@live.cn
  7. // @match https://www.figma.com/file/*/DCE-5-Prototype?*
  8. // @match https://www.figma.com/file/*/DCE-5_New?*
  9. // @match https://www.figma.com/file/*/%E9%A6%96%E9%A1%B5-Dashboar-%26-Login?*
  10. // @match https://www.sketch.com/s/*
  11. // @icon https://www.google.com/s2/favicons?sz=64&domain=figma.com
  12. // @license MIT
  13. // ==/UserScript==
  14.  
  15. const aliasUrl = 'https://cdn.jsdelivr.net/npm/@dao-style/core@0.7.1/dist/styles/color/alias.css';
  16. const varUrl = 'https://cdn.jsdelivr.net/npm/@dao-style/core@0.7.1/dist/styles/color/var.css';
  17.  
  18. const DELAY_MS = 500;
  19. const divTargetStr = 'selection_colors_panel--styleName--';
  20. const targetStr = 'colors_inspect_panel--paintColor';
  21.  
  22. const sketchDivTargetStr = 'ColorText';
  23. const sketchTargetStr = 'ColorText';
  24.  
  25.  
  26. const DAO_REPLACE_ATTR_KEY = 'DAO_REPLACE_ATTR_KEY';
  27. let lastLastTimeoutId = -1;
  28.  
  29. const cssMap = new Map();
  30.  
  31. async function init() {
  32. cssMap.clear();
  33. const handler = await fetch(varUrl);
  34. const cssStr = await handler.text();
  35.  
  36. const aliasHandler = await fetch(aliasUrl);
  37. const aliasStr = await aliasHandler.text();
  38.  
  39. const cssArr = cssStr.split('\n').map(item=>item.split(':').map(iitem => iitem.trim())).slice(1, -1).map(item => [item[1].slice(0, -1), item[0]]).filter(item => item[0].startsWith('#'));
  40. const aliasArr = aliasStr.split('\n').map(item=>item.split(':').map(iitem => iitem.trim())).slice(1, -1).map(item => [item[1].slice(0, -1), item[0]]).filter(item => item[0].startsWith('#'));
  41.  
  42. cssArr.forEach(item => cssMap.set(item[0].toUpperCase(), item[1]));
  43. aliasArr.forEach(item => cssMap.set(item[0].toUpperCase(), item[1]));
  44. }
  45.  
  46. function getSuitableTag(item) {
  47. while(item) {
  48. item = item.parentNode;
  49. if (!item.className || item.className.includes('selection_colors_panel--styleRow')) {
  50. return item;
  51. }
  52. }
  53. }
  54. function getTargetList() {
  55. const spanList = Array.from(document.querySelectorAll('span'));
  56. const divList = Array.from(document.querySelectorAll('div'));
  57.  
  58.  
  59. const targetSpanList = spanList.filter(item => item.className.includes(targetStr));
  60. const targetDivList = divList.filter(item => item.className.includes(divTargetStr));
  61.  
  62.  
  63. const sketchTargetSpanList = spanList.filter(item => item.className.includes(sketchDivTargetStr));
  64. const sketchTargetDivList = divList.filter(item => item.className.includes(sketchTargetStr));
  65.  
  66. const targetList = [...targetSpanList, ...targetDivList, ...sketchTargetSpanList, ...sketchTargetDivList]
  67.  
  68. targetList.forEach(item => {
  69. const innerText = item.innerText;
  70. const cssVariable = cssMap.get(innerText.toUpperCase());
  71. if (cssVariable) {
  72. item.innerHTML = `<div>${cssVariable}</div><div>${innerText}</div>`;
  73. item.setAttribute(DAO_REPLACE_ATTR_KEY, innerText);
  74. const eventBindingDom = getSuitableTag(item);
  75. if (eventBindingDom) {
  76. let fn = (e) => {
  77. setTimeout(() => {
  78. navigator.clipboard.writeText(e?.target?.getAttribute(DAO_REPLACE_ATTR_KEY) ?? cssVariable);
  79. }, DELAY_MS)
  80. }
  81. eventBindingDom.addEventListener('click', fn);
  82. }
  83.  
  84. }
  85. })
  86. lastLastTimeoutId = -1;
  87. }
  88.  
  89. (async function() {
  90. 'use strict';
  91.  
  92. await init();
  93. document.body.addEventListener('click', () => {
  94. if (lastLastTimeoutId !== -1) {
  95. clearTimeout(lastLastTimeoutId);
  96. lastLastTimeoutId = -1;
  97. }
  98. lastLastTimeoutId = setTimeout(getTargetList, DELAY_MS);
  99. })
  100. })();