Импорт/экспорт сниппетов в Chrome DevTools
В Google Chrome есть куртая функция - Сниппеты (Snippets). Находитя она в инструментах разработчика во вкладке Источник (Sources).
Коллекция полезных сниппетов: https://bgrins.github.io/devtools-snippets/
Дока по снипетам: https://developer.chrome.com/docs/devtools/
Экспорт/импорт сниппетов
В Google Chrome из коробки нет возможности синхронизации, экспорта и импорта имеющихся сниппетов. Однако экспортировать и импортировать сниппеты можно вручную, через консоль.
Как это сделать описано на этой странице. Ниже рассмотрим тот же подход, только в упрощенном варианте. Мне этот подход понравился больше, потому что он проще и работает как часы.
Шаг 1. Откроем DevTools программы DevTools
-
Нажмите
Ctrl + Shift + i
. -
Откройте меню в правом верхнем углу панели, затем выберите пункт Dock side: undock into separate window:
- На открывшейся панели DevTools снова нажмите
Ctrl + Shift + i
, теперь откроется панель DevTools программы DevTools.
Шаг 2. Экспорт (резервное копирование существующих сниппетов)
Вставьте и запустите этот код в Console
let exportSnippets InspectorFrontendHost.getPreferences( _ => { exportSnippets = JSON.parse( _.scriptSnippets ) } )
Теперь запустить этот код там же в Console, и он скопирует ВСЕ снипеты в буфер обмена вашей ОС в формате JSON:
copy( exportSnippets )
Шаг 3. Импорт (из кода в формате JSON)
let importSnippets = [ /* тут набор объектов ваших снипетов */ { ... }, { ... }, { ... }, ]; InspectorFrontendHost.setPreference( "scriptSnippets", JSON.stringify( importSnippets ) )
Набор полезных снипетов для импорта
[ { "id": "1", "name": "consoleSaveJSON", "content": "(function(console){\n\n console.save = function(data, filename){\n\n if(!data) {\n console.error('Console.save: No data')\n return;\n }\n\n if(!filename) filename = 'console.json'\n\n if(typeof data === \"object\"){\n data = JSON.stringify(data, undefined, 4)\n }\n\n var blob = new Blob([data], {type: 'text/json'}),\n e = document.createEvent('MouseEvents'),\n a = document.createElement('a')\n\n a.download = filename\n a.href = window.URL.createObjectURL(blob)\n a.dataset.downloadurl = ['text/json', a.download, a.href].join(':')\n e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)\n a.dispatchEvent(e)\n }\n})(console)" }, { "id": "2", "name": "cssPrettifier", "content": "// cssprettifier.js\n// https://github.com/bgrins/devtools-snippets\n// Unminify and prettify a CSS file.\n\n/*\n * cssprettifier-bookmarklet\n * Copyright (c) 2013 Addy Osmani, Sindre Sorhus\n * CSSBeautify (c) Sencha, Ariya Hidayat\n * Prism (c) Lea Verou\n * Licensed under the MIT license.\n */\n /*globals document:true*/\n(function () {\n 'use strict';\n\n if (document.body.childNodes.length !== 1) {\n console.log(\"CSS Prettify: This page doesn't appear to be a stylesheet. Make sure you run this on a css file\");\n return;\n }\n\n // cssbeautify\n (function(){\"use strict\";function a(a,b){function s(a){return\" \"===a||\"\\n\"===a||\" \"===a||\"\\r\"===a||\"\\f\"===a}function t(a){return\"'\"===a||'\"'===a}function u(a){return h>=\"a\"&&\"z\">=h||h>=\"A\"&&\"Z\">=h||h>=\"0\"&&\"9\">=h||\"-_*.:#\".indexOf(a)>=0}function v(){var a;for(a=m;a>0;a-=1)g+=c.indent}function w(){g=r(g),p?g+=\" {\":(g+=\"\\n\",v(),g+=\"{\"),\"\\n\"!==i&&(g+=\"\\n\"),m+=1}function x(){var a;m-=1,g=r(g),q&&(a=g.charAt(g.length-1),\";\"!==a&&\"{\"!==a&&(g+=\";\")),g+=\"\\n\",v(),g+=\"}\",f.push(g),g=\"\"}var c,f,h,i,j,k,l,m,n,o,r,d=0,e=a.length,g=\"\",p=!0,q=!1;for(c=arguments.length>1?b:{},c.indent===void 0&&(c.indent=\" \"),\"string\"==typeof c.openbrace&&(p=\"end-of-line\"===c.openbrace),\"boolean\"==typeof c.autosemicolon&&(q=c.autosemicolon),r=String.prototype.trimRight?function(a){return a.trimRight()}:function(a){return a.replace(/\\s+$/,\"\")},l={Start:0,AtRule:1,Block:2,Selector:3,Ruleset:4,Property:5,Separator:6,Expression:7,URL:8},m=0,k=l.Start,o=!1,f=[],a=a.replace(/\\r\\n/g,\"\\n\");e>d;)if(h=a.charAt(d),i=a.charAt(d+1),d+=1,t(n))g+=h,h===n&&(n=null),\"\\\\\"===h&&i===n&&(g+=i,d+=1);else if(t(h))g+=h,n=h;else if(o)g+=h,\"*\"===h&&\"/\"===i&&(o=!1,g+=i,d+=1);else if(\"/\"!==h||\"*\"!==i){if(k===l.Start){if(0===f.length&&s(h)&&0===g.length)continue;if(\" \">=h||h.charCodeAt(0)>=128){k=l.Start,g+=h;continue}if(u(h)||\"[\"===h||\"@\"===h){if(j=r(g),0===j.length)f.length>0&&(g=\"\\n\\n\");else if(\"}\"===j.charAt(j.length-1)||\";\"===j.charAt(j.length-1))g=j+\"\\n\\n\";else for(;;){if(i=g.charAt(g.length-1),\" \"!==i&&9!==i.charCodeAt(0))break;g=g.substr(0,g.length-1)}g+=h,k=\"@\"===h?l.AtRule:l.Selector;continue}}if(k!==l.AtRule)if(k!==l.Block)if(k!==l.Selector)if(k!==l.Ruleset)if(k!==l.Property)if(k!==l.Separator)if(k!==l.Expression)k===l.URL&&\")\"===h&&g.charAt(\"\\\\\"!==g.length-1)?(g+=h,k=l.Expression):g+=h;else{if(\"}\"===h){x(),k=l.Start,m>0&&(k=l.Block);continue}if(\";\"===h){g=r(g),g+=\";\\n\",k=l.Ruleset;continue}if(g+=h,\"(\"===h&&\"l\"===g.charAt(g.length-2)&&\"r\"===g.charAt(g.length-3)&&\"u\"===g.charAt(g.length-4)){k=l.URL;continue}}else{if(!s(h)){g+=h,k=l.Expression;continue}t(i)&&(k=l.Expression)}else{if(\":\"===h){g=r(g),g+=\": \",k=l.Expression,s(i)&&(k=l.Separator);continue}if(\"}\"===h){x(),k=l.Start,m>0&&(k=l.Block);continue}g+=h}else{if(\"}\"===h){x(),k=l.Start,m>0&&(k=l.Block);continue}if(\"\\n\"===h){g=r(g),g+=\"\\n\";continue}if(!s(h)){g=r(g),g+=\"\\n\",v(),g+=h,k=l.Property;continue}g+=h}else{if(\"{\"===h){w(),k=l.Ruleset;continue}if(\"}\"===h){x(),k=l.Start;continue}g+=h}else{if(u(h)){if(j=r(g),0===j.length)f.length>0&&(g=\"\\n\\n\");else if(\"}\"===j.charAt(j.length-1))g=j+\"\\n\\n\";else for(;;){if(i=g.charAt(g.length-1),\" \"!==i&&9!==i.charCodeAt(0))break;g=g.substr(0,g.length-1)}v(),g+=h,k=l.Selector;continue}if(\"}\"===h){x(),k=l.Start;continue}g+=h}else{if(\";\"===h){g+=h,k=l.Start;continue}if(\"{\"===h){j=r(g),w(),k=\"@font-face\"===j?l.Ruleset:l.Block;continue}g+=h}}else o=!0,g+=h,g+=i,d+=1;return g=f.join(\"\")+g}\"undefined\"!=typeof exports?module.exports=exports=a:\"object\"==typeof window&&(window.cssbeautify=a)})();\n // prism\n (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)}}},highlightAll:function(e,n){var r=document.querySelectorAll('code[class*=\"language-\"], [class*=\"language-\"] code, code[class*=\"lang-\"], [class*=\"lang-\"] code');for(var i=0,s;s=r[i++];)t.highlightElement(s,e===!0,n)},highlightElement:function(r,i,s){var o,u,a=r;while(a&&!e.test(a.className))a=a.parentNode;if(a){o=(a.className.match(e)||[,\"\"])[1];u=t.languages[o]}if(!u)return;r.className=r.className.replace(e,\"\").replace(/\\s+/g,\" \")+\" language-\"+o;a=r.parentNode;/pre/i.test(a.nodeName)&&(a.className=a.className.replace(e,\"\").replace(/\\s+/g,\" \")+\" language-\"+o);var f=r.textContent;if(!f)return;f=f.replace(/&/g,\"&\").replace(/</g,\"<\").replace(/>/g,\">\").replace(/\\u00a0/g,\" \");var l={element:r,language:o,grammar:u,code:f};t.hooks.run(\"before-highlight\",l);if(i&&self.Worker){var c=new Worker(t.filename);c.onmessage=function(e){l.highlightedCode=n.stringify(JSON.parse(e.data));l.element.innerHTML=l.highlightedCode;s&&s.call(l.element);t.hooks.run(\"after-highlight\",l)};c.postMessage(JSON.stringify({language:l.language,code:l.code}))}else{l.highlightedCode=t.highlight(l.code,l.grammar);l.element.innerHTML=l.highlightedCode;s&&s.call(r);t.hooks.run(\"after-highlight\",l)}},highlight:function(e,r){return n.stringify(t.tokenize(e,r))},tokenize:function(e,n){var r=t.Token,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.tokenize(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.Token=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:[\"token\",e.type],attributes:{}};r.type==\"comment\"&&(r.attributes.spellcheck=\"true\");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+\">\"};if(!self.document){self.addEventListener(\"message\",function(e){var n=JSON.parse(e.data),r=n.language,i=n.code;self.postMessage(JSON.stringify(t.tokenize(i,t.languages[r])));self.close()},!1);return}var r=document.getElementsByTagName(\"script\");r=r[r.length-1];if(r){t.filename=r.src;document.addEventListener&&!r.hasAttribute(\"data-manual\")&&document.addEventListener(\"DOMContentLoaded\",t.highlightAll)}})();;\n Prism.languages.css={comment:/\\/\\*[\\w\\W]*?\\*\\//g,atrule:/@[\\w-]+?(\\s+[^;{]+)?(?=\\s*{|\\s*;)/gi,url:/url\\(([\"']?).*?\\1\\)/gi,selector:/[^\\{\\}\\s][^\\{\\}]*(?=\\s*\\{)/g,property:/(\\b|\\B)[a-z-]+(?=\\s*:)/ig,string:/(\"|')(\\\\?.)*?\\1/g,important:/\\B!important\\b/gi,ignore:/&(lt|gt|amp);/gi,punctuation:/[\\{\\};:]/g};Prism.languages.markup&&Prism.languages.insertBefore(\"markup\",\"tag\",{style:{pattern:/(<|<)style[\\w\\W]*?(>|>)[\\w\\W]*?(<|<)\\/style(>|>)/ig,inside:{tag:{pattern:/(<|<)style[\\w\\W]*?(>|>)|(<|<)\\/style(>|>)/ig,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css}}});\n\n var prismStyle = document.createElement('style');\n var beautified = cssbeautify(document.body.textContent, {autosemicolon: true});\n var highlighted = Prism.highlight(beautified, Prism.languages.css);\n\n prismStyle.textContent = 'code[class*=\"language-\"],pre[class*=\"language-\"]{color:black;text-shadow:0 1px white;font-family:Consolas,Monaco,\\'Andale Mono\\',monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;}@media print{code[class*=\"language-\"],pre[class*=\"language-\"]{text-shadow:none;}}pre[class*=\"language-\"]{padding:1em;margin:.5em 0;overflow:auto;}:not(pre) > code[class*=\"language-\"],pre[class*=\"language-\"]{background:#f5f2f0;}:not(pre) > code[class*=\"language-\"]{padding:.1em;border-radius:.3em;}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:slategray;}.token.punctuation{color:#999;}.namespace{opacity:.7;}.token.property,.token.tag,.token.boolean,.token.number{color:#905;}.token.selector,.token.attr-name,.token.string{color:#690;}.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string{color:#a67f59;background:hsla(0,0%,100%,.5);}.token.atrule,.token.attr-value,.token.keyword{color:#07a;}.token.regex,.token.important{color:#e90;}.token.important{font-weight:bold;}.token.entity{cursor:help;}';\n\n document.head.innerHTML = '';\n document.head.appendChild(prismStyle);\n document.body.innerHTML = '<code><pre>' + highlighted + '</pre></code>';\n\n})();" }, { "id": "3", "name": "dataURL", "content": "// dataurl.js\n// https://github.com/bgrins/devtools-snippets\n// Print out data URLs for all images / canvases on the page.\n\n(function() {\n\n console.group(\"Data URLs\");\n\n [].forEach.call(document.querySelectorAll(\"img\"), function(i) {\n var c = document.createElement(\"canvas\");\n var ctx = c.getContext(\"2d\");\n c.width = i.width;\n c.height = i.height;\n\n try {\n ctx.drawImage(i, 0, 0);\n console.log(i, c.toDataURL());\n }\n catch(e) {\n console.log(i, \"No Permission - try opening this image in a new tab and running the snippet again?\", i.src);\n }\n });\n\n [].forEach.call(document.querySelectorAll(\"canvas\"), function(c) {\n try {\n console.log(c, c.toDataURL());\n }\n catch(e) {\n console.log(c, \"No Permission\");\n }\n });\n\n console.groupEnd(\"Data URLs\");\n\n})();" }, { "id": "4", "name": "formControls", "content": "// formcontrols.js\n// https://github.com/bgrins/devtools-snippets\n// Print out forms and their controls\n\n(function() {\n\n var forms = document.querySelectorAll(\"form\");\n\n for (var i = 0, len = forms.length; i < len; i++) {\n var tab = [ ];\n\n console.group(\"HTMLForm quot;\" + forms[i].name + \"quot;: \" + forms[i].action);\n console.log(\"Element:\", forms[i], \"\\nName: \"+forms[i].name+\"\\nMethod: \"+forms[i].method.toUpperCase()+\"\\nAction: \"+forms[i].action || \"null\");\n\n [\"input\", \"textarea\", \"select\"].forEach(function (control) {\n [].forEach.call(forms[i].querySelectorAll(control), function (node) {\n tab.push({\n \"Element\": node,\n \"Type\": node.type,\n \"Name\": node.name,\n \"Value\": node.value,\n \"Pretty Value\": (isNaN(node.value) || node.value === \"\" ? node.value : parseFloat(node.value))\n });\n });\n });\n\n console.table(tab);\n console.groupEnd();\n }\n})();" }, { "id": "5", "name": "insertCSS", "content": "// insert-css.js\n// https://github.com/bgrins/devtools-snippets\n// Injects a snippet of CSS into the current page.\n\nfunction insertCss(code) {\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (style.styleSheet) { // IE\n style.styleSheet.cssText = code;\n } else { // Other browsers\n style.innerHTML = code;\n }\n document.getElementsByTagName(\"head\")[0].appendChild( style );\n}\n\n// Feel free to extend this snippet with your favorite CSS snippets.\n// Here's an example which makes the current page high contrast.\n// Notice the trailing backslashes, used to define multiline strings.\nfunction insertCssHighContrast() {\n var css = '\\\n * { background: white ! important; color: black !important } \\\n :link, :link * { color: #0000EE !important } \\\n :visited, :visited * { color: #551A8B !important } \\\n ';\n insertCss(css);\n}" }, { "id": "7", "name": "log-globals", "content": "/*\n\tlog-globals\n\tby Sindre Sorhus\n\thttps://github.com/sindresorhus/log-globals\n\tMIT License\n*/\n(function () {\n\t'use strict';\n\n\tfunction getIframe() {\n\t\tvar el = document.createElement('iframe');\n\t\tel.style.display = 'none';\n\t\tdocument.body.appendChild(el);\n\t\tvar win = el.contentWindow;\n\t\tdocument.body.removeChild(el);\n\t\treturn win;\n\t}\n\n\tfunction detectGlobals() {\n\t\tvar iframe = getIframe();\n\t\tvar ret = Object.create(null);\n\n\t\tfor (var prop in window) {\n\t\t\tif (!(prop in iframe)) {\n\t\t\t\tret[prop] = window[prop];\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t}\n\n\tconsole.log(detectGlobals());\n})();" }, { "id": "8", "name": "plainForms", "content": "// plainforms.js\n// https://github.com/bgrins/devtools-snippets\n// Remove HTML5 form features (validations and special input types).\n//HTML5 Forms are great, but sometimes you don’t want the browser to validate \n//or present special controls for them. For instance, if you want to test server-side \n//validation of some fields, you do not want the browser to prevent invalid data for \n//that field type. This snippet finds all of the HTML5 input elements, sets their type \n//attributes to “text” (and keeps any values that were set), and removes any validations \n//enforced by the browser. Implementation by stroebjo.\n(function () {\n\n ['maxlength', 'required', 'min', 'max', 'pattern', 'step' ].forEach(function (attr) {\n [].forEach.call(document.querySelectorAll(\"[\" + attr + \"]\"), function (node) {\n node.removeAttribute(attr);\n });\n });\n\n ['tel', 'url', 'email', 'datetime', 'date', 'month', 'week', 'time', 'datetime-local', 'number', 'range', 'color'].forEach(function (type) {\n [].forEach.call(document.querySelectorAll(\"input[type=\" + type + \"]\"), function (node) {\n node.setAttribute('type', 'text');\n });\n });\n\n console.info(\"All HTML5 form validations have been removed.\");\n})();" }, { "id": "9", "name": "queryStringValues", "content": "// querystringvalues.js\n// https://github.com/bgrins/devtools-snippets\n// Print out key/value pairs from querystring.\n \n(function() {\n \n var url = location;\n var querystring = location.search.slice(1);\n var tab = querystring.split(\"&\").map(function(qs) {\n return { \"Key\": qs.split(\"=\")[0], \"Value\": qs.split(\"=\")[1], \"Pretty Value\": decodeURIComponent(qs.split(\"=\")[1]).replace(/\\+/g,\" \") }\n });\n \n console.group(\"Querystring Values\");\n console.log(\"URL: \"+url+\"\\nQS: \"+querystring);\n console.table(tab);\n console.groupEnd(\"Querystring Values\");\n \n})();" }, { "id": "10", "name": "showHeaders", "content": "// showheaders.js\n// https://github.com/bgrins/devtools-snippets\n// Print out response headers for current URL.\n \n(function() {\n \n var request=new XMLHttpRequest();\n request.open('HEAD',window.location,true);\n \n request.onload = request.onerror = function () {\n var headers = request.getAllResponseHeaders();\n var tab = headers.split(\"\\n\").map(function(h) {\n return { \"Key\": h.split(\": \")[0], \"Value\": h.split(\": \")[1] }\n }).filter(function(h) { return h.Value !== undefined; });\n \n console.group(\"Request Headers\");\n console.log(headers);\n console.table(tab);\n console.groupEnd(\"Request Headers\");\n };\n \n request.send(null);\n \n})();" }, { "id": "11", "name": "viewCookies", "content": "// viewcookies.js\n// https://github.com/bgrins/devtools-snippets\n// Shows all cookies stored in document.cookies in a console.table\n \n(function() {\n 'use strict';\n \n window.viewCookies = function() {\n if (document.cookie) {\n const cookies = document.cookie\n .split(/; ?/)\n .map(s => {\n const [ , key, value ] = s.match(/^(.*?)=(.*)$/);\n return {\n key,\n value: decodeURIComponent(value)\n };\n });\n \n console.table(cookies);\n }\n else {\n console.warn('document.cookie is empty!');\n }\n };\n})();\n \nwindow.viewCookies();" }, { "id": "13", "name": "allColors", "content": "// allcolors.js\n// https://github.com/bgrins/devtools-snippets\n// Print out CSS colors used in elements on the page.\n \n(function () {\n // Should include colors from elements that have a border color but have a zero width?\n var includeBorderColorsWithZeroWidth = false;\n \n var allColors = {};\n var props = [\"background-color\", \"color\", \"border-top-color\", \"border-right-color\", \"border-bottom-color\", \"border-left-color\"];\n var skipColors = {\n \"rgb(0, 0, 0)\": 1,\n \"rgba(0, 0, 0, 0)\": 1,\n \"rgb(255, 255, 255)\": 1\n };\n \n [].forEach.call(document.querySelectorAll(\"*\"), function (node) {\n var nodeColors = {};\n props.forEach(function (prop) {\n var color = window.getComputedStyle(node, null).getPropertyValue(prop),\n thisIsABorderProperty = (prop.indexOf(\"border\") != -1),\n notBorderZero = thisIsABorderProperty ? window.getComputedStyle(node, null).getPropertyValue(prop.replace(\"color\", \"width\")) !== \"0px\" : true,\n colorConditionsMet;\n \n if (includeBorderColorsWithZeroWidth) {\n colorConditionsMet = color && !skipColors[color];\n } else {\n colorConditionsMet = color && !skipColors[color] && notBorderZero;\n }\n \n if (colorConditionsMet) {\n if (!allColors[color]) {\n allColors[color] = {\n count: 0,\n nodes: []\n };\n }\n \n if (!nodeColors[color]) {\n allColors[color].count++;\n allColors[color].nodes.push(node);\n }\n \n nodeColors[color] = true;\n }\n });\n });\n \n function rgbTextToRgbArray(rgbText) {\n return rgbText.replace(/\\s/g, \"\").match(/\\d+,\\d+,\\d+/)[0].split(\",\").map(function(num) {\n return parseInt(num, 10);\n });\n }\n \n function componentToHex(c) {\n var hex = c.toString(16);\n return hex.length == 1 ? \"0\" + hex : hex;\n }\n \n function rgbToHex(rgbArray) {\n var r = rgbArray[0],\n g = rgbArray[1],\n b = rgbArray[2];\n return \"#\" + componentToHex(r) + componentToHex(g) + componentToHex(b);\n }\n \n var allColorsSorted = [];\n for (var i in allColors) {\n var rgbArray = rgbTextToRgbArray(i);\n var hexValue = rgbToHex(rgbArray);\n \n allColorsSorted.push({\n key: i,\n value: allColors[i],\n hexValue: hexValue\n });\n }\n \n allColorsSorted = allColorsSorted.sort(function (a, b) {\n return b.value.count - a.value.count;\n });\n \n var nameStyle = \"font-weight:normal;\";\n var countStyle = \"font-weight:bold;\";\n function colorStyle(color) {\n return \"background:\" + color + \";color:\" + color + \";border:1px solid #333;\";\n };\n \n console.group(\"Total colors used in elements on the page: \" + window.location.href + \" are \" + allColorsSorted.length);\n allColorsSorted.forEach(function (c) {\n console.groupCollapsed(\"%c %c \" + c.key + \" \" + c.hexValue + \" %c(\" + c.value.count + \" times)\",\n colorStyle(c.key), nameStyle, countStyle);\n c.value.nodes.forEach(function (node) {\n console.log(node);\n });\n console.groupEnd();\n });\n console.groupEnd(\"All colors used in elements on the page\");\n \n})();" } ]
--
Источнк: https://neotan.github.io/chrome-dev-tools-snippets/