break-up.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. var InvalidPropertyError = require('../invalid-property-error');
  2. var wrapSingle = require('../wrap-for-optimizing').single;
  3. var Token = require('../../tokenizer/token');
  4. var Marker = require('../../tokenizer/marker');
  5. var formatPosition = require('../../utils/format-position');
  6. function _anyIsInherit(values) {
  7. var i, l;
  8. for (i = 0, l = values.length; i < l; i++) {
  9. if (values[i][1] == 'inherit') {
  10. return true;
  11. }
  12. }
  13. return false;
  14. }
  15. function _colorFilter(validator) {
  16. return function(value) {
  17. return value[1] == 'invert' || validator.isColor(value[1]) || validator.isPrefixed(value[1]);
  18. };
  19. }
  20. function _styleFilter(validator) {
  21. return function(value) {
  22. return value[1] != 'inherit' && validator.isStyleKeyword(value[1]) && !validator.isColorFunction(value[1]);
  23. };
  24. }
  25. function _wrapDefault(name, property, configuration) {
  26. var descriptor = configuration[name];
  27. if (descriptor.doubleValues && descriptor.defaultValue.length == 2) {
  28. return wrapSingle([
  29. Token.PROPERTY,
  30. [Token.PROPERTY_NAME, name],
  31. [Token.PROPERTY_VALUE, descriptor.defaultValue[0]],
  32. [Token.PROPERTY_VALUE, descriptor.defaultValue[1]]
  33. ]);
  34. } if (descriptor.doubleValues && descriptor.defaultValue.length == 1) {
  35. return wrapSingle([
  36. Token.PROPERTY,
  37. [Token.PROPERTY_NAME, name],
  38. [Token.PROPERTY_VALUE, descriptor.defaultValue[0]]
  39. ]);
  40. }
  41. return wrapSingle([
  42. Token.PROPERTY,
  43. [Token.PROPERTY_NAME, name],
  44. [Token.PROPERTY_VALUE, descriptor.defaultValue]
  45. ]);
  46. }
  47. function _widthFilter(validator) {
  48. return function(value) {
  49. return value[1] != 'inherit'
  50. && (validator.isWidth(value[1]) || validator.isUnit(value[1]) || validator.isDynamicUnit(value[1]))
  51. && !validator.isStyleKeyword(value[1])
  52. && !validator.isColorFunction(value[1]);
  53. };
  54. }
  55. function animation(property, configuration, validator) {
  56. var duration = _wrapDefault(property.name + '-duration', property, configuration);
  57. var timing = _wrapDefault(property.name + '-timing-function', property, configuration);
  58. var delay = _wrapDefault(property.name + '-delay', property, configuration);
  59. var iteration = _wrapDefault(property.name + '-iteration-count', property, configuration);
  60. var direction = _wrapDefault(property.name + '-direction', property, configuration);
  61. var fill = _wrapDefault(property.name + '-fill-mode', property, configuration);
  62. var play = _wrapDefault(property.name + '-play-state', property, configuration);
  63. var name = _wrapDefault(property.name + '-name', property, configuration);
  64. var components = [duration, timing, delay, iteration, direction, fill, play, name];
  65. var values = property.value;
  66. var value;
  67. var durationSet = false;
  68. var timingSet = false;
  69. var delaySet = false;
  70. var iterationSet = false;
  71. var directionSet = false;
  72. var fillSet = false;
  73. var playSet = false;
  74. var nameSet = false;
  75. var i;
  76. var l;
  77. if (property.value.length == 1 && property.value[0][1] == 'inherit') {
  78. // eslint-disable-next-line max-len
  79. duration.value = timing.value = delay.value = iteration.value = direction.value = fill.value = play.value = name.value = property.value;
  80. return components;
  81. }
  82. if (values.length > 1 && _anyIsInherit(values)) {
  83. throw new InvalidPropertyError('Invalid animation values at ' + formatPosition(values[0][2][0]) + '. Ignoring.');
  84. }
  85. for (i = 0, l = values.length; i < l; i++) {
  86. value = values[i];
  87. if (validator.isTime(value[1]) && !durationSet) {
  88. duration.value = [value];
  89. durationSet = true;
  90. } else if (validator.isTime(value[1]) && !delaySet) {
  91. delay.value = [value];
  92. delaySet = true;
  93. } else if ((validator.isGlobal(value[1]) || validator.isTimingFunction(value[1])) && !timingSet) {
  94. timing.value = [value];
  95. timingSet = true;
  96. } else if ((validator.isAnimationIterationCountKeyword(value[1])
  97. || validator.isPositiveNumber(value[1]))
  98. && !iterationSet) {
  99. iteration.value = [value];
  100. iterationSet = true;
  101. } else if (validator.isAnimationDirectionKeyword(value[1]) && !directionSet) {
  102. direction.value = [value];
  103. directionSet = true;
  104. } else if (validator.isAnimationFillModeKeyword(value[1]) && !fillSet) {
  105. fill.value = [value];
  106. fillSet = true;
  107. } else if (validator.isAnimationPlayStateKeyword(value[1]) && !playSet) {
  108. play.value = [value];
  109. playSet = true;
  110. } else if ((validator.isAnimationNameKeyword(value[1]) || validator.isIdentifier(value[1])) && !nameSet) {
  111. name.value = [value];
  112. nameSet = true;
  113. } else {
  114. throw new InvalidPropertyError('Invalid animation value at ' + formatPosition(value[2][0]) + '. Ignoring.');
  115. }
  116. }
  117. return components;
  118. }
  119. function background(property, configuration, validator) {
  120. var image = _wrapDefault('background-image', property, configuration);
  121. var position = _wrapDefault('background-position', property, configuration);
  122. var size = _wrapDefault('background-size', property, configuration);
  123. var repeat = _wrapDefault('background-repeat', property, configuration);
  124. var attachment = _wrapDefault('background-attachment', property, configuration);
  125. var origin = _wrapDefault('background-origin', property, configuration);
  126. var clip = _wrapDefault('background-clip', property, configuration);
  127. var color = _wrapDefault('background-color', property, configuration);
  128. var components = [image, position, size, repeat, attachment, origin, clip, color];
  129. var values = property.value;
  130. var positionSet = false;
  131. var clipSet = false;
  132. var originSet = false;
  133. var repeatSet = false;
  134. var anyValueSet = false;
  135. if (property.value.length == 1 && property.value[0][1] == 'inherit') {
  136. // NOTE: 'inherit' is not a valid value for background-attachment
  137. color.value = image.value = repeat.value = position.value = size.value = origin.value = clip.value = property.value;
  138. return components;
  139. }
  140. if (property.value.length == 1 && property.value[0][1] == '0 0') {
  141. return components;
  142. }
  143. for (var i = values.length - 1; i >= 0; i--) {
  144. var value = values[i];
  145. if (validator.isBackgroundAttachmentKeyword(value[1])) {
  146. attachment.value = [value];
  147. anyValueSet = true;
  148. } else if (validator.isBackgroundClipKeyword(value[1]) || validator.isBackgroundOriginKeyword(value[1])) {
  149. if (clipSet) {
  150. origin.value = [value];
  151. originSet = true;
  152. } else {
  153. clip.value = [value];
  154. clipSet = true;
  155. }
  156. anyValueSet = true;
  157. } else if (validator.isBackgroundRepeatKeyword(value[1])) {
  158. if (repeatSet) {
  159. repeat.value.unshift(value);
  160. } else {
  161. repeat.value = [value];
  162. repeatSet = true;
  163. }
  164. anyValueSet = true;
  165. } else if (validator.isBackgroundPositionKeyword(value[1])
  166. || validator.isBackgroundSizeKeyword(value[1])
  167. || validator.isUnit(value[1])
  168. || validator.isDynamicUnit(value[1])) {
  169. if (i > 0) {
  170. var previousValue = values[i - 1];
  171. if (previousValue[1] == Marker.FORWARD_SLASH) {
  172. size.value = [value];
  173. } else if (i > 1 && values[i - 2][1] == Marker.FORWARD_SLASH) {
  174. size.value = [previousValue, value];
  175. i -= 2;
  176. } else {
  177. if (!positionSet) { position.value = []; }
  178. position.value.unshift(value);
  179. positionSet = true;
  180. }
  181. } else {
  182. if (!positionSet) { position.value = []; }
  183. position.value.unshift(value);
  184. positionSet = true;
  185. }
  186. anyValueSet = true;
  187. } else if ((color.value[0][1] == configuration[color.name].defaultValue || color.value[0][1] == 'none') && (validator.isColor(value[1]) || validator.isPrefixed(value[1]))) {
  188. color.value = [value];
  189. anyValueSet = true;
  190. } else if (validator.isUrl(value[1]) || validator.isFunction(value[1])) {
  191. image.value = [value];
  192. anyValueSet = true;
  193. }
  194. }
  195. if (clipSet && !originSet) { origin.value = clip.value.slice(0); }
  196. if (!anyValueSet) {
  197. throw new InvalidPropertyError('Invalid background value at ' + formatPosition(values[0][2][0]) + '. Ignoring.');
  198. }
  199. return components;
  200. }
  201. function borderRadius(property, configuration) {
  202. var values = property.value;
  203. var splitAt = -1;
  204. for (var i = 0, l = values.length; i < l; i++) {
  205. if (values[i][1] == Marker.FORWARD_SLASH) {
  206. splitAt = i;
  207. break;
  208. }
  209. }
  210. if (splitAt === 0 || splitAt === values.length - 1) {
  211. throw new InvalidPropertyError('Invalid border-radius value at ' + formatPosition(values[0][2][0]) + '. Ignoring.');
  212. }
  213. var target = _wrapDefault(property.name, property, configuration);
  214. target.value = splitAt > -1
  215. ? values.slice(0, splitAt)
  216. : values.slice(0);
  217. target.components = fourValues(target, configuration);
  218. var remainder = _wrapDefault(property.name, property, configuration);
  219. remainder.value = splitAt > -1
  220. ? values.slice(splitAt + 1)
  221. : values.slice(0);
  222. remainder.components = fourValues(remainder, configuration);
  223. for (var j = 0; j < 4; j++) {
  224. target.components[j].multiplex = true;
  225. target.components[j].value = target.components[j].value.concat(remainder.components[j].value);
  226. }
  227. return target.components;
  228. }
  229. function font(property, configuration, validator) {
  230. var style = _wrapDefault('font-style', property, configuration);
  231. var variant = _wrapDefault('font-variant', property, configuration);
  232. var weight = _wrapDefault('font-weight', property, configuration);
  233. var stretch = _wrapDefault('font-stretch', property, configuration);
  234. var size = _wrapDefault('font-size', property, configuration);
  235. var height = _wrapDefault('line-height', property, configuration);
  236. var family = _wrapDefault('font-family', property, configuration);
  237. var components = [style, variant, weight, stretch, size, height, family];
  238. var values = property.value;
  239. var fuzzyMatched = 4; // style, variant, weight, and stretch
  240. var index = 0;
  241. var isStretchSet = false;
  242. var isStretchValid;
  243. var isStyleSet = false;
  244. var isStyleValid;
  245. var isVariantSet = false;
  246. var isVariantValid;
  247. var isWeightSet = false;
  248. var isWeightValid;
  249. var appendableFamilyName = false;
  250. if (!values[index]) {
  251. throw new InvalidPropertyError('Missing font values at ' + formatPosition(property.all[property.position][1][2][0]) + '. Ignoring.');
  252. }
  253. if (values.length == 1 && values[0][1] == 'inherit') {
  254. style.value = variant.value = weight.value = stretch.value = size.value = height.value = family.value = values;
  255. return components;
  256. }
  257. if (values.length == 1
  258. && (validator.isFontKeyword(values[0][1])
  259. || validator.isGlobal(values[0][1])
  260. || validator.isPrefixed(values[0][1]))
  261. ) {
  262. values[0][1] = Marker.INTERNAL + values[0][1];
  263. style.value = variant.value = weight.value = stretch.value = size.value = height.value = family.value = values;
  264. return components;
  265. }
  266. if (values.length < 2 || !_anyIsFontSize(values, validator) || !_anyIsFontFamily(values, validator)) {
  267. throw new InvalidPropertyError('Invalid font values at ' + formatPosition(property.all[property.position][1][2][0]) + '. Ignoring.');
  268. }
  269. if (values.length > 1 && _anyIsInherit(values)) {
  270. throw new InvalidPropertyError('Invalid font values at ' + formatPosition(values[0][2][0]) + '. Ignoring.');
  271. }
  272. // fuzzy match style, variant, weight, and stretch on first elements
  273. while (index < fuzzyMatched) {
  274. isStretchValid = validator.isFontStretchKeyword(values[index][1]) || validator.isGlobal(values[index][1]);
  275. isStyleValid = validator.isFontStyleKeyword(values[index][1]) || validator.isGlobal(values[index][1]);
  276. isVariantValid = validator.isFontVariantKeyword(values[index][1]) || validator.isGlobal(values[index][1]);
  277. isWeightValid = validator.isFontWeightKeyword(values[index][1]) || validator.isGlobal(values[index][1]);
  278. if (isStyleValid && !isStyleSet) {
  279. style.value = [values[index]];
  280. isStyleSet = true;
  281. } else if (isVariantValid && !isVariantSet) {
  282. variant.value = [values[index]];
  283. isVariantSet = true;
  284. } else if (isWeightValid && !isWeightSet) {
  285. weight.value = [values[index]];
  286. isWeightSet = true;
  287. } else if (isStretchValid && !isStretchSet) {
  288. stretch.value = [values[index]];
  289. isStretchSet = true;
  290. } else if (isStyleValid
  291. && isStyleSet
  292. || isVariantValid
  293. && isVariantSet
  294. || isWeightValid
  295. && isWeightSet
  296. || isStretchValid
  297. && isStretchSet) {
  298. throw new InvalidPropertyError('Invalid font style / variant / weight / stretch value at ' + formatPosition(values[0][2][0]) + '. Ignoring.');
  299. } else {
  300. break;
  301. }
  302. index++;
  303. }
  304. // now comes font-size ...
  305. if (validator.isFontSizeKeyword(values[index][1])
  306. || validator.isUnit(values[index][1])
  307. && !validator.isDynamicUnit(values[index][1])) {
  308. size.value = [values[index]];
  309. index++;
  310. } else {
  311. throw new InvalidPropertyError('Missing font size at ' + formatPosition(values[0][2][0]) + '. Ignoring.');
  312. }
  313. if (!values[index]) {
  314. throw new InvalidPropertyError('Missing font family at ' + formatPosition(values[0][2][0]) + '. Ignoring.');
  315. }
  316. // ... and perhaps line-height
  317. if (values[index]
  318. && values[index][1] == Marker.FORWARD_SLASH
  319. && values[index + 1]
  320. && (validator.isLineHeightKeyword(values[index + 1][1])
  321. || validator.isUnit(values[index + 1][1])
  322. || validator.isNumber(values[index + 1][1]))) {
  323. height.value = [values[index + 1]];
  324. index++;
  325. index++;
  326. }
  327. // ... and whatever comes next is font-family
  328. family.value = [];
  329. while (values[index]) {
  330. if (values[index][1] == Marker.COMMA) {
  331. appendableFamilyName = false;
  332. } else {
  333. if (appendableFamilyName) {
  334. family.value[family.value.length - 1][1] += Marker.SPACE + values[index][1];
  335. } else {
  336. family.value.push(values[index]);
  337. }
  338. appendableFamilyName = true;
  339. }
  340. index++;
  341. }
  342. if (family.value.length === 0) {
  343. throw new InvalidPropertyError('Missing font family at ' + formatPosition(values[0][2][0]) + '. Ignoring.');
  344. }
  345. return components;
  346. }
  347. function _anyIsFontSize(values, validator) {
  348. var value;
  349. var i, l;
  350. for (i = 0, l = values.length; i < l; i++) {
  351. value = values[i];
  352. if (validator.isFontSizeKeyword(value[1])
  353. || validator.isUnit(value[1])
  354. && !validator.isDynamicUnit(value[1])
  355. || validator.isFunction(value[1])) {
  356. return true;
  357. }
  358. }
  359. return false;
  360. }
  361. function _anyIsFontFamily(values, validator) {
  362. var value;
  363. var i, l;
  364. for (i = 0, l = values.length; i < l; i++) {
  365. value = values[i];
  366. if (validator.isIdentifier(value[1]) || validator.isQuotedText(value[1])) {
  367. return true;
  368. }
  369. }
  370. return false;
  371. }
  372. function fourValues(property, configuration) {
  373. var componentNames = configuration[property.name].components;
  374. var components = [];
  375. var value = property.value;
  376. if (value.length < 1) { return []; }
  377. if (value.length < 2) { value[1] = value[0].slice(0); }
  378. if (value.length < 3) { value[2] = value[0].slice(0); }
  379. if (value.length < 4) { value[3] = value[1].slice(0); }
  380. for (var i = componentNames.length - 1; i >= 0; i--) {
  381. var component = wrapSingle([
  382. Token.PROPERTY,
  383. [Token.PROPERTY_NAME, componentNames[i]]
  384. ]);
  385. component.value = [value[i]];
  386. components.unshift(component);
  387. }
  388. return components;
  389. }
  390. function multiplex(splitWith) {
  391. return function(property, configuration, validator) {
  392. var splitsAt = [];
  393. var values = property.value;
  394. var i, j, l, m;
  395. // find split commas
  396. for (i = 0, l = values.length; i < l; i++) {
  397. if (values[i][1] == ',') { splitsAt.push(i); }
  398. }
  399. if (splitsAt.length === 0) { return splitWith(property, configuration, validator); }
  400. var splitComponents = [];
  401. // split over commas, and into components
  402. for (i = 0, l = splitsAt.length; i <= l; i++) {
  403. var from = i === 0 ? 0 : splitsAt[i - 1] + 1;
  404. var to = i < l ? splitsAt[i] : values.length;
  405. var _property = _wrapDefault(property.name, property, configuration);
  406. _property.value = values.slice(from, to);
  407. if (_property.value.length > 0) {
  408. splitComponents.push(splitWith(_property, configuration, validator));
  409. }
  410. }
  411. var components = splitComponents[0];
  412. // group component values from each split
  413. for (i = 0, l = components.length; i < l; i++) {
  414. components[i].multiplex = true;
  415. for (j = 1, m = splitComponents.length; j < m; j++) {
  416. components[i].value.push([Token.PROPERTY_VALUE, Marker.COMMA]);
  417. Array.prototype.push.apply(components[i].value, splitComponents[j][i].value);
  418. }
  419. }
  420. return components;
  421. };
  422. }
  423. function listStyle(property, configuration, validator) {
  424. var type = _wrapDefault('list-style-type', property, configuration);
  425. var position = _wrapDefault('list-style-position', property, configuration);
  426. var image = _wrapDefault('list-style-image', property, configuration);
  427. var components = [type, position, image];
  428. if (property.value.length == 1 && property.value[0][1] == 'inherit') {
  429. type.value = position.value = image.value = [property.value[0]];
  430. return components;
  431. }
  432. var values = property.value.slice(0);
  433. var total = values.length;
  434. var index = 0;
  435. // `image` first...
  436. for (index = 0, total = values.length; index < total; index++) {
  437. if (validator.isUrl(values[index][1]) || values[index][1] == '0') {
  438. image.value = [values[index]];
  439. values.splice(index, 1);
  440. break;
  441. }
  442. }
  443. // ... then `position`
  444. for (index = 0, total = values.length; index < total; index++) {
  445. if (validator.isListStylePositionKeyword(values[index][1])) {
  446. position.value = [values[index]];
  447. values.splice(index, 1);
  448. break;
  449. }
  450. }
  451. // ... and what's left is a `type`
  452. if (values.length > 0 && (validator.isListStyleTypeKeyword(values[0][1]) || validator.isIdentifier(values[0][1]))) {
  453. type.value = [values[0]];
  454. }
  455. return components;
  456. }
  457. function transition(property, configuration, validator) {
  458. var prop = _wrapDefault(property.name + '-property', property, configuration);
  459. var duration = _wrapDefault(property.name + '-duration', property, configuration);
  460. var timing = _wrapDefault(property.name + '-timing-function', property, configuration);
  461. var delay = _wrapDefault(property.name + '-delay', property, configuration);
  462. var components = [prop, duration, timing, delay];
  463. var values = property.value;
  464. var value;
  465. var durationSet = false;
  466. var delaySet = false;
  467. var propSet = false;
  468. var timingSet = false;
  469. var i;
  470. var l;
  471. if (property.value.length == 1 && property.value[0][1] == 'inherit') {
  472. prop.value = duration.value = timing.value = delay.value = property.value;
  473. return components;
  474. }
  475. if (values.length > 1 && _anyIsInherit(values)) {
  476. throw new InvalidPropertyError('Invalid animation values at ' + formatPosition(values[0][2][0]) + '. Ignoring.');
  477. }
  478. for (i = 0, l = values.length; i < l; i++) {
  479. value = values[i];
  480. if (validator.isTime(value[1]) && !durationSet) {
  481. duration.value = [value];
  482. durationSet = true;
  483. } else if (validator.isTime(value[1]) && !delaySet) {
  484. delay.value = [value];
  485. delaySet = true;
  486. } else if ((validator.isGlobal(value[1]) || validator.isTimingFunction(value[1])) && !timingSet) {
  487. timing.value = [value];
  488. timingSet = true;
  489. } else if (validator.isIdentifier(value[1]) && !propSet) {
  490. prop.value = [value];
  491. propSet = true;
  492. } else {
  493. throw new InvalidPropertyError('Invalid animation value at ' + formatPosition(value[2][0]) + '. Ignoring.');
  494. }
  495. }
  496. return components;
  497. }
  498. function widthStyleColor(property, configuration, validator) {
  499. var descriptor = configuration[property.name];
  500. var components = [
  501. _wrapDefault(descriptor.components[0], property, configuration),
  502. _wrapDefault(descriptor.components[1], property, configuration),
  503. _wrapDefault(descriptor.components[2], property, configuration)
  504. ];
  505. var color, style, width;
  506. for (var i = 0; i < 3; i++) {
  507. var component = components[i];
  508. if (component.name.indexOf('color') > 0) { color = component; } else if (component.name.indexOf('style') > 0) { style = component; } else { width = component; }
  509. }
  510. if ((property.value.length == 1 && property.value[0][1] == 'inherit')
  511. || (property.value.length == 3 && property.value[0][1] == 'inherit' && property.value[1][1] == 'inherit' && property.value[2][1] == 'inherit')) {
  512. color.value = style.value = width.value = [property.value[0]];
  513. return components;
  514. }
  515. var values = property.value.slice(0);
  516. var match, matches;
  517. // NOTE: usually users don't follow the required order of parts in this shorthand,
  518. // so we'll try to parse it caring as little about order as possible
  519. if (values.length > 0) {
  520. matches = values.filter(_widthFilter(validator));
  521. match = matches.length > 1 && (matches[0][1] == 'none' || matches[0][1] == 'auto') ? matches[1] : matches[0];
  522. if (match) {
  523. width.value = [match];
  524. values.splice(values.indexOf(match), 1);
  525. }
  526. }
  527. if (values.length > 0) {
  528. match = values.filter(_styleFilter(validator))[0];
  529. if (match) {
  530. style.value = [match];
  531. values.splice(values.indexOf(match), 1);
  532. }
  533. }
  534. if (values.length > 0) {
  535. match = values.filter(_colorFilter(validator))[0];
  536. if (match) {
  537. color.value = [match];
  538. values.splice(values.indexOf(match), 1);
  539. }
  540. }
  541. return components;
  542. }
  543. module.exports = {
  544. animation: animation,
  545. background: background,
  546. border: widthStyleColor,
  547. borderRadius: borderRadius,
  548. font: font,
  549. fourValues: fourValues,
  550. listStyle: listStyle,
  551. multiplex: multiplex,
  552. outline: widthStyleColor,
  553. transition: transition
  554. };