userstyles.org css highlighter

Formats and highlights CSS code shown after [Show CSS] clicking. (works with the new userstyles.org layout).

  1. // ==UserScript==
  2. // @name userstyles.org css highlighter
  3. // @namespace darkred
  4. // @version 2018.2.27
  5. // @description Formats and highlights CSS code shown after [Show CSS] clicking. (works with the new userstyles.org layout).
  6. // @author trespassersW
  7. // @contributor darkred
  8. // @license MIT
  9. //
  10. // @released 2013-11-20
  11. // @updated 2018-2-27
  12. //
  13. // 17.10.19 Modified by darkred to work in the new userstyles.org layout.
  14. // 16.08.28 + keeps highliting status between sessions; 16.08.28.1 - some instead of each
  15. // 2.1.1 2016-01-04 + ctrl-clik copies CSS code to clipboard
  16. // 2.0.1 cut extra empty lines
  17. // 2.0 dark grey background;
  18. // 1.3 icons for toggle button; tiny optimization
  19. // 1.1 fresh versions of formater/hiliter; switching butifying on/off; fixed </& issue
  20. //
  21. // @include http://userstyles.org/styles/*
  22. // @include https://userstyles.org/styles/*
  23. // @include http://web.archive.org/web/20170222172435/https://userstyles.org/styles/118959/darksearch-for-google
  24. // @grant GM.setClipboard
  25. // @require https://greatest.deepsurf.us/scripts/21927-arrive-js/code/arrivejs.js
  26. // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
  27. //
  28. // @supportURL https://github.com/darkred/Userscripts/issues
  29. // ==/UserScript==
  30.  
  31. /* globals Prism, cssbeautify */
  32.  
  33. document.arrive('#button_middle > .css_button', function() {
  34.  
  35.  
  36.  
  37. (function() {
  38. 'use strict';
  39.  
  40.  
  41. var Light = 0,
  42. Dark = 1;
  43. // choose color scheme according to your taste:
  44. var scheme = 1; // 0 for light; 1 for dark
  45.  
  46. //function _L(s){console.log(s);}
  47. var sb;
  48.  
  49. if (location.href.indexOf('s.org/styles/') < 0 ||
  50. !(sb = document.querySelector('#button_middle > .css_button'))
  51. ) { return; } // else alert();
  52.  
  53.  
  54.  
  55.  
  56. var bt, tc, sc, vc, highlighted;
  57. var hiId = '<!--userstyles.org css highlighter-->';
  58.  
  59. // CSSBeautify (C) 2013 Sencha Inc. Author: Ariya Hidayat.
  60. (function(){function a(s,f){var h,m=0,i=s.length,t,e='',p,g,q,k,o,y,u,d,r=true,j=false,n;h=arguments.length>1?f:{};if(typeof h.indent==='undefined'){h.indent=' ';}if(typeof h.openbrace==='string'){r=(h.openbrace==='end-of-line');}if(typeof h.autosemicolon==='boolean'){j=h.autosemicolon;}function l(z){return(z===' ')||(z==='\n')||(z==='\t')||(z==='\r')||(z==='\f');}function b(z){return(z==='\'')||(z==='"');}function c(z){return(p>='a'&&p<='z')||(p>='A'&&p<='Z')||(p>='0'&&p<='9')||'-_*.:#[]'.indexOf(z)>=0;}function x(){var z;for(z=y;z>0;z-=1){e+=h.indent;}}function w(){e=n(e);if(r){e+=' {';}else{e+='\n';x();e+='{';}if(g!=='\n'){e+='\n';}y+=1;}function v(){var z;y-=1;e=n(e);if(e.length>0&&j){z=e.charAt(e.length-1);if(z!==';'&&z!=='{'){e+=';';}}e+='\n';x();e+='}';t.push(e);e='';}if(String.prototype.trimRight){n=function(z){return z.trimRight();};}else{n=function(z){return z.replace(/\s+$/,'');};}o={Start:0,AtRule:1,Block:2,Selector:3,Ruleset:4,Property:5,Separator:6,Expression:7,URL:8};y=0;k=o.Start;d=false;t=[];s=s.replace(/\r\n/g,'\n');while(m<i){p=s.charAt(m);g=s.charAt(m+1);m+=1;if(b(u)){e+=p;if(p===u){u=null;}if(p==='\\'&&g===u){e+=g;m+=1;}continue;}if(b(p)){e+=p;u=p;continue;}if(d){e+=p;if(p==='*'&&g==='/'){d=false;e+=g;m+=1;}continue;}if(p==='/'&&g==='*'){d=true;e+=p;e+=g;m+=1;continue;}if(k===o.Start){if(t.length===0){if(l(p)&&e.length===0){continue;}}if(p<=' '||p.charCodeAt(0)>=128){k=o.Start;e+=p;continue;}if(c(p)||(p==='@')){q=n(e);if(q.length===0){if(t.length>0){e='\n\n';}}else{if(q.charAt(q.length-1)==='}'||q.charAt(q.length-1)===';'){e=q+'\n\n';}else{while(true){g=e.charAt(e.length-1);if(g!==' '&&g.charCodeAt(0)!==9){break;}e=e.substr(0,e.length-1);}}}e+=p;k=(p==='@')?o.AtRule:o.Selector;continue;}}if(k===o.AtRule){if(p===';'){e+=p;k=o.Start;continue;}if(p==='{'){q=n(e);w();k=(q==='@font-face')?o.Ruleset:o.Block;continue;}e+=p;continue;}if(k===o.Block){if(c(p)){q=n(e);if(q.length===0){if(t.length>0){e='\n\n';}}else{if(q.charAt(q.length-1)==='}'){e=q+'\n\n';}else{while(true){g=e.charAt(e.length-1);if(g!==' '&&g.charCodeAt(0)!==9){break;}e=e.substr(0,e.length-1);}}}x();e+=p;k=o.Selector;continue;}if(p==='}'){v();k=o.Start;continue;}e+=p;continue;}if(k===o.Selector){if(p==='{'){w();k=o.Ruleset;continue;}if(p==='}'){v();k=o.Start;continue;}e+=p;continue;}if(k===o.Ruleset){if(p==='}'){v();k=o.Start;if(y>0){k=o.Block;}continue;}if(p==='\n'){e=n(e);e+='\n';continue;}if(!l(p)){e=n(e);e+='\n';x();e+=p;k=o.Property;continue;}e+=p;continue;}if(k===o.Property){if(p===':'){e=n(e);e+=': ';k=o.Expression;if(l(g)){k=o.Separator;}continue;}if(p==='}'){v();k=o.Start;if(y>0){k=o.Block;}continue;}e+=p;continue;}if(k===o.Separator){if(!l(p)){e+=p;k=o.Expression;continue;}if(b(g)){k=o.Expression;}continue;}if(k===o.Expression){if(p==='}'){v();k=o.Start;if(y>0){k=o.Block;}continue;}if(p===';'){e=n(e);e+=';\n';k=o.Ruleset;continue;}e+=p;if(p==='('){if(e.charAt(e.length-2)==='l'&&e.charAt(e.length-3)==='r'&&e.charAt(e.length-4)==='u'){k=o.URL;continue;}}continue;}if(k===o.URL){if(p===')'&&e.charAt(e.length-1!=='\\')){e+=p;k=o.Expression;continue;}}e+=p;}e=t.join('')+e;return e;}if(typeof exports!=='undefined'){module.exports=exports=a;}else{if(typeof window==='object'){window.cssbeautify=a;}}}());
  61. // Prism (c) Lea Verou, MIT License
  62. (function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1];},clone:function(e){var n=t.util.type(e);switch(n){case'Object':var r={};for(var i in e){e.hasOwnProperty(i)&&(r[i]=t.util.clone(e[i]));}return r;case'Array':return e.slice();}return e;}},languages:{extend:function(e,n){var r=t.util.clone(t.languages[e]);for(var i in n){r[i]=n[i];}return r;},insertBefore:function(e,n,r,i){i=i||t.languages;var s=i[e],o={};for(var u in s){if(s.hasOwnProperty(u)){if(u==n){for(var a in r){r.hasOwnProperty(a)&&(o[a]=r[a]);}}o[u]=s[u];}}return i[e]=o;},DFS:function(e,n){for(var r in e){n.call(e,r,e[r]);t.util.type(e)==='Object'&&t.languages.DFS(e[r],n);}}},highlight:function(e,r){return n.stringify(t.tkize(e,r));},tkize:function(e,n){var r=t.tk,i=[e],s=n.rest;if(s){for(var o in s){n[o]=s[o];}delete n.rest;}e:for(var o in n){if(!n.hasOwnProperty(o)||!n[o]){continue;}var u=n[o],a=u.inside,f=!!u.lookbehind||0;u=u.pattern||u;for(var l=0;l<i.length;l++){var c=i[l];if(i.length>e.length){break e;}if(c instanceof r){continue;}u.lastIndex=0;var h=u.exec(c);if(h){f&&(f=h[1].length);var p=h.index-1+f,h=h[0].slice(f),d=h.length,v=p+d,m=c.slice(0,p+1),g=c.slice(v+1),y=[l,1];m&&y.push(m);var b=new r(o,a?t.tkize(h,a):h);y.push(b);g&&y.push(g);Array.prototype.splice.apply(i,y);}}}return i;},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[];r[e].push(n);},run:function(e,n){var r=t.hooks.all[e];if(!r||!r.length){return;}for(var i=0,s;s=r[i++];){s(n);}}}},n=t.tk=function(e,t){this.type=e;this.content=t;};n.stringify=function(e){if(typeof e==='string'){return e;}if(Object.prototype.toString.call(e)=='[object Array]'){return e.map(n.stringify).join('');}var r={type:e.type,content:n.stringify(e.content),tag:'span',classes:['tk',e.type],attributes:{}};t.hooks.run('wrap',r);var i='';for(var s in r.attributes){i+=s+'="'+(r.attributes[s]||'')+'"';}return'<'+r.tag+' class="'+r.classes.join(' ')+'" '+i+'>'+r.content+'</'+r.tag+'>';};})();
  63.  
  64. Prism.languages.css = {
  65. com: /\/\*[\w\W]*?\*\//g, // whose guilt?
  66. atr: /@[\w-]+?(\s+[^;{]+)?(?=\s*{|\s*;)/gi,
  67. url: /url\((["']?).*?\1\)/gi,
  68. sel: /[^{}\s][^{}]*(?=\s*\{)/g,
  69. pro: /(\b|\B)[a-z-]+(?=\s*:)/ig,
  70. str: /("|')(\\?.)*?\1/g,
  71. imp: /!important\b/gi,
  72. pun: /[{};:]/g
  73. };
  74.  
  75. /*
  76. .com comment, .atr at-rule, .sel selector, .imp !important,
  77. .pun punctuation, .url url, .str string
  78. */
  79. var prismCSS;
  80. if (scheme === Dark) {
  81. prismCSS = `
  82. .tk.com {
  83. color:#69A;
  84. }
  85. .tk.pun {
  86. color:#8FC;
  87. }
  88. .tk.pro {
  89. color:#5cf;
  90. }
  91. .tk.sel {
  92. color:#7F5;
  93. }
  94. .tk.str {
  95. color:#F63;
  96. }
  97. .tk.atr {
  98. color:#F8C;
  99. }
  100. .tk.imp {
  101. color:#e90;
  102. }
  103. .tk.url{
  104. color:#B87;
  105. }
  106. #css_text_area_div.hiBeautted {
  107. background-color:#293134 !important;
  108. color: #e0e2e4 !important;}
  109. `;
  110. } else {
  111. prismCSS = `
  112. .tk.com {
  113. color:slategray;
  114. }
  115. .tk.pun {
  116. color:#488;
  117. }
  118. .tk.pro {
  119. color:#05A;
  120. }
  121. .tk.sel {
  122. color:#470;
  123. }
  124. .tk.str {
  125. color:#E30;
  126. }
  127. .tk.atr {
  128. color:#905;
  129. }
  130. .tk.imp {
  131. color:#e90;
  132. /*font-weight:bold;*/
  133. }
  134. .tk.url{
  135. color:#a75;
  136. }
  137. `;}
  138.  
  139. prismCSS += `
  140. #css_text_area_div {
  141. padding: 1.2em .8em !important;
  142. }
  143. #css_text_area_div.hiBeautted {
  144. white-space: pre-wrap !important;
  145. word-wrap: break-word!important;
  146. }
  147. #hiBeauty:before{
  148. content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAACXBIWXMAAC4jAAAuIwF4pT92AAACjklEQVR42pXTz0/TYBgH8Nf/gaMJhoAXZzx7NhJviiZ6wmiWXRbRxBjjSYEQN8PPjbGxsWwgOjQYCVHWQoQM2IYDYbCta1e6tfvRTRMVjffnsW9HFkGzuMPnfd68ab79vk1KfD7fYrlcxv8lCAJWKhWUZVnfh8PhXwaD4TLxer2LqqoCRR88vv/zjFIUBXmeh0P6fmRkhCETExOsWiyAkt6jMC+k6gb962Xj4+MM8Xg8bCnowwNrh+6bpQOLyS1s5Loul4shbrebLc874EdPO4V0FncjDTVyOp0M0Wqx6pshOHh0nsLv2izurDceRGup2yH4/KJH042VQB+ostRQ0NjYWDVISb7H3LK5aqULC1kO0+5V5B0hnbS0W/cb6UF0KcSeQeXdOQrplOPLIN5dwOw9BjQouSN1GzkcjmqQEu3D0tvWGnlnCfnbcyga56vsa3UbjY6OMoSmybFhkAInKZRmTkGe24BE5ywmb7wGDWac63Ub6UF0kQoShDNrFEbFMJTUEixnshjkJdBgUslDWlAgFN2nMLol/R1kt9uZQHoazbvGmlUxhmciGTTEsrr7cRGHn+fwVndRd/NxDmWlVLuazWYLEvqf+FNe6Ny6TiGdH4QItK0ksC3EwekQh12bPDz15uDaQ4XCqw+ykJVLtUYDAwMsGRwcZNx7TrgSuUQhnUv8OjQHN7F5cRs0aI4m4IlTgvY7OQovmvePBFkslgXS39/PxpUdnOYmdQFuGvOlPHr2BLTFeV1oX8bIpwL65xTdq6CiBeghKEkSmkymIWK1WllRFIHjOEilUphMpuAQHptHzhOJJIUbGx9/NjU1nSVGo2nW73/5dWpqpiGTk4Evvb3WtZaW1guEkBO/ARQgDsZ2Sv7VAAAAAElFTkSuQmCC);
  149. opacity:.75;
  150. display: block;
  151. position: absolute;
  152. top: 0px;
  153. left: 33%;
  154. z-index: 1;
  155. }
  156. #hiBeauty.hiBeautted:before{
  157. content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAACXBIWXMAAC4jAAAuIwF4pT92AAACf0lEQVR42qWSW09aURCF9x9srJd6ARGqtf0nVUHkJreDtCrIRX/AjlFjQjUxISpXNdZ7DeC7rX1a0xm6TU6IjQ99+DIz+8xayVl7q06nox8eHoiBqb29fX5xRzxUu93WDJqNBj5NTeLjew8+TLgwOe6ExzEG9+gIXMNDcA4NwDHwFo16DbLfg1atVkszxMgBGey9fYbZ7e7beq3u7+81QxcXF9goFmmjWKD1Qh7r+TwVczkq5NaosJZFPpulfDaDXGaVcqsrtLayzH9RJ9GKh7q7u9MMzs7OsJxO4+vSEr6kUoyFtJXEUjKBVCKOVDwGKxZFMrrIRJBYjOD46AiiFQ91c3Ojb29viYGpvb19fnFHPNTV1ZW+vr7G4eEhpj3ubsgTHLBzaBDTbhfk22uIh+Js9OXlJTEwtbe3zy/uiIc6Pz/XDNVqNcmIOCOSjNKWRZwRcUYkGVnxGCX/ZkSNep1YA9EZtOKQNUOV42MYEzawOOQkG7BJPE5sAjahBAfNIVO1WiG5HNEZtGo2m/rk5AT/g3ioer2uGfpWKmHKPUGTrnHyOB1wj42Sa2SYnO8GyTHYj9H+PhrpeyOvXGIg1kB0Bq0qlYpmiEG1WiWDvbfP3fq8b6qgFV+7PuKHtb+/j0gwiHAwgFBgAaEFP4L+eQTmfQj4vFjweuH3zsE/N4v52Rn4Zj5jZ3sLohUPVS6XNUN7e3tImYAtvqVk95ZilOiGHAUHTXF+zbFImGLhEEXDIezsbJNoxUMdHBxohhiY2tvb53/taLW5uekrlUqPzE/mF/PE/H6FJ7MrmkfxUNlsdpcpZzKZU67fmR/ct7i2mY7A83OVs5bZkd1To939A6wgCBc2cNwFAAAAAElFTkSuQmCC);
  158. }
  159. #css_text_area_div {
  160. position: relative !important;
  161. }
  162. #hiBeauty {
  163. padding: 0;
  164. margin: 0;
  165. width: auto;
  166. cursor: pointer;
  167. border: none
  168. }
  169. `;
  170.  
  171. function hiStat(x) {
  172. vc.className = bt.className = x;
  173. bt.setAttribute('title', x ? 'raw text' : 'highlight');
  174. if (locStor) locStor.setItem('HiliteUsoCod', !!x);
  175. }
  176.  
  177. function isBeauty() {
  178. sc = document.getElementById('stylish-code');
  179. if (!sc || !(sc.textContent)) return -1;
  180. if (sc.innerHTML.substr(0, hiId.length) === hiId) {
  181. if (bt.className) {
  182. sc.innerHTML = '';
  183. sc.textContent = tc;
  184. hiStat('');
  185. } else hiStat('hiBeautted');
  186. return 1;
  187. }
  188. hiStat('');
  189. return 0;
  190. }
  191.  
  192. function hiBeauty(e) {
  193. sc = document.getElementById('stylish-code');
  194. if (e) {
  195. e.preventDefault(), e.stopPropagation();
  196. if (e.shiftKey || e.altKey) return;
  197. if (e.ctrlKey) { // 2016-01-04
  198. GM.setClipboard(sc.textContent);
  199. window.status = 'CSS copied to clipboard';
  200. return;
  201. }
  202. }
  203. if (isBeauty() !== 0) return;
  204. if (!(highlighted && tc && tc === sc.textContent)) {
  205. tc = sc.textContent;
  206. // console.log(tc);
  207. highlighted = cssbeautify(tc, {
  208. // autosemicolon: true ,
  209. // openbrace: "newline",
  210. indent: '\u0020\u0020' // 14-02-26 o_0
  211. // indent: " " // 14-02-26 o_0
  212. // indent: "\u00a0\u00a0"
  213. });
  214. // console.log(highlighted);
  215.  
  216. highlighted = highlighted.replace(/\n(\s*)@\s+/g, '\n$1@'); // 2014-03-12 dirty patch
  217. highlighted = highlighted.replace(/,\n\n+/g, ',\n'); // 2014-03-12 4freecyber
  218. highlighted = highlighted.replace(/\n\n+/g, '\n\n'); // 2014-02-25
  219. highlighted = highlighted.replace(/&/g, '&amp;').replace(/</g, '&lt;');
  220. highlighted = hiId +
  221. Prism.highlight(highlighted, Prism.languages.css) /* */ ;
  222. }
  223. // console.log(highlighted);
  224. sc.innerHTML = highlighted;
  225. hiStat('hiBeautted');
  226. }
  227.  
  228. /* * /
  229. function insAfter(n,e){
  230. if(e.nextElementSibling)
  231. return e.parentNode.insertBefore(n,e.nextElementSibling);
  232. return e.parentNode.appendChild(n);
  233. } /* */
  234.  
  235. function insBefore(n, e) {
  236. return e.parentNode.insertBefore(n, e);
  237. }
  238.  
  239. function cE(t, aA, eL, ht) {
  240. var n = document.createElement(t);
  241. for (var at in aA)
  242. if (aA.hasOwnProperty(at)) n.setAttribute(at, aA[at]);
  243. if (eL) n.addEventListener(eL[0], eL[1], eL[2] ? true : false);
  244. if (ht) n.innerHTML = ht;
  245. return n;
  246. }
  247.  
  248. function sbclik() {
  249.  
  250. if (document.querySelector('#stylish-code').outerHTML.indexOf('<textarea') !== -1) {
  251. document.querySelector('#stylish-code').outerHTML = document.querySelector('#stylish-code').outerHTML.replace('<textarea', '<code');
  252. document.querySelector('#stylish-code').style.whiteSpace = 'pre-wrap';
  253. document.querySelector('#stylish-code').style.display = 'block';
  254. document.querySelector('#stylish-code').style.width = '715px';
  255. document.querySelector('#stylish-code').style.overflowX = 'hidden';
  256. document.querySelector('#stylish-code').style.border = '1px';
  257. document.querySelector('#stylish-code').style.borderStyle = 'solid';
  258. document.querySelector('#stylish-code').style.borderColor = 'black';
  259. document.querySelector('#stylish-code').style.marginLeft = '-12px';
  260. }
  261.  
  262. if (!bt) {
  263. vc = document.getElementById('stylish-code');
  264. if (!vc) return;
  265. var pz = cE('style');
  266. pz.textContent = prismCSS;
  267. document.head.appendChild(pz);
  268. bt = cE('div', { id: 'hiBeauty', title: 'Highlight' }, ['click', hiBeauty], '');
  269. insBefore(bt, vc);
  270. }
  271. bt.className = '';
  272. //if(HiliteOn) alert('HiOn'),HiliteOn=0;
  273. }
  274.  
  275. sb.addEventListener('mousedown', sbclik, false);
  276.  
  277. var locStor, HiliteUsoCod = false;
  278. try { // localStorage throws 'security error' when cookies are disabled
  279. locStor = localStorage;
  280. HiliteUsoCod = locStor.getItem('HiliteUsoCod') === 'true';
  281. // see SQlite manager -> %FFpath%\webappstore.sqlite -> find -> key -> contains HiliteUso
  282. } catch (e) { locStor = false; }
  283.  
  284.  
  285.  
  286. document.arrive('#stylish-code', function() {
  287. var toggle = document.querySelector('#hiBeauty');
  288. if (toggle.title === 'Highlight' && localStorage.getItem('HiliteUsoCod') === 'true') {
  289. toggle.click();
  290. }
  291. });
  292.  
  293.  
  294. document.querySelector('.css_button').addEventListener('click', function() {
  295. if (document.querySelector('.css_button').firstChild.className === 'css_open') {
  296. document.querySelector('#stylish-code').style.display = 'none';
  297. document.querySelector('#hiBeauty').style.display = 'none';
  298. } else {
  299. document.querySelector('#stylish-code').style.display = 'block';
  300. document.querySelector('#hiBeauty').style.display = 'initial';
  301. }
  302. });
  303.  
  304.  
  305.  
  306.  
  307. })();
  308.  
  309.  
  310.  
  311. });