No Description

gradient.js 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. (function() {
  2. var Gradient, OldValue, Value, isDirection, list, utils,
  3. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  4. hasProp = {}.hasOwnProperty;
  5. OldValue = require('../old-value');
  6. Value = require('../value');
  7. utils = require('../utils');
  8. list = require('postcss/lib/list');
  9. isDirection = /top|left|right|bottom/gi;
  10. Gradient = (function(superClass) {
  11. extend(Gradient, superClass);
  12. function Gradient() {
  13. return Gradient.__super__.constructor.apply(this, arguments);
  14. }
  15. Gradient.names = ['linear-gradient', 'repeating-linear-gradient', 'radial-gradient', 'repeating-radial-gradient'];
  16. Gradient.prototype.replace = function(string, prefix) {
  17. return list.space(string).map((function(_this) {
  18. return function(value) {
  19. var after, args, close, params;
  20. if (value.slice(0, +_this.name.length + 1 || 9e9) !== _this.name + '(') {
  21. return value;
  22. }
  23. close = value.lastIndexOf(')');
  24. after = value.slice(close + 1);
  25. args = value.slice(_this.name.length + 1, +(close - 1) + 1 || 9e9);
  26. params = list.comma(args);
  27. params = _this.newDirection(params);
  28. if (prefix === '-webkit- old') {
  29. return _this.oldWebkit(value, args, params, after);
  30. } else {
  31. _this.convertDirection(params);
  32. return prefix + _this.name + '(' + params.join(', ') + ')' + after;
  33. }
  34. };
  35. })(this)).join(' ');
  36. };
  37. Gradient.prototype.directions = {
  38. top: 'bottom',
  39. left: 'right',
  40. bottom: 'top',
  41. right: 'left'
  42. };
  43. Gradient.prototype.oldDirections = {
  44. 'top': 'left bottom, left top',
  45. 'left': 'right top, left top',
  46. 'bottom': 'left top, left bottom',
  47. 'right': 'left top, right top',
  48. 'top right': 'left bottom, right top',
  49. 'top left': 'right bottom, left top',
  50. 'right top': 'left bottom, right top',
  51. 'right bottom': 'left top, right bottom',
  52. 'bottom right': 'left top, right bottom',
  53. 'bottom left': 'right top, left bottom',
  54. 'left top': 'right bottom, left top',
  55. 'left bottom': 'right top, left bottom'
  56. };
  57. Gradient.prototype.newDirection = function(params) {
  58. var first, value;
  59. first = params[0];
  60. if (first.indexOf('to ') === -1 && isDirection.test(first)) {
  61. first = first.split(' ');
  62. first = (function() {
  63. var j, len, results;
  64. results = [];
  65. for (j = 0, len = first.length; j < len; j++) {
  66. value = first[j];
  67. results.push(this.directions[value.toLowerCase()] || value);
  68. }
  69. return results;
  70. }).call(this);
  71. params[0] = 'to ' + first.join(' ');
  72. }
  73. return params;
  74. };
  75. Gradient.prototype.oldWebkit = function(value, args, params, after) {
  76. if (args.indexOf('px') !== -1) {
  77. return value;
  78. }
  79. if (this.name !== 'linear-gradient') {
  80. return value;
  81. }
  82. if (params[0] && params[0].indexOf('deg') !== -1) {
  83. return value;
  84. }
  85. if (args.indexOf('-corner') !== -1) {
  86. return value;
  87. }
  88. if (args.indexOf('-side') !== -1) {
  89. return value;
  90. }
  91. params = this.oldDirection(params);
  92. params = this.colorStops(params);
  93. return '-webkit-gradient(linear, ' + params.join(', ') + ')' + after;
  94. };
  95. Gradient.prototype.convertDirection = function(params) {
  96. if (params.length > 0) {
  97. if (params[0].slice(0, 3) === 'to ') {
  98. return params[0] = this.fixDirection(params[0]);
  99. } else if (params[0].indexOf('deg') !== -1) {
  100. return params[0] = this.fixAngle(params[0]);
  101. } else if (params[0].indexOf(' at ') !== -1) {
  102. return this.fixRadial(params);
  103. }
  104. }
  105. };
  106. Gradient.prototype.fixDirection = function(param) {
  107. var value;
  108. param = param.split(' ');
  109. param.splice(0, 1);
  110. param = (function() {
  111. var j, len, results;
  112. results = [];
  113. for (j = 0, len = param.length; j < len; j++) {
  114. value = param[j];
  115. results.push(this.directions[value.toLowerCase()] || value);
  116. }
  117. return results;
  118. }).call(this);
  119. return param.join(' ');
  120. };
  121. Gradient.prototype.roundFloat = function(float, digits) {
  122. return parseFloat(float.toFixed(digits));
  123. };
  124. Gradient.prototype.fixAngle = function(param) {
  125. param = parseFloat(param);
  126. param = Math.abs(450 - param) % 360;
  127. param = this.roundFloat(param, 3);
  128. return param + "deg";
  129. };
  130. Gradient.prototype.oldDirection = function(params) {
  131. var direction;
  132. if (params.length === 0) {
  133. params;
  134. }
  135. if (params[0].indexOf('to ') !== -1) {
  136. direction = params[0].replace(/^to\s+/, '');
  137. direction = this.oldDirections[direction];
  138. params[0] = direction;
  139. return params;
  140. } else {
  141. direction = this.oldDirections.bottom;
  142. return [direction].concat(params);
  143. }
  144. };
  145. Gradient.prototype.colorStops = function(params) {
  146. return params.map(function(param, i) {
  147. var color, match, position, ref;
  148. if (i === 0) {
  149. return param;
  150. }
  151. ref = list.space(param), color = ref[0], position = ref[1];
  152. if (position == null) {
  153. match = param.match(/^(.*\))(\d.*)$/);
  154. if (match) {
  155. color = match[1];
  156. position = match[2];
  157. }
  158. }
  159. if (position && position.indexOf(')') !== -1) {
  160. color += ' ' + position;
  161. position = void 0;
  162. }
  163. if (i === 1 && (position === void 0 || position === '0%')) {
  164. return "from(" + color + ")";
  165. } else if (i === params.length - 1 && (position === void 0 || position === '100%')) {
  166. return "to(" + color + ")";
  167. } else if (position) {
  168. return "color-stop(" + position + ", " + color + ")";
  169. } else {
  170. return "color-stop(" + color + ")";
  171. }
  172. });
  173. };
  174. Gradient.prototype.fixRadial = function(params) {
  175. var first;
  176. first = params[0].split(/\s+at\s+/);
  177. return params.splice(0, 1, first[1], first[0]);
  178. };
  179. Gradient.prototype.old = function(prefix) {
  180. var regexp, string, type;
  181. if (prefix === '-webkit-') {
  182. type = this.name === 'linear-gradient' ? 'linear' : 'radial';
  183. string = '-gradient';
  184. regexp = utils.regexp("-webkit-(" + type + "-gradient|gradient\\(\\s*" + type + ")", false);
  185. return new OldValue(this.name, prefix + this.name, string, regexp);
  186. } else {
  187. return Gradient.__super__.old.apply(this, arguments);
  188. }
  189. };
  190. Gradient.prototype.add = function(decl, prefix) {
  191. var p;
  192. p = decl.prop;
  193. if (p.indexOf('mask') !== -1) {
  194. if (prefix === '-webkit-' || prefix === '-webkit- old') {
  195. return Gradient.__super__.add.apply(this, arguments);
  196. }
  197. } else if (p === 'list-style' || p === 'list-style-image' || p === 'content') {
  198. if (prefix === '-webkit-' || prefix === '-webkit- old') {
  199. return Gradient.__super__.add.apply(this, arguments);
  200. }
  201. } else {
  202. return Gradient.__super__.add.apply(this, arguments);
  203. }
  204. };
  205. Gradient.prototype.process = function(node, result) {
  206. var added;
  207. added = Gradient.__super__.process.apply(this, arguments);
  208. if (added && this.name === 'linear-gradient') {
  209. if (/\(\s*(top|left|right|bottom)/.test(node.value)) {
  210. result.warn('Gradient has outdated direction syntax. ' + 'New syntax is like "to left" instead of "right".', {
  211. node: node
  212. });
  213. }
  214. }
  215. return added;
  216. };
  217. return Gradient;
  218. })(Value);
  219. module.exports = Gradient;
  220. }).call(this);