csso-rails 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -4,3 +4,6 @@
4
4
  *.rbc
5
5
  .yardoc
6
6
  Gemfile.lock
7
+ tmp
8
+ .DS_Store
9
+
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # csso-rails: Stylesheet Optimizer (CSSO) for Rails Asset pipeline
2
2
 
3
- Ruby adapter for [github.com/afelix/csso](https://github.com/afelix/csso).
3
+ Ruby adapter for [github.com/css/csso](https://github.com/css/csso).
4
4
 
5
5
  ## About
6
6
  CSSO does structure-optimization for CSS.
@@ -40,13 +40,14 @@ TRBL.prototype.impSum = function() {
40
40
 
41
41
  TRBL.prototype.add = function(name, sValue, tValue, imp) {
42
42
  var s = this.sides,
43
+ currentSide,
43
44
  i, x, side, a = [], last,
44
45
  imp = imp ? 1 : 0,
45
46
  wasUnary = false;
46
47
  if ((i = name.lastIndexOf('-')) !== -1) {
47
48
  side = name.substr(i + 1);
48
49
  if (side in s) {
49
- if (!s[side]) {
50
+ if (!(currentSide = s[side]) || (imp && !currentSide.imp)) {
50
51
  s[side] = { s: imp ? sValue.substring(0, sValue.length - 10) : sValue, t: [tValue[0]], imp: imp };
51
52
  if (tValue[0][1] === 'unary') s[side].t.push(tValue[1]);
52
53
  }
@@ -145,7 +146,7 @@ TRBL.prototype.getValue = function() {
145
146
  }
146
147
  r = r.concat(a[i].t);
147
148
 
148
- if (this.imp) r.push([{ s: '!important'}, 'important']);
149
+ if (this.impSum()) r.push([{ s: '!important'}, 'important']);
149
150
 
150
151
  return r;
151
152
  };
@@ -407,18 +408,21 @@ CSSOCompressor.prototype.process = function(rules, token, container, i, path) {
407
408
  };
408
409
 
409
410
  CSSOCompressor.prototype.compress = function(tree, ro) {
411
+ tree = tree || ['stylesheet'];
410
412
  this.init();
411
- this.info = typeof tree[0] !== 'string';
413
+ this.info = true;
412
414
 
413
- var x = this.info ? tree : this.injectInfo([tree])[0],
415
+ var x = (typeof tree[0] !== 'string') ? tree : this.injectInfo([tree])[0],
414
416
  l0, l1 = 100000000000, ls,
415
- x0, x1, xs;
417
+ x0, x1, xs,
418
+ protectedComment = this.findProtectedComment(tree);
416
419
 
417
420
  // compression without restructure
418
421
  x = this.walk(this.ccrules, x, '/0');
419
422
  x = this.walk(this.crules, x, '/0');
420
423
  x = this.walk(this.prules, x, '/0');
421
424
  x = this.walk(this.frrules, x, '/0');
425
+
422
426
  ls = translator.translate(cleanInfo(x)).length;
423
427
 
424
428
  if (!ro) { // restructure ON
@@ -442,7 +446,18 @@ CSSOCompressor.prototype.compress = function(tree, ro) {
442
446
 
443
447
  x = this.walk(this.frules, x, '/0');
444
448
 
445
- return this.info ? x : cleanInfo(x);
449
+ if (protectedComment) x.splice(2, 0, protectedComment);
450
+
451
+ return x;
452
+ };
453
+
454
+ CSSOCompressor.prototype.findProtectedComment = function(tree) {
455
+ var token;
456
+ for (var i = 2; i < tree.length; i++) {
457
+ token = tree[i];
458
+ if (token[1] === 'comment' && token[2].length > 0 && token[2].charAt(0) === '!') return token;
459
+ if (token[1] !== 's') return;
460
+ }
446
461
  };
447
462
 
448
463
  CSSOCompressor.prototype.injectInfo = function(token) {
@@ -487,6 +502,7 @@ CSSOCompressor.prototype.walk = function(rules, container, path) {
487
502
  for (var i = container.length - 1; i > -1; i--) {
488
503
  t = container[i];
489
504
  if (t && Array.isArray(t)) {
505
+ t[0].parent = container;
490
506
  if (this.isContainer(t)) t = this.walk(rules, t, path + '/' + i); // go inside
491
507
  if (t === null) container.splice(i, 1);
492
508
  else {
@@ -754,6 +770,12 @@ CSSOCompressor.prototype.compressNumber = function(token, rule, container, i) {
754
770
  return token;
755
771
  };
756
772
 
773
+ CSSOCompressor.prototype.findDeclaration = function(token) {
774
+ var parent = token;
775
+ while ((parent = parent[0].parent) && parent[1] !== 'declaration');
776
+ return parent;
777
+ };
778
+
757
779
  CSSOCompressor.prototype.cleanUnary = function(token, rule, container, i) {
758
780
  var next = container[i + 1];
759
781
  if (next && next[1] === 'number' && next[2] === '0') return null;
@@ -829,7 +851,15 @@ CSSOCompressor.prototype.compressFunctionColor = function(token) {
829
851
  };
830
852
 
831
853
  CSSOCompressor.prototype.compressDimension = function(token) {
832
- if (token[2][2] === '0') return token[2];
854
+ var declaration;
855
+ if (token[2][2] === '0') {
856
+ if (token[3][2] === 's' && (declaration = this.findDeclaration(token))) {
857
+ var declName = declaration[2][2][2];
858
+ if (declName === '-moz-transition') return; // https://github.com/css/csso/issues/82
859
+ if (declName === '-moz-animation' || declName === 'animation') return; // https://github.com/css/csso/issues/100
860
+ }
861
+ return token[2];
862
+ }
833
863
  };
834
864
 
835
865
  CSSOCompressor.prototype.compressString = function(token, rule, container) {
@@ -954,14 +984,13 @@ CSSOCompressor.prototype.markShorthands = function(token, rule, container, j, pa
954
984
  x[0].id = path + '/' + i;
955
985
  if (p in TRBL.props) {
956
986
  key = pre + TRBL.extractMain(p);
957
-
958
987
  var shorts = this.shorts2[key] || [];
959
988
  shortsI = shorts.length === 0 ? 0 : shorts.length - 1;
960
989
 
961
990
  if (!this.lastShortSelector || selector === this.lastShortSelector || shortGroupID === this.lastShortGroupID) {
962
991
  if (shorts.length) {
963
992
  sh = shorts[shortsI];
964
- if (imp && !sh.imp) sh.invalid = true;
993
+ //if (imp && !sh.imp) sh.invalid = true;
965
994
  createNew = false;
966
995
  }
967
996
  }
@@ -1077,9 +1106,11 @@ CSSOCompressor.prototype.buildPPre = function(pre, p, v, d, freeze) {
1077
1106
  0, // hsl
1078
1107
  0, // hsla
1079
1108
  0 // rgba
1080
- ];
1109
+ ],
1110
+ vID = '';
1081
1111
 
1082
1112
  for (var i = 0; i < _v.length; i++) {
1113
+ if (!vID) vID = this.getVendorIDFromToken(_v[i]);
1083
1114
  switch(_v[i][1]) {
1084
1115
  case 'vhash':
1085
1116
  case 'ident':
@@ -1099,7 +1130,38 @@ CSSOCompressor.prototype.buildPPre = function(pre, p, v, d, freeze) {
1099
1130
  }
1100
1131
  }
1101
1132
 
1102
- return fp + pre + p + colorMark.join('');
1133
+ return fp + pre + p + colorMark.join('') + (vID ? vID : '');
1134
+ };
1135
+
1136
+ CSSOCompressor.prototype.vendorID = {
1137
+ '-o-': 'o',
1138
+ '-moz-': 'm',
1139
+ '-webkit-': 'w',
1140
+ '-ms-': 'i',
1141
+ '-epub-': 'e',
1142
+ '-apple-': 'a',
1143
+ '-xv-': 'x',
1144
+ '-wap-': 'p'
1145
+ };
1146
+
1147
+ CSSOCompressor.prototype.getVendorIDFromToken = function(token) {
1148
+ var vID;
1149
+ switch(token[1]) {
1150
+ case 'ident':
1151
+ if (vID = this.getVendorFromString(token[2])) return this.vendorID[vID];
1152
+ break;
1153
+ case 'funktion':
1154
+ if (vID = this.getVendorFromString(token[2][2])) return this.vendorID[vID];
1155
+ break;
1156
+ }
1157
+ };
1158
+
1159
+ CSSOCompressor.prototype.getVendorFromString = function(string) {
1160
+ var vendor = string.charAt(0), i;
1161
+ if (vendor === '-') {
1162
+ if ((i = string.indexOf('-', 2)) !== -1) return string.substr(0, i + 1);
1163
+ }
1164
+ return '';
1103
1165
  };
1104
1166
 
1105
1167
  CSSOCompressor.prototype.deleteProperty = function(block, id) {
@@ -1159,17 +1221,13 @@ CSSOCompressor.prototype.needless = function(name, props, pre, imp, v, d, freeze
1159
1221
  name = name.substr(2);
1160
1222
  } else hack = '';
1161
1223
 
1162
- var vendor = name.charAt(0), i;
1163
- if (vendor === '-') {
1164
- if ((i = name.indexOf('-', 2)) !== -1) vendor = name.substr(0, i + 1);
1165
- } else vendor = '';
1166
-
1167
- var prop = name.substr(vendor.length),
1224
+ var vendor = this.getVendorFromString(name),
1225
+ prop = name.substr(vendor.length),
1168
1226
  x, t, ppre;
1169
1227
 
1170
1228
  if (prop in this.nlTable) {
1171
1229
  x = this.nlTable[prop];
1172
- for (i = 0; i < x.length; i++) {
1230
+ for (var i = 0; i < x.length; i++) {
1173
1231
  ppre = this.buildPPre(pre, hack + vendor + x[i], v, d, freeze);
1174
1232
  if (t = props[ppre]) return (!imp || t.imp);
1175
1233
  }
data/lib/csso/js/csso.js CHANGED
@@ -29,10 +29,10 @@ if (single && single.contains(['-v', '--version'])) {
29
29
  } else {
30
30
  src = fs.readFileSync(inFile).toString().trim();
31
31
 
32
- if (single.contains(['-dp', '--parser'])) csso.printTree(csso.cleanInfo(csso.parse(src, rule)));
32
+ if (single.contains(['-dp', '--parser'])) csso.printTree(csso.cleanInfo(csso.parse(src, rule, true)));
33
33
  else {
34
- if (!outFile) print(csso.justDoIt(src, ro));
35
- else fs.writeFileSync(outFile, csso.justDoIt(src, ro));
34
+ if (!outFile) print(csso.justDoIt(src, ro, true));
35
+ else fs.writeFileSync(outFile, csso.justDoIt(src, ro, true));
36
36
  }
37
37
  }
38
38
 
@@ -1,9 +1,11 @@
1
1
  var util = require('./util.js'),
2
- parser = require('./parser.js'),
2
+ gonzales = require('./gonzales.cssp.node.js'),
3
3
  translator = require('./translator.js'),
4
4
  compressor = require('./compressor.js');
5
5
 
6
- var parse = exports.parse = parser.parse;
6
+ var parse = exports.parse = function(s, rule, needInfo) {
7
+ return gonzales.srcToCSSP(s, rule, needInfo);
8
+ };
7
9
 
8
10
  var cleanInfo = exports.cleanInfo = util.cleanInfo;
9
11
 
@@ -15,6 +17,6 @@ var translate = exports.translate = translator.translate;
15
17
 
16
18
  var compress = exports.compress = compressor.compress;
17
19
 
18
- exports.justDoIt = function(src, ro) {
19
- return translate(cleanInfo(compress(parse(src, 'stylesheet'), ro)));
20
+ exports.justDoIt = function(src, ro, needInfo) {
21
+ return translate(cleanInfo(compress(parse(src, 'stylesheet', needInfo), ro)));
20
22
  };