├── .gitignore ├── src ├── outro.js ├── css-rename │ ├── core.js │ ├── namespace.js │ ├── utils.js │ ├── dom.js │ └── tokenize.js ├── intro.js └── generate.js ├── lib └── config-all.json ├── sample ├── minified │ ├── map.js │ ├── style.css │ ├── test.html │ └── config.js ├── map.js ├── style.css ├── test.html └── config.js ├── grunt-tasks ├── config │ ├── stripdefine.js │ ├── generateinit.js │ ├── clean.js │ ├── copy.js │ ├── docker.js │ ├── uglify.js │ ├── class-id-minifier.js │ └── requirejs.js └── tasks │ ├── stripdefine.js │ ├── generateinit.js │ └── class-id-minifier.js ├── package.json ├── Gruntfile.js ├── LICENSE ├── README.md └── dist ├── css-rename.min.js ├── css-rename.min.js.map └── css-rename.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea -------------------------------------------------------------------------------- /src/outro.js: -------------------------------------------------------------------------------- 1 | 2 | return cssr; 3 | })); -------------------------------------------------------------------------------- /lib/config-all.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": [ 3 | "./css-rename/namespace" 4 | ] 5 | } -------------------------------------------------------------------------------- /sample/minified/map.js: -------------------------------------------------------------------------------- 1 | define(function () { 2 | return { 3 | "content-CTR": "a", 4 | "content-CNT": "b" 5 | }; 6 | }) -------------------------------------------------------------------------------- /grunt-tasks/config/stripdefine.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by marco on 10/01/2015. 3 | */ 4 | module.exports={ 5 | build: ['dist/css-rename.js'] 6 | }; -------------------------------------------------------------------------------- /sample/map.js: -------------------------------------------------------------------------------- 1 | define(function () { 2 | return { 3 | "content-CTR": "content-CTR", 4 | "content-CNT": "content-CNT" 5 | }; 6 | }) -------------------------------------------------------------------------------- /grunt-tasks/config/generateinit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by marco on 10/01/2015. 3 | */ 4 | module.exports ={ 5 | build: { 6 | src: ['tmp/js-init.js'] 7 | } 8 | } -------------------------------------------------------------------------------- /src/css-rename/core.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mgobbi on 15/10/2015. 3 | */ 4 | define(function () { 5 | var cssr = { 6 | CLASSES_MAP: {} 7 | }; 8 | return cssr; 9 | }); -------------------------------------------------------------------------------- /grunt-tasks/config/clean.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by marco on 10/01/2015. 3 | */ 4 | module.exports={ 5 | dist: ['dist'], 6 | postbuild: [ 7 | 'build', 8 | 'tmp' 9 | ] 10 | }; -------------------------------------------------------------------------------- /src/css-rename/namespace.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mgobbi on 15/10/2015. 3 | */ 4 | define(function (require) { 5 | var cssr = require("./core"); 6 | var _dom = require("./dom"); 7 | cssr.dom = _dom; 8 | }); -------------------------------------------------------------------------------- /src/intro.js: -------------------------------------------------------------------------------- 1 | (function (root, factory) { 2 | if (typeof define === 'function' && define.amd) { 3 | define("cssr",factory); 4 | } else { 5 | root.cssr = factory(); 6 | } 7 | }(this, function () { 8 | 'use strict'; 9 | -------------------------------------------------------------------------------- /sample/minified/style.css: -------------------------------------------------------------------------------- 1 | .a{ 2 | display: block; 3 | border: 1px #000 solid; 4 | width:100px; 5 | height:100px; 6 | } 7 | .a .b{ 8 | background: #ffcc00; 9 | width:100%; 10 | height:100%; 11 | } -------------------------------------------------------------------------------- /grunt-tasks/config/copy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by marco on 10/01/2015. 3 | */ 4 | module.exports={ 5 | build: { 6 | files: { 7 | 'dist/css-rename.js': 'build/src/js-build.js' 8 | } 9 | } 10 | }; -------------------------------------------------------------------------------- /sample/style.css: -------------------------------------------------------------------------------- 1 | .content-CTR{ 2 | display: block; 3 | border: 1px #000 solid; 4 | width:100px; 5 | height:100px; 6 | } 7 | .content-CTR .content-CNT{ 8 | background: #ffcc00; 9 | width:100%; 10 | height:100%; 11 | } -------------------------------------------------------------------------------- /grunt-tasks/config/docker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by marco on 11/01/2015. 3 | */ 4 | module.exports={ 5 | //options:{ 6 | // sidebarState: true, 7 | // colourScheme:"default" 8 | //}, 9 | app: { 10 | // Specify `src` and `dest` directly on the task object 11 | src: ['dist/robojs.js'], 12 | dest: '../gh-pages/RoboJS' 13 | } 14 | } -------------------------------------------------------------------------------- /sample/minified/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 9 | 10 |
11 |
1
12 |
13 |
14 |
2
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /grunt-tasks/config/uglify.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by marco on 10/01/2015. 3 | */ 4 | module.exports={ 5 | options: { 6 | compress: { 7 | drop_console: true 8 | }, 9 | sourceMap: true, 10 | stripbanners: true, 11 | banner: '<%= banner.compact %>', 12 | mangle: { 13 | except: ['cssr'] 14 | } 15 | }, 16 | dist: { 17 | src: ['dist/css-rename.js'], 18 | dest: 'dist/css-rename.min.js' 19 | } 20 | }; -------------------------------------------------------------------------------- /sample/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 9 | 10 |
11 |
1
12 |
13 |
14 |
2
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /sample/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mgobbi on 15/10/2015. 3 | */ 4 | require.config( 5 | { 6 | paths: { 7 | cssr: "../dist/css-rename" 8 | } 9 | } 10 | ); 11 | require(["./map", "cssr"], function (map, cssr) { 12 | cssr.CLASSES_MAP=map; 13 | var nodes = cssr.dom.querySelectorAll(".content-CTR > .content-CNT", document.body); 14 | console.log(nodes); 15 | var query = cssr.dom.getCssName("input[type=checkbox].content-CTR[data-foo] > .content-CNT:first-child"); 16 | console.log(query) 17 | }); -------------------------------------------------------------------------------- /grunt-tasks/tasks/stripdefine.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by marco on 10/01/2015. 3 | */ 4 | module.exports = function (grunt) { 5 | grunt.registerMultiTask('stripdefine', 'Strip define call from dist file', function () { 6 | this.filesSrc.forEach(function (filepath) { 7 | // Remove `define('js-init' ...)` and `define('js-build' ...)` 8 | var mod = grunt.file.read(filepath).replace(/define\("js-(init|build)", function\(\)\{\}\);/g, ''); 9 | 10 | 11 | grunt.file.write(filepath, mod); 12 | }); 13 | }); 14 | }; -------------------------------------------------------------------------------- /sample/minified/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mgobbi on 15/10/2015. 3 | */ 4 | require.config( 5 | { 6 | paths: { 7 | cssr: "../../dist/css-rename" 8 | } 9 | } 10 | ); 11 | require(["./map", "cssr"], function (map, cssr) { 12 | cssr.CLASSES_MAP=map; 13 | var nodes = cssr.dom.querySelectorAll(".content-CTR > .content-CNT", document.body); 14 | console.log(nodes); 15 | var query = cssr.dom.getCssName("input[type=checkbox].content-CTR[data-foo] > .content-CNT:first-child"); 16 | console.log(query) 17 | }); -------------------------------------------------------------------------------- /grunt-tasks/config/class-id-minifier.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mgobbi on 14/10/2015. 3 | */ 4 | 5 | module.exports={ 6 | 7 | sample: { 8 | options: { 9 | jsMapFile: 'sample/minified/map.js', 10 | jsMapDevFile: 'sample/map.js', 11 | jsWrapper:"define(function(){return {{code}};})" 12 | }, 13 | files: [ 14 | { 15 | expand: true, 16 | cwd: 'sample', 17 | src: '*.{html,css}', 18 | dest: 'sample/minified' 19 | } 20 | ] 21 | } 22 | }; -------------------------------------------------------------------------------- /grunt-tasks/tasks/generateinit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by marco on 10/01/2015. 3 | */ 4 | module.exports = function (grunt) { 5 | var modConfig = grunt.file.readJSON('lib/config-all.json'); 6 | grunt.registerMultiTask('generateinit', 'Generate Init file', function () { 7 | var requirejs = require('requirejs'); 8 | requirejs.config({ 9 | appDir:__dirname, 10 | baseUrl: __dirname 11 | }); 12 | var generateInit = requirejs('../../src/generate'); 13 | 14 | grunt.file.write('tmp/js-init.js', generateInit(modConfig)); 15 | }); 16 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-rename", 3 | "version": "0.0.2", 4 | "license": "MIT", 5 | "devDependencies": { 6 | "class-id-minifier": "git+https://github.com/marcog83/class-id-minifier.git", 7 | "glob": "^4.3.2", 8 | "grunt": "^0.4.5", 9 | "grunt-contrib-clean": "^0.6.0", 10 | "grunt-contrib-copy": "^0.7.0", 11 | "grunt-contrib-requirejs": "^0.4.4", 12 | "grunt-contrib-uglify": "^0.7.0", 13 | "grunt-docker": "0.0.9", 14 | "load-grunt-config": "^0.16.0", 15 | "path": "^0.11.14", 16 | "requirejs": "^2.1.15", 17 | "underscore": "^1.7.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/generate.js: -------------------------------------------------------------------------------- 1 | define(['underscore'], function( _ ) { 2 | return function( config ) { 3 | // Set some defaults 4 | if (!config) { 5 | config = {}; 6 | } 7 | config.options = config.options || []; 8 | config['modules'] = config['modules'] || []; 9 | 10 | 11 | 12 | var output = 'require(["./css-rename/core"'; 13 | 14 | 15 | 16 | // Load in all the detects 17 | _(config['modules']).forEach(function (detect) { 18 | output += ', "' + detect + '"'; 19 | }); 20 | 21 | output += '], function( cssr'; 22 | output += ') {\n' ; 23 | output += '});'; 24 | return output; 25 | }; 26 | }); 27 | -------------------------------------------------------------------------------- /src/css-rename/utils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by mgobbi on 15/10/2015. 3 | */ 4 | define(function (require) { 5 | var cssr = require("./core"); 6 | cssr.utils = { 7 | compose: function () { 8 | var fns = arguments; 9 | return function (result) { 10 | for (var i = fns.length - 1; i > -1; i--) { 11 | result = fns[i].call(this, result); 12 | } 13 | 14 | return result; 15 | }; 16 | }, 17 | once: function (fn) { 18 | var called = false, result; 19 | return function () { 20 | if (called) { 21 | return result; 22 | } 23 | called = true; 24 | result = fn.apply(this, arguments); 25 | return result; 26 | }; 27 | } 28 | }; 29 | return cssr 30 | 31 | }); -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by marco.gobbi on 09/01/2015. 3 | */ 4 | var path = require('path'); 5 | module.exports = function (grunt) { 6 | 7 | grunt.loadTasks('grunt-tasks/tasks'); 8 | require('load-grunt-config')(grunt, { 9 | // path to task.js files, defaults to grunt dir 10 | configPath: path.join(process.cwd(), 'grunt-tasks/config'), 11 | //can post process config object before it gets passed to grunt 12 | postProcess: function (config) { 13 | config.pkg = grunt.file.readJSON('package.json'); 14 | config.banner = { 15 | compact: '/*! <%= pkg.name %> <%= pkg.version %> (RoboJS Build) | <%= pkg.license %> */', 16 | full: '/** RoboJS full build **/' 17 | } 18 | } 19 | }); 20 | 21 | // Build 22 | grunt.registerTask('build', [ 23 | 'generateinit', 24 | 'requirejs', 25 | 'copy', 26 | 'clean:postbuild', 27 | 'stripdefine', 28 | //'docker:app', 29 | 'uglify' 30 | ]); 31 | }; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 marco gobbi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /grunt-tasks/config/requirejs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by marco on 10/01/2015. 3 | */ 4 | var cjsRequireRegExp = /(var\s+)*([^'"\s]*\s*=)*[^.\w]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)[^.\w]/g; 5 | var returnRegExp = /module.exports.*[^]*/; 6 | module.exports = { 7 | compile: { 8 | options: { 9 | dir: 'build', 10 | appDir: '.', 11 | baseUrl: 'src', 12 | optimize: 'none', 13 | optimizeCss: 'none', 14 | useStrict: true, 15 | paths: { 16 | 17 | lodash: "empty:", 18 | 19 | 20 | 21 | 'js-init': '../tmp/js-init' 22 | }, 23 | modules: [{ 24 | 'name': 'js-build', 25 | 'include': ['js-init'], 26 | 'create': true 27 | }], 28 | fileExclusionRegExp: /^(.git|node_modules|bower_components|grunt-tasks|dist|test|sample)$/, 29 | wrap: { 30 | startFile: "src/intro.js", 31 | endFile: "src/outro.js" 32 | }, 33 | onBuildWrite: function (id, path, contents) { 34 | if ((/define\(.*?\{/).test(contents)) { 35 | //Remove AMD ceremony for use without require.js or almond.js 36 | contents = contents.replace(/define\(.*?\{/, ''); 37 | 38 | contents = contents.replace(/\}\);\s*?$/, ''); 39 | //remove cjs style 40 | contents = contents.replace(cjsRequireRegExp, ""); 41 | 42 | //remove last return statement and trailing }) 43 | contents = contents.replace(/return.*[^return]*$/, ''); 44 | contents = contents.replace(returnRegExp, ''); 45 | } 46 | else if ((/require\([^\{]*?\{/).test(contents)) { 47 | contents = contents.replace(/require[^\{]+\{/, ''); 48 | contents = contents.replace(/\}\);\s*$/, ''); 49 | } 50 | 51 | return contents; 52 | } 53 | } 54 | } 55 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # css-rename 2 | a tool that allow you to rename css selector in your css files, html and javascript, in order to save some bytes in production 3 | 4 | #Usage 5 | As far as HTML and CSS minification, I use [yiminghe class-id-minifier](https://github.com/yiminghe/class-id-minifier) grunt module. 6 | It also creates a JS Object which maps extended selectors and minified ones. 7 | On top of this map, css-rename is able to convert selectors. 8 | 9 | let's say you have this original HTML markup 10 | 11 | ```html 12 |
13 |
1
14 |
15 |
16 |
2
17 |
18 | ``` 19 | 20 | that after the minification becomes 21 | 22 | ```html 23 |
24 |
1
25 |
26 |
27 |
2
28 |
29 | ``` 30 | 31 | in your javascript you need to query DOM. Well you can do it with original selectors and css-rename takes care of converting your query 32 | 33 | ```javascript 34 | var nodes = cssr.dom.querySelectorAll(".content-CTR > .content-CNT", document.body); // [div.b, div.b] 35 | ``` 36 | 37 | If you need just the query, not the DOM element, you can use getCssName function. For example to use it with jQuery 38 | 39 | ```javascript 40 | var query = cssr.dom.getCssName(".content-CTR > .content-CNT");//.a > .b 41 | 42 | $(query).doSomething(); 43 | ``` 44 | 45 | #Sample 46 | sample folder contains a demo app that minify CSS, HTML and creates a map of selectors. 47 | 48 | The grunt task that allow you to minify is `class-id-minifier` 49 | 50 | ```javascript 51 | module.exports={ 52 | 53 | sample: { 54 | options: { 55 | jsMapFile: 'sample/minified/map.js', 56 | jsMapDevFile: 'sample/map.js', 57 | jsWrapper:"define(function(){return {{code}};})" 58 | }, 59 | files: [ 60 | { 61 | expand: true, 62 | cwd: 'sample', 63 | src: '*.{html,css}', 64 | dest: 'sample/minified' 65 | } 66 | ] 67 | } 68 | }; 69 | ``` -------------------------------------------------------------------------------- /grunt-tasks/tasks/class-id-minifier.js: -------------------------------------------------------------------------------- 1 | /* 2 | * class-id-minifier 3 | * https://github.com/yiminghe/grunt-class-id-minifier 4 | * 5 | * Copyright (c) 2013 yiminghe 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | 'use strict'; 10 | 11 | module.exports = function (grunt) { 12 | var defaultEncoding = 'utf-8'; 13 | 14 | // Please see the Grunt documentation for more information regarding task 15 | // creation: http://gruntjs.com/creating-tasks 16 | 17 | var classIdMinifier = require('class-id-minifier'); 18 | 19 | function endsWith(str, suffix) { 20 | var ind = str.length - suffix.length; 21 | return ind >= 0 && str.indexOf(suffix, ind) == ind; 22 | } 23 | 24 | grunt.registerMultiTask('class-id-minifier', 'minify class and id from html', function () { 25 | // Merge task-specific and/or target-specific options with these defaults. 26 | var options = this.options(); 27 | 28 | var classIdMap = {}; 29 | 30 | var moduleName = options.moduleName; 31 | var jsWrapper = options.jsWrapper; 32 | var encoding = options.encoding || defaultEncoding; 33 | 34 | var css = []; 35 | 36 | // Iterate over all specified file groups. 37 | this.files.forEach(function (f) { 38 | var src = f.src[0]; 39 | var dest = f.dest; 40 | 41 | var srcContent = grunt.file.read(src, { 42 | encoding: encoding 43 | }); 44 | if (endsWith(src, '.css')) { 45 | css.push({ 46 | content: srcContent, 47 | dest: dest 48 | }); 49 | return; 50 | } 51 | var transformContent = classIdMinifier.minify(srcContent, classIdMap, options.minifyFilter); 52 | grunt.file.write(dest, transformContent.html, { 53 | encoding: encoding 54 | }); 55 | }); 56 | 57 | css.forEach(function (c) { 58 | grunt.file.write(c.dest, classIdMinifier.getCssCode(classIdMap, c.content), { 59 | encoding: encoding 60 | }); 61 | }); 62 | 63 | grunt.file.write(options.jsMapFile, 64 | classIdMinifier.getJsCode(classIdMap, moduleName, options.jsMapFilter,jsWrapper), { 65 | encoding: encoding 66 | }); 67 | 68 | grunt.file.write(options.jsMapDevFile, 69 | classIdMinifier.getDevJsCode(classIdMap, moduleName,jsWrapper), { 70 | encoding: encoding 71 | }); 72 | }); 73 | 74 | }; 75 | -------------------------------------------------------------------------------- /dist/css-rename.min.js: -------------------------------------------------------------------------------- 1 | /*! css-rename 0.0.2 (RoboJS Build) | MIT */ 2 | !function(a,b){"function"==typeof define&&define.amd?define("cssr",b):a.cssr=b()}(this,function(){"use strict";var cssr={CLASSES_MAP:{}},a=function(){var a={attrAliases:{"for":"htmlFor"},shorthand:{"\\#(-?[_a-z]+[-\\w]*)":"[id=$1]","\\.(-?[_a-z]+[-\\w]*)":"[class~=$1]"}},b={},c={tag:/^((?:-?[_a-z]+[\w-]*)|\*)/i,attributes:/^\[([a-z]+\w*)+([~\|\^\$\*!=]=?)?['"]?([^\]]*)['"]?\]*/i,pseudos:/^:([-\w]+)(?:\(['"]?(.+)['"]?\))*/i,combinator:/^\s*([>+~]|\s)\s*/},d=function(b){var c=a.attrAliases;b=b||[];for(var d=0,e=b.length;e>d;++d)c[b[d][0]]&&(b[d][0]=c[b[d][0]]),b[d][1]||(b[d][1]="");return b},e=function(a,c){return c=c||"",b[a+c]||(b[a+c]=new RegExp(a,c)),b[a+c]},f=function(b){var d=a.shorthand,f=b.match(c.attributes);f&&(b=b.replace(c.attributes,"REPLACED_ATTRIBUTE"));for(var g in d)b=b.replace(e(g,"gi"),d[g]);if(f)for(var h=0,i=f.length;i>h;++h)b=b.replace("REPLACED_ATTRIBUTE",f[h]);return b};return function(a){var b,e={},g=[],h=!1;a=f(a);do{h=!1;for(var i in c)"tag"!=i&&"combinator"!=i&&(e[i]=e[i]||[]),(b=c[i].exec(a))&&(h=!0,"tag"!=i&&"combinator"!=i?("attributes"===i&&"id"===b[1]&&(e.id=b[3]),e[i].push(b.slice(1))):e[i]=b[1],a=a.replace(b[0],""),"combinator"!==i&&a.length||(e.attributes=d(e.attributes),e.pseudos=e.pseudos||[],e.tag=e.tag||"*",g.push(e),e={previous:e}))}while(h);return g}}();cssr.utils={compose:function(){var a=arguments;return function(b){for(var c=a.length-1;c>-1;c--)b=a[c].call(this,b);return b}},once:function(a){var b,c=!1;return function(){return c?b:(c=!0,b=a.apply(this,arguments))}}};var b=function(){function b(b){return a(b).map(function(a){var b=a.attributes||[],e=a.pseudos||[],f=b.reduce(function(a,b){var c=d[b[0]]||d.attributes;return a+c(b)},"*"==a.tag?"":a.tag);f=e.reduce(function(a,b){var d=c[b[0]];return a+d(b)},f);var g=a.combinator?" "!=a.combinator?" "+a.combinator+" ":" ":"";return f+g}).join("")}var c={"nth-child":function(a){return":"+a[0]},"nth-last-child":function(a){return":"+a[0]},"nth-of-type":function(a){return":"+a[0]},"nth-last-of-type":function(a){return":"+a[0]},"first-child":function(a){return":"+a[0]},"last-child":function(a){return":"+a[0]},"first-of-type":function(a){return":"+a[0]},"last-of-type":function(a){return":"+a[0]},"only-child":function(a){return":"+a[0]},"only-of-type":function(a){return":"+a[0]},empty:function(a){return":"+a[0]},not:function(a){return":not("+a[1]+")"},checked:function(a){return":checked"}},d={id:function(a){var b=cssr.CLASSES_MAP[a[2]]||a[2];return"#"+b},"class":function(a){var b=cssr.CLASSES_MAP[a[2]]||a[2];return"."+b},attributes:function(a){return"["+a.join("")+"]"}};return{getCssName:b,querySelector:function(a,c){return c.querySelector(b(a))},querySelectorAll:function(a,c){return c.querySelectorAll(b(a))},getElementById:function(a,c){return c.getElementById(b(a))},getElementsByClassName:function(a,c){return c.getElementsByClassName(b(a))}}}();return cssr.dom=b,cssr}); 3 | //# sourceMappingURL=css-rename.min.js.map -------------------------------------------------------------------------------- /src/css-rename/dom.js: -------------------------------------------------------------------------------- 1 | define(function (require) { 2 | 3 | var tokenize = require("./tokenize"); 4 | var cssr = require("./utils"); 5 | 6 | var _dom = (function dom() { 7 | var pseudos = { 8 | 9 | 10 | 'nth-child': function (attr) { 11 | return ":" + attr[0]; 12 | }, 13 | 14 | 'nth-last-child': function (attr) { 15 | return ":" + attr[0]; 16 | }, 17 | 18 | 'nth-of-type': function (attr) { 19 | return ":" + attr[0]; 20 | }, 21 | 22 | 'nth-last-of-type': function (attr) { 23 | return ":" + attr[0]; 24 | }, 25 | 26 | 'first-child': function (attr) { 27 | return ":" + attr[0]; 28 | }, 29 | 30 | 'last-child': function (attr) { 31 | return ":" + attr[0]; 32 | }, 33 | 34 | 'first-of-type': function (attr) { 35 | return ":" + attr[0]; 36 | }, 37 | 38 | 'last-of-type': function (attr) { 39 | return ":" + attr[0]; 40 | }, 41 | 42 | 'only-child': function (attr) { 43 | return ":" + attr[0]; 44 | }, 45 | 46 | 'only-of-type': function (attr) { 47 | return ":" + attr[0]; 48 | }, 49 | 50 | 'empty': function (attr) { 51 | return ":" + attr[0]; 52 | }, 53 | 54 | 'not': function (attr) { 55 | return ":not(" + attr[1] + ")"; 56 | }, 57 | 58 | 59 | 'checked': function (node) { 60 | return ':checked'; 61 | } 62 | }; 63 | var starter = { 64 | id: function (attr) { 65 | var new_selector = cssr.CLASSES_MAP[attr[2]] || attr[2]; 66 | return "#" + new_selector; 67 | }, 68 | "class": function (attr) { 69 | var new_selector = cssr.CLASSES_MAP[attr[2]] || attr[2]; 70 | return "." + new_selector; 71 | }, 72 | attributes: function (attr) { 73 | return "[" + attr.join("") + "]"; 74 | } 75 | }; 76 | 77 | function getCssName(selector) { 78 | return tokenize(selector).map(function (item) { 79 | var attributes = item.attributes || []; 80 | var _pseudos = item.pseudos || []; 81 | var result = attributes.reduce(function (prev, attr) { 82 | var fn = starter[attr[0]] || starter.attributes; 83 | return prev + fn(attr); 84 | }, item.tag=="*"?"":item.tag); 85 | result = _pseudos.reduce(function (prev, pseudo) { 86 | var fn = pseudos[pseudo[0]]; 87 | return prev + fn(pseudo); 88 | }, result); 89 | var combinator = item.combinator ? (item.combinator != " " ? " " + item.combinator + " " : " ") : ""; 90 | return result + combinator; 91 | 92 | }).join(""); 93 | } 94 | 95 | 96 | return { 97 | getCssName: getCssName, 98 | querySelector: function (selector, node) { 99 | return node.querySelector(getCssName(selector)); 100 | }, 101 | querySelectorAll: function (selector, node) { 102 | return node.querySelectorAll(getCssName(selector)); 103 | }, 104 | getElementById: function (selector, node) { 105 | return node.getElementById(getCssName(selector)); 106 | }, 107 | getElementsByClassName: function (selector, node) { 108 | return node.getElementsByClassName(getCssName(selector)); 109 | } 110 | } 111 | })(); 112 | return _dom; 113 | }); -------------------------------------------------------------------------------- /dist/css-rename.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["css-rename.js"],"names":["root","factory","define","amd","cssr","this","CLASSES_MAP","tokenize","Selector","attrAliases","for","shorthand","\\#(-?[_a-z]+[-\\w]*)","\\.(-?[_a-z]+[-\\w]*)","regexCache","patterns","tag","attributes","pseudos","combinator","fixAttributes","attr","aliases","i","len","length","getRegExp","str","flags","RegExp","replaceShorthand","selector","attrs","match","replace","re","token","tokens","found","exec","id","push","slice","previous","utils","compose","fns","arguments","result","call","once","fn","called","apply","_dom","getCssName","map","item","_pseudos","reduce","prev","starter","pseudo","join","nth-child","nth-last-child","nth-of-type","nth-last-of-type","first-child","last-child","first-of-type","last-of-type","only-child","only-of-type","empty","not","checked","node","new_selector","class","querySelector","querySelectorAll","getElementById","getElementsByClassName","dom"],"mappings":"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","file":"css-rename.min.js"} -------------------------------------------------------------------------------- /src/css-rename/tokenize.js: -------------------------------------------------------------------------------- 1 | define(function () { 2 | var tokenize = function () { 3 | var Selector = { 4 | attrAliases: { 5 | 'for': 'htmlFor' 6 | }, 7 | shorthand: { 8 | //'(?:(?:[^\\)\\]\\s*>+~,]+)(?:-?[_a-z]+[-\\w]))+#(-?[_a-z]+[-\\w]*)': '[id=$1]', 9 | '\\#(-?[_a-z]+[-\\w]*)': '[id=$1]', 10 | '\\.(-?[_a-z]+[-\\w]*)': '[class~=$1]' 11 | } 12 | }; 13 | var foundCache = []; 14 | var parentCache = []; 15 | var regexCache = {}; 16 | var patterns = { 17 | tag: /^((?:-?[_a-z]+[\w-]*)|\*)/i, 18 | attributes: /^\[([a-z]+\w*)+([~\|\^\$\*!=]=?)?['"]?([^\]]*)['"]?\]*/i, 19 | pseudos: /^:([-\w]+)(?:\(['"]?(.+)['"]?\))*/i, 20 | combinator: /^\s*([>+~]|\s)\s*/ 21 | }; 22 | 23 | var fixAttributes = function (attr) { 24 | var aliases = Selector.attrAliases; 25 | attr = attr || []; 26 | for (var i = 0, len = attr.length; i < len; ++i) { 27 | if (aliases[attr[i][0]]) { // convert reserved words, etc 28 | attr[i][0] = aliases[attr[i][0]]; 29 | } 30 | if (!attr[i][1]) { // use exists operator 31 | attr[i][1] = ''; 32 | } 33 | } 34 | return attr; 35 | }; 36 | var getRegExp = function (str, flags) { 37 | flags = flags || ''; 38 | if (!regexCache[str + flags]) { 39 | regexCache[str + flags] = new RegExp(str, flags); 40 | } 41 | return regexCache[str + flags]; 42 | }; 43 | var replaceShorthand = function (selector) { 44 | var shorthand = Selector.shorthand; 45 | var attrs = selector.match(patterns.attributes); // pull attributes to avoid false pos on "." and "#" 46 | if (attrs) { 47 | selector = selector.replace(patterns.attributes, 'REPLACED_ATTRIBUTE'); 48 | } 49 | for (var re in shorthand) { 50 | selector = selector.replace(getRegExp(re, 'gi'), shorthand[re]); 51 | } 52 | 53 | if (attrs) { 54 | for (var i = 0, len = attrs.length; i < len; ++i) { 55 | selector = selector.replace('REPLACED_ATTRIBUTE', attrs[i]); 56 | } 57 | } 58 | return selector; 59 | }; 60 | return function (selector) { 61 | var token = {}, // one token per simple selector (left selector holds combinator) 62 | tokens = [], // array of tokens 63 | id, // unique id for the simple selector (if found) 64 | found = false, // whether or not any matches were found this pass 65 | match; // the regex match 66 | 67 | selector = replaceShorthand(selector); // convert ID and CLASS shortcuts to attributes 68 | 69 | /* 70 | Search for selector patterns, store, and strip them from the selector string 71 | until no patterns match (invalid selector) or we run out of chars. 72 | 73 | Multiple attributes and pseudos are allowed, in any order. 74 | for example: 75 | 'form:first-child[type=button]:not(button)[lang|=en]' 76 | */ 77 | do { 78 | found = false; // reset after full pass 79 | for (var re in patterns) { 80 | if (re != 'tag' && re != 'combinator') { // only one allowed 81 | token[re] = token[re] || []; 82 | } 83 | if (match = patterns[re].exec(selector)) { // note assignment 84 | found = true; 85 | if (re != 'tag' && re != 'combinator') { // only one allowed 86 | //token[re] = token[re] || []; 87 | 88 | // capture ID for fast path to element 89 | if (re === 'attributes' && match[1] === 'id') { 90 | token.id = match[3]; 91 | } 92 | 93 | token[re].push(match.slice(1)); 94 | } else { // single selector (tag, combinator) 95 | token[re] = match[1]; 96 | } 97 | selector = selector.replace(match[0], ''); // strip current match from selector 98 | if (re === 'combinator' || !selector.length) { // next token or done 99 | token.attributes = fixAttributes(token.attributes); 100 | token.pseudos = token.pseudos || []; 101 | token.tag = token.tag || '*'; 102 | tokens.push(token); 103 | 104 | token = { // prep next token 105 | previous: token 106 | }; 107 | } 108 | } 109 | } 110 | } while (found); 111 | 112 | return tokens; 113 | }; 114 | }(); 115 | return tokenize; 116 | }); -------------------------------------------------------------------------------- /dist/css-rename.js: -------------------------------------------------------------------------------- 1 | (function (root, factory) { 2 | if (typeof define === 'function' && define.amd) { 3 | define("cssr",factory); 4 | } else { 5 | root.cssr = factory(); 6 | } 7 | }(this, function () { 8 | 'use strict'; 9 | /** 10 | * Created by mgobbi on 15/10/2015. 11 | */ 12 | 13 | var cssr = { 14 | CLASSES_MAP: {} 15 | }; 16 | 17 | 18 | var tokenize = function () { 19 | var Selector = { 20 | attrAliases: { 21 | 'for': 'htmlFor' 22 | }, 23 | shorthand: { 24 | //'(?:(?:[^\\)\\]\\s*>+~,]+)(?:-?[_a-z]+[-\\w]))+#(-?[_a-z]+[-\\w]*)': '[id=$1]', 25 | '\\#(-?[_a-z]+[-\\w]*)': '[id=$1]', 26 | '\\.(-?[_a-z]+[-\\w]*)': '[class~=$1]' 27 | } 28 | }; 29 | var foundCache = []; 30 | var parentCache = []; 31 | var regexCache = {}; 32 | var patterns = { 33 | tag: /^((?:-?[_a-z]+[\w-]*)|\*)/i, 34 | attributes: /^\[([a-z]+\w*)+([~\|\^\$\*!=]=?)?['"]?([^\]]*)['"]?\]*/i, 35 | pseudos: /^:([-\w]+)(?:\(['"]?(.+)['"]?\))*/i, 36 | combinator: /^\s*([>+~]|\s)\s*/ 37 | }; 38 | 39 | var fixAttributes = function (attr) { 40 | var aliases = Selector.attrAliases; 41 | attr = attr || []; 42 | for (var i = 0, len = attr.length; i < len; ++i) { 43 | if (aliases[attr[i][0]]) { // convert reserved words, etc 44 | attr[i][0] = aliases[attr[i][0]]; 45 | } 46 | if (!attr[i][1]) { // use exists operator 47 | attr[i][1] = ''; 48 | } 49 | } 50 | return attr; 51 | }; 52 | var getRegExp = function (str, flags) { 53 | flags = flags || ''; 54 | if (!regexCache[str + flags]) { 55 | regexCache[str + flags] = new RegExp(str, flags); 56 | } 57 | return regexCache[str + flags]; 58 | }; 59 | var replaceShorthand = function (selector) { 60 | var shorthand = Selector.shorthand; 61 | var attrs = selector.match(patterns.attributes); // pull attributes to avoid false pos on "." and "#" 62 | if (attrs) { 63 | selector = selector.replace(patterns.attributes, 'REPLACED_ATTRIBUTE'); 64 | } 65 | for (var re in shorthand) { 66 | selector = selector.replace(getRegExp(re, 'gi'), shorthand[re]); 67 | } 68 | 69 | if (attrs) { 70 | for (var i = 0, len = attrs.length; i < len; ++i) { 71 | selector = selector.replace('REPLACED_ATTRIBUTE', attrs[i]); 72 | } 73 | } 74 | return selector; 75 | }; 76 | return function (selector) { 77 | var token = {}, // one token per simple selector (left selector holds combinator) 78 | tokens = [], // array of tokens 79 | id, // unique id for the simple selector (if found) 80 | found = false, // whether or not any matches were found this pass 81 | match; // the regex match 82 | 83 | selector = replaceShorthand(selector); // convert ID and CLASS shortcuts to attributes 84 | 85 | /* 86 | Search for selector patterns, store, and strip them from the selector string 87 | until no patterns match (invalid selector) or we run out of chars. 88 | 89 | Multiple attributes and pseudos are allowed, in any order. 90 | for example: 91 | 'form:first-child[type=button]:not(button)[lang|=en]' 92 | */ 93 | do { 94 | found = false; // reset after full pass 95 | for (var re in patterns) { 96 | if (re != 'tag' && re != 'combinator') { // only one allowed 97 | token[re] = token[re] || []; 98 | } 99 | if (match = patterns[re].exec(selector)) { // note assignment 100 | found = true; 101 | if (re != 'tag' && re != 'combinator') { // only one allowed 102 | //token[re] = token[re] || []; 103 | 104 | // capture ID for fast path to element 105 | if (re === 'attributes' && match[1] === 'id') { 106 | token.id = match[3]; 107 | } 108 | 109 | token[re].push(match.slice(1)); 110 | } else { // single selector (tag, combinator) 111 | token[re] = match[1]; 112 | } 113 | selector = selector.replace(match[0], ''); // strip current match from selector 114 | if (re === 'combinator' || !selector.length) { // next token or done 115 | token.attributes = fixAttributes(token.attributes); 116 | token.pseudos = token.pseudos || []; 117 | token.tag = token.tag || '*'; 118 | tokens.push(token); 119 | 120 | token = { // prep next token 121 | previous: token 122 | }; 123 | } 124 | } 125 | } 126 | } while (found); 127 | 128 | return tokens; 129 | }; 130 | }(); 131 | 132 | /** 133 | * Created by mgobbi on 15/10/2015. 134 | */ 135 | 136 | 137 | cssr.utils = { 138 | compose: function () { 139 | var fns = arguments; 140 | return function (result) { 141 | for (var i = fns.length - 1; i > -1; i--) { 142 | result = fns[i].call(this, result); 143 | } 144 | 145 | return result; 146 | }; 147 | }, 148 | once: function (fn) { 149 | var called = false, result; 150 | return function () { 151 | if (called) { 152 | return result; 153 | } 154 | called = true; 155 | result = fn.apply(this, arguments); 156 | return result; 157 | }; 158 | } 159 | }; 160 | 161 | 162 | 163 | 164 | 165 | 166 | var _dom = (function dom() { 167 | var pseudos = { 168 | 169 | 170 | 'nth-child': function (attr) { 171 | return ":" + attr[0]; 172 | }, 173 | 174 | 'nth-last-child': function (attr) { 175 | return ":" + attr[0]; 176 | }, 177 | 178 | 'nth-of-type': function (attr) { 179 | return ":" + attr[0]; 180 | }, 181 | 182 | 'nth-last-of-type': function (attr) { 183 | return ":" + attr[0]; 184 | }, 185 | 186 | 'first-child': function (attr) { 187 | return ":" + attr[0]; 188 | }, 189 | 190 | 'last-child': function (attr) { 191 | return ":" + attr[0]; 192 | }, 193 | 194 | 'first-of-type': function (attr) { 195 | return ":" + attr[0]; 196 | }, 197 | 198 | 'last-of-type': function (attr) { 199 | return ":" + attr[0]; 200 | }, 201 | 202 | 'only-child': function (attr) { 203 | return ":" + attr[0]; 204 | }, 205 | 206 | 'only-of-type': function (attr) { 207 | return ":" + attr[0]; 208 | }, 209 | 210 | 'empty': function (attr) { 211 | return ":" + attr[0]; 212 | }, 213 | 214 | 'not': function (attr) { 215 | return ":not(" + attr[1] + ")"; 216 | }, 217 | 218 | 219 | 'checked': function (node) { 220 | return ':checked'; 221 | } 222 | }; 223 | var starter = { 224 | id: function (attr) { 225 | var new_selector = cssr.CLASSES_MAP[attr[2]] || attr[2]; 226 | return "#" + new_selector; 227 | }, 228 | "class": function (attr) { 229 | var new_selector = cssr.CLASSES_MAP[attr[2]] || attr[2]; 230 | return "." + new_selector; 231 | }, 232 | attributes: function (attr) { 233 | return "[" + attr.join("") + "]"; 234 | } 235 | }; 236 | 237 | function getCssName(selector) { 238 | return tokenize(selector).map(function (item) { 239 | var attributes = item.attributes || []; 240 | var _pseudos = item.pseudos || []; 241 | var result = attributes.reduce(function (prev, attr) { 242 | var fn = starter[attr[0]] || starter.attributes; 243 | return prev + fn(attr); 244 | }, item.tag=="*"?"":item.tag); 245 | result = _pseudos.reduce(function (prev, pseudo) { 246 | var fn = pseudos[pseudo[0]]; 247 | return prev + fn(pseudo); 248 | }, result); 249 | var combinator = item.combinator ? (item.combinator != " " ? " " + item.combinator + " " : " ") : ""; 250 | return result + combinator; 251 | 252 | }).join(""); 253 | } 254 | 255 | 256 | return { 257 | getCssName: getCssName, 258 | querySelector: function (selector, node) { 259 | return node.querySelector(getCssName(selector)); 260 | }, 261 | querySelectorAll: function (selector, node) { 262 | return node.querySelectorAll(getCssName(selector)); 263 | }, 264 | getElementById: function (selector, node) { 265 | return node.getElementById(getCssName(selector)); 266 | }, 267 | getElementsByClassName: function (selector, node) { 268 | return node.getElementsByClassName(getCssName(selector)); 269 | } 270 | } 271 | })(); 272 | 273 | /** 274 | * Created by mgobbi on 15/10/2015. 275 | */ 276 | 277 | 278 | 279 | cssr.dom = _dom; 280 | 281 | 282 | ; 283 | 284 | 285 | 286 | 287 | 288 | return cssr; 289 | })); --------------------------------------------------------------------------------