{"action":"created","issue":{"url":"https://api.github.com/repos/cssstats/css-statistics/issues/42","labels_url":"https://api.github.com/repos/cssstats/css-statistics/issues/42/labels{/name}","comments_url":"https://api.github.com/repos/cssstats/css-statistics/issues/42/comments","events_url":"https://api.github.com/repos/cssstats/css-statistics/issues/42/events","html_url":"https://github.com/cssstats/css-statistics/pull/42","id":97774295,"number":42,"title":"V2","user":{"login":"jxnblk","id":3451712,"avatar_url":"https://avatars.githubusercontent.com/u/3451712?v=3","gravatar_id":"","url":"https://api.github.com/users/jxnblk","html_url":"https://github.com/jxnblk","followers_url":"https://api.github.com/users/jxnblk/followers","following_url":"https://api.github.com/users/jxnblk/following{/other_user}","gists_url":"https://api.github.com/users/jxnblk/gists{/gist_id}","starred_url":"https://api.github.com/users/jxnblk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jxnblk/subscriptions","organizations_url":"https://api.github.com/users/jxnblk/orgs","repos_url":"https://api.github.com/users/jxnblk/repos","events_url":"https://api.github.com/users/jxnblk/events{/privacy}","received_events_url":"https://api.github.com/users/jxnblk/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":17,"created_at":"2015-07-28T18:48:50Z","updated_at":"2015-07-29T20:52:30Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/cssstats/css-statistics/pulls/42","html_url":"https://github.com/cssstats/css-statistics/pull/42","diff_url":"https://github.com/cssstats/css-statistics/pull/42.diff","patch_url":"https://github.com/cssstats/css-statistics/pull/42.patch"},"body":"# v2\r\n\r\nThis is presented as a prototype for discussion. This doesn't have to be the actual v2, but I do like a lot of the things happening here. Would love some feedback and questions.\r\n\r\n### What\r\n\r\n- Smaller, simplified, and reorganized object\r\n- Reduce duplication with PostCSS functionality\r\n- Works as a postcss plugin\r\n- Remove stats that can be determined in the app/presentation layer\r\n- Lite option\r\n- Full property names are used as keys rather than camel casing\r\n- Uses [standard](https://www.npmjs.com/package/standard)\r\n- **New** Helper methods\r\n\r\n### New returned object\r\n\r\n```js\r\n// n = number\r\n// str = string\r\n// [] = array\r\n// prop = CSS property key\r\n\r\n{\r\n  size: n,\r\n  gzipSize: n,\r\n  rules: {\r\n    total: n,\r\n    size: {\r\n      graph: [n], // Array of numbers for each rule's size (e.g. number of declarations)\r\n      max: n,\r\n      average: n\r\n    }\r\n  },\r\n  selectors: {\r\n    total: n,\r\n    id: n,              // total number of id selectors\r\n    class: n,           // total number of class selectors\r\n    type: n,            // total number of type selectors (not currently implemented)\r\n    pseudoClass: n,     // total number of pseudo class selectors\r\n    psuedoElement: n,   // total number of pseudo element selectors\r\n    repeated: [str],    // array of repeated selectors\r\n    values: [str],      // array of all selectors\r\n    specificity: {\r\n      max: n\r\n      average: n\r\n    },\r\n    getSpecificityGraph(),\r\n    getRepeatedSelectors(),\r\n    getSortedSpecificity()\r\n  },\r\n  declarations: {\r\n    total: n,\r\n    important: n,       // total number of important declarations\r\n    vendorPrefix: n,    // total number of vendor prefixed declarations\r\n    properties:         // object for each unique property\r\n      prop: [str]       // array of values for each property\r\n    },\r\n    getPropertyResets(),\r\n    getUniquePropertyCount(),\r\n    getPropertyValueCount()\r\n  },\r\n  mediaQueries: {\r\n    total: n,\r\n    unique: n,\r\n    values: [str]       // array of values for media queries (e.g. '(min-width: 40em)')\r\n  }\r\n}\r\n```\r\n\r\n### To do\r\n\r\n- [ ] Implement lite option\r\n- [ ] Clean up unused modules and/or create new modules\r\n- [ ] Count type selectors\r\n- [ ] Update README\r\n- [x] Account for missing _reset_ declarations\r\n- [ ] Update/add new tests\r\n\r\n### Questions\r\n\r\n- Does this organizational scheme make sense?\r\n- Can/should we handle any shorthand property parsing at the presentation layer?\r\n- Is there anything else we'd want to parse for media queries?\r\n- How should the lite option be implemented? Should `opts` be passed to each module in `lib`? Or should the modules be split up further?\r\n\r\n### Usage examples\r\n\r\n**UPDATE**\r\nI've added some helper methods that make the examples below redundant.\r\n\r\n#### Get total number of unique colors\r\n\r\n```js\r\nvar _ = require('lodash')\r\nvar cssstats = require('cssstats')\r\n\r\nvar stats = cssstats(css)\r\n\r\nvar uniqueColorsCount = _.uniq(stats.declarations.properties.colors).length\r\n```\r\n\r\n#### `display: none` count\r\n\r\n```js\r\nvar displayNoneCount = stats.declarations.properties.display\r\n  .filter(function (val) {\r\n    return val === 'none'\r\n  })\r\n  .length\r\n```\r\n\r\n#### Find the selector with the highest specificity\r\n\r\n```js\r\nvar maxSpecificity = _.max(stats.selectors.specificity.graph)\r\nvar index = stats.selectors.specificity.graph.indexOf(maxSpecificity)\r\nvar maxSelector = stats.selectors.values[index]\r\n```\r\n\r\n#### Sort selectors by highest specificity\r\n\r\n```js\r\nvar ranked = _.zipWith(stats.selectors.values, stats.selectors.specificity.graph, function (a, b) {\r\n    return {\r\n      selector: a,\r\n      specificity: b\r\n    }\r\n  })\r\n  .sort(function (a, b) {\r\n    return b.specificity - a.specificity\r\n  })\r\n```\r\n\r\n#### Specificity graph\r\n\r\n```js\r\nvar graph = stats.selectors.specificity.graph\r\n```\r\n\r\n#### Rule size graph\r\n\r\n```js\r\nvar graph = stats.rules.size.graph\r\n```\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/cssstats/css-statistics/issues/comments/126092797","html_url":"https://github.com/cssstats/css-statistics/pull/42#issuecomment-126092797","issue_url":"https://api.github.com/repos/cssstats/css-statistics/issues/42","id":126092797,"user":{"login":"jxnblk","id":3451712,"avatar_url":"https://avatars.githubusercontent.com/u/3451712?v=3","gravatar_id":"","url":"https://api.github.com/users/jxnblk","html_url":"https://github.com/jxnblk","followers_url":"https://api.github.com/users/jxnblk/followers","following_url":"https://api.github.com/users/jxnblk/following{/other_user}","gists_url":"https://api.github.com/users/jxnblk/gists{/gist_id}","starred_url":"https://api.github.com/users/jxnblk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jxnblk/subscriptions","organizations_url":"https://api.github.com/users/jxnblk/orgs","repos_url":"https://api.github.com/users/jxnblk/repos","events_url":"https://api.github.com/users/jxnblk/events{/privacy}","received_events_url":"https://api.github.com/users/jxnblk/received_events","type":"User","site_admin":false},"created_at":"2015-07-29T20:52:29Z","updated_at":"2015-07-29T20:52:29Z","body":"I've added helper methods in, as well as options to include the results of relevant methods in the object for stringifying.\r\n\r\n@rafaelrinaldi @johnotander For important declarations, they now have an option `importantDeclarations` that will add an array of `!important` declarations with properties and values. For vendor prefixes, `declarations.getVendorPrefixed()` will return an array of declarations. Setting the `vendorPrefixedProperties` option will include that array in the results."}}