Импорт/экспорт сниппетов в Chrome DevTools

В Google Chrome есть куртая функция - Сниппеты (Snippets). Находитя она в инструментах разработчика во вкладке Источник (Sources).

Коллекция полезных сниппетов: https://bgrins.github.io/devtools-snippets/
Дока по снипетам: https://developer.chrome.com/docs/devtools/

Экспорт/импорт сниппетов

В Google Chrome из коробки нет возможности синхронизации, экспорта и импорта имеющихся сниппетов. Однако экспортировать и импортировать сниппеты можно вручную, через консоль.

Как это сделать описано на этой странице. Ниже рассмотрим тот же подход, только в упрощенном варианте. Мне этот подход понравился больше, потому что он проще и работает как часы.

Шаг 1. Откроем DevTools программы DevTools

  1. Нажмите Ctrl + Shift + i.

  2. Откройте меню в правом верхнем углу панели, затем выберите пункт Dock side: undock into separate window:

  3. На открывшейся панели 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/