csso-rails 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
  };