index.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. function _interopDefault(ex) {
  6. return ex && typeof ex === 'object' && 'default' in ex ? ex['default'] : ex;
  7. }
  8. var parse = require('postcss-value-parser');
  9. var parse__default = _interopDefault(parse);
  10. var camelizeStyleName = _interopDefault(require('camelize'));
  11. var cssColorKeywords = _interopDefault(require('css-color-keywords'));
  12. var matchString = function matchString(node) {
  13. if (node.type !== 'string') return null;
  14. return node.value.replace(/\\([0-9a-f]{1,6})(?:\s|$)/gi, function (match, charCode) {
  15. return String.fromCharCode(parseInt(charCode, 16));
  16. }).replace(/\\/g, '');
  17. };
  18. var hexColorRe = /^(#(?:[0-9a-f]{3,4}){1,2})$/i;
  19. var cssFunctionNameRe = /^(rgba?|hsla?|hwb|lab|lch|gray|color)$/;
  20. var matchColor = function matchColor(node) {
  21. if (node.type === 'word' && (hexColorRe.test(node.value) || node.value in cssColorKeywords || node.value === 'transparent')) {
  22. return node.value;
  23. } else if (node.type === 'function' && cssFunctionNameRe.test(node.value)) {
  24. return parse.stringify(node);
  25. }
  26. return null;
  27. };
  28. var noneRe = /^(none)$/i;
  29. var autoRe = /^(auto)$/i;
  30. var identRe = /(^-?[_a-z][_a-z0-9-]*$)/i; // Note if these are wrong, you'll need to change index.js too
  31. var numberRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?)$/i; // Note lengthRe is sneaky: you can omit units for 0
  32. var lengthRe = /^(0$|(?:[+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?)(?=px$))/i;
  33. var unsupportedUnitRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?(ch|em|ex|rem|vh|vw|vmin|vmax|cm|mm|in|pc|pt))$/i;
  34. var angleRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?(?:deg|rad))$/i;
  35. var percentRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?%)$/i;
  36. var noopToken = function noopToken(predicate) {
  37. return function (node) {
  38. return predicate(node) ? '<token>' : null;
  39. };
  40. };
  41. var valueForTypeToken = function valueForTypeToken(type) {
  42. return function (node) {
  43. return node.type === type ? node.value : null;
  44. };
  45. };
  46. var regExpToken = function regExpToken(regExp, transform) {
  47. if (transform === void 0) {
  48. transform = String;
  49. }
  50. return function (node) {
  51. if (node.type !== 'word') return null;
  52. var match = node.value.match(regExp);
  53. if (match === null) return null;
  54. var value = transform(match[1]);
  55. return value;
  56. };
  57. };
  58. var SPACE = noopToken(function (node) {
  59. return node.type === 'space';
  60. });
  61. var SLASH = noopToken(function (node) {
  62. return node.type === 'div' && node.value === '/';
  63. });
  64. var COMMA = noopToken(function (node) {
  65. return node.type === 'div' && node.value === ',';
  66. });
  67. var WORD = valueForTypeToken('word');
  68. var NONE = regExpToken(noneRe);
  69. var AUTO = regExpToken(autoRe);
  70. var NUMBER = regExpToken(numberRe, Number);
  71. var LENGTH = regExpToken(lengthRe, Number);
  72. var UNSUPPORTED_LENGTH_UNIT = regExpToken(unsupportedUnitRe);
  73. var ANGLE = regExpToken(angleRe, function (angle) {
  74. return angle.toLowerCase();
  75. });
  76. var PERCENT = regExpToken(percentRe);
  77. var IDENT = regExpToken(identRe);
  78. var STRING = matchString;
  79. var COLOR = matchColor;
  80. var LINE = regExpToken(/^(none|underline|line-through)$/i);
  81. var aspectRatio = function aspectRatio(tokenStream) {
  82. var aspectRatio = tokenStream.expect(NUMBER);
  83. if (tokenStream.hasTokens()) {
  84. tokenStream.expect(SLASH);
  85. aspectRatio /= tokenStream.expect(NUMBER);
  86. }
  87. return {
  88. aspectRatio: aspectRatio
  89. };
  90. };
  91. var BORDER_STYLE = regExpToken(/^(solid|dashed|dotted)$/);
  92. var defaultBorderWidth = 1;
  93. var defaultBorderColor = 'black';
  94. var defaultBorderStyle = 'solid';
  95. var border = function border(tokenStream) {
  96. var borderWidth;
  97. var borderColor;
  98. var borderStyle;
  99. if (tokenStream.matches(NONE)) {
  100. tokenStream.expectEmpty();
  101. return {
  102. borderWidth: 0,
  103. borderColor: 'black',
  104. borderStyle: 'solid'
  105. };
  106. }
  107. var partsParsed = 0;
  108. while (partsParsed < 3 && tokenStream.hasTokens()) {
  109. if (partsParsed !== 0) tokenStream.expect(SPACE);
  110. if (borderWidth === undefined && tokenStream.matches(LENGTH, UNSUPPORTED_LENGTH_UNIT)) {
  111. borderWidth = tokenStream.lastValue;
  112. } else if (borderColor === undefined && tokenStream.matches(COLOR)) {
  113. borderColor = tokenStream.lastValue;
  114. } else if (borderStyle === undefined && tokenStream.matches(BORDER_STYLE)) {
  115. borderStyle = tokenStream.lastValue;
  116. } else {
  117. tokenStream["throw"]();
  118. }
  119. partsParsed += 1;
  120. }
  121. tokenStream.expectEmpty();
  122. if (borderWidth === undefined) borderWidth = defaultBorderWidth;
  123. if (borderColor === undefined) borderColor = defaultBorderColor;
  124. if (borderStyle === undefined) borderStyle = defaultBorderStyle;
  125. return {
  126. borderWidth: borderWidth,
  127. borderColor: borderColor,
  128. borderStyle: borderStyle
  129. };
  130. };
  131. var directionFactory = function directionFactory(_ref) {
  132. var _ref$types = _ref.types,
  133. types = _ref$types === void 0 ? [LENGTH, UNSUPPORTED_LENGTH_UNIT, PERCENT] : _ref$types,
  134. _ref$directions = _ref.directions,
  135. directions = _ref$directions === void 0 ? ['Top', 'Right', 'Bottom', 'Left'] : _ref$directions,
  136. _ref$prefix = _ref.prefix,
  137. prefix = _ref$prefix === void 0 ? '' : _ref$prefix,
  138. _ref$suffix = _ref.suffix,
  139. suffix = _ref$suffix === void 0 ? '' : _ref$suffix;
  140. return function (tokenStream) {
  141. var _ref2;
  142. var values = []; // borderWidth doesn't currently allow a percent value, but may do in the future
  143. values.push(tokenStream.expect.apply(tokenStream, types));
  144. while (values.length < 4 && tokenStream.hasTokens()) {
  145. tokenStream.expect(SPACE);
  146. values.push(tokenStream.expect.apply(tokenStream, types));
  147. }
  148. tokenStream.expectEmpty();
  149. var top = values[0],
  150. _values$ = values[1],
  151. right = _values$ === void 0 ? top : _values$,
  152. _values$2 = values[2],
  153. bottom = _values$2 === void 0 ? top : _values$2,
  154. _values$3 = values[3],
  155. left = _values$3 === void 0 ? right : _values$3;
  156. var keyFor = function keyFor(n) {
  157. return "" + prefix + directions[n] + suffix;
  158. };
  159. return _ref2 = {}, _ref2[keyFor(0)] = top, _ref2[keyFor(1)] = right, _ref2[keyFor(2)] = bottom, _ref2[keyFor(3)] = left, _ref2;
  160. };
  161. };
  162. var parseShadowOffset = function parseShadowOffset(tokenStream) {
  163. var width = tokenStream.expect(LENGTH);
  164. var height = tokenStream.matches(SPACE) ? tokenStream.expect(LENGTH) : width;
  165. tokenStream.expectEmpty();
  166. return {
  167. width: width,
  168. height: height
  169. };
  170. };
  171. var parseShadow = function parseShadow(tokenStream) {
  172. var offsetX;
  173. var offsetY;
  174. var radius;
  175. var color;
  176. if (tokenStream.matches(NONE)) {
  177. tokenStream.expectEmpty();
  178. return {
  179. offset: {
  180. width: 0,
  181. height: 0
  182. },
  183. radius: 0,
  184. color: 'black'
  185. };
  186. }
  187. var didParseFirst = false;
  188. while (tokenStream.hasTokens()) {
  189. if (didParseFirst) tokenStream.expect(SPACE);
  190. if (offsetX === undefined && tokenStream.matches(LENGTH, UNSUPPORTED_LENGTH_UNIT)) {
  191. offsetX = tokenStream.lastValue;
  192. tokenStream.expect(SPACE);
  193. offsetY = tokenStream.expect(LENGTH, UNSUPPORTED_LENGTH_UNIT);
  194. tokenStream.saveRewindPoint();
  195. if (tokenStream.matches(SPACE) && tokenStream.matches(LENGTH, UNSUPPORTED_LENGTH_UNIT)) {
  196. radius = tokenStream.lastValue;
  197. } else {
  198. tokenStream.rewind();
  199. }
  200. } else if (color === undefined && tokenStream.matches(COLOR)) {
  201. color = tokenStream.lastValue;
  202. } else {
  203. tokenStream["throw"]();
  204. }
  205. didParseFirst = true;
  206. }
  207. if (offsetX === undefined) tokenStream["throw"]();
  208. return {
  209. offset: {
  210. width: offsetX,
  211. height: offsetY
  212. },
  213. radius: radius !== undefined ? radius : 0,
  214. color: color !== undefined ? color : 'black'
  215. };
  216. };
  217. var boxShadow = function boxShadow(tokenStream) {
  218. var _parseShadow = parseShadow(tokenStream),
  219. offset = _parseShadow.offset,
  220. radius = _parseShadow.radius,
  221. color = _parseShadow.color;
  222. return {
  223. shadowOffset: offset,
  224. shadowRadius: radius,
  225. shadowColor: color,
  226. shadowOpacity: 1
  227. };
  228. };
  229. var defaultFlexGrow = 1;
  230. var defaultFlexShrink = 1;
  231. var defaultFlexBasis = 0;
  232. var flex = function flex(tokenStream) {
  233. var flexGrow;
  234. var flexShrink;
  235. var flexBasis;
  236. if (tokenStream.matches(NONE)) {
  237. tokenStream.expectEmpty();
  238. return {
  239. flexGrow: 0,
  240. flexShrink: 0,
  241. flexBasis: 'auto'
  242. };
  243. }
  244. tokenStream.saveRewindPoint();
  245. if (tokenStream.matches(AUTO) && !tokenStream.hasTokens()) {
  246. return {
  247. flexGrow: 1,
  248. flexShrink: 1,
  249. flexBasis: 'auto'
  250. };
  251. }
  252. tokenStream.rewind();
  253. var partsParsed = 0;
  254. while (partsParsed < 2 && tokenStream.hasTokens()) {
  255. if (partsParsed !== 0) tokenStream.expect(SPACE);
  256. if (flexGrow === undefined && tokenStream.matches(NUMBER)) {
  257. flexGrow = tokenStream.lastValue;
  258. tokenStream.saveRewindPoint();
  259. if (tokenStream.matches(SPACE) && tokenStream.matches(NUMBER)) {
  260. flexShrink = tokenStream.lastValue;
  261. } else {
  262. tokenStream.rewind();
  263. }
  264. } else if (flexBasis === undefined && tokenStream.matches(LENGTH, UNSUPPORTED_LENGTH_UNIT, PERCENT)) {
  265. flexBasis = tokenStream.lastValue;
  266. } else if (flexBasis === undefined && tokenStream.matches(AUTO)) {
  267. flexBasis = 'auto';
  268. } else {
  269. tokenStream["throw"]();
  270. }
  271. partsParsed += 1;
  272. }
  273. tokenStream.expectEmpty();
  274. if (flexGrow === undefined) flexGrow = defaultFlexGrow;
  275. if (flexShrink === undefined) flexShrink = defaultFlexShrink;
  276. if (flexBasis === undefined) flexBasis = defaultFlexBasis;
  277. return {
  278. flexGrow: flexGrow,
  279. flexShrink: flexShrink,
  280. flexBasis: flexBasis
  281. };
  282. };
  283. var FLEX_WRAP = regExpToken(/(nowrap|wrap|wrap-reverse)/);
  284. var FLEX_DIRECTION = regExpToken(/(row|row-reverse|column|column-reverse)/);
  285. var defaultFlexWrap = 'nowrap';
  286. var defaultFlexDirection = 'row';
  287. var flexFlow = function flexFlow(tokenStream) {
  288. var flexWrap;
  289. var flexDirection;
  290. var partsParsed = 0;
  291. while (partsParsed < 2 && tokenStream.hasTokens()) {
  292. if (partsParsed !== 0) tokenStream.expect(SPACE);
  293. if (flexWrap === undefined && tokenStream.matches(FLEX_WRAP)) {
  294. flexWrap = tokenStream.lastValue;
  295. } else if (flexDirection === undefined && tokenStream.matches(FLEX_DIRECTION)) {
  296. flexDirection = tokenStream.lastValue;
  297. } else {
  298. tokenStream["throw"]();
  299. }
  300. partsParsed += 1;
  301. }
  302. tokenStream.expectEmpty();
  303. if (flexWrap === undefined) flexWrap = defaultFlexWrap;
  304. if (flexDirection === undefined) flexDirection = defaultFlexDirection;
  305. return {
  306. flexWrap: flexWrap,
  307. flexDirection: flexDirection
  308. };
  309. };
  310. var fontFamily = function fontFamily(tokenStream) {
  311. var fontFamily;
  312. if (tokenStream.matches(STRING)) {
  313. fontFamily = tokenStream.lastValue;
  314. } else {
  315. fontFamily = tokenStream.expect(IDENT);
  316. while (tokenStream.hasTokens()) {
  317. tokenStream.expect(SPACE);
  318. var nextIdent = tokenStream.expect(IDENT);
  319. fontFamily += " " + nextIdent;
  320. }
  321. }
  322. tokenStream.expectEmpty();
  323. return {
  324. fontFamily: fontFamily
  325. };
  326. };
  327. var NORMAL = regExpToken(/^(normal)$/);
  328. var STYLE = regExpToken(/^(italic)$/);
  329. var WEIGHT = regExpToken(/^([1-9]00|bold)$/);
  330. var VARIANT = regExpToken(/^(small-caps)$/);
  331. var defaultFontStyle = 'normal';
  332. var defaultFontWeight = 'normal';
  333. var defaultFontVariant = [];
  334. var font = function font(tokenStream) {
  335. var fontStyle;
  336. var fontWeight;
  337. var fontVariant; // let fontSize;
  338. var lineHeight; // let fontFamily;
  339. var numStyleWeightVariantMatched = 0;
  340. while (numStyleWeightVariantMatched < 3 && tokenStream.hasTokens()) {
  341. if (tokenStream.matches(NORMAL)) ;else if (fontStyle === undefined && tokenStream.matches(STYLE)) {
  342. fontStyle = tokenStream.lastValue;
  343. } else if (fontWeight === undefined && tokenStream.matches(WEIGHT)) {
  344. fontWeight = tokenStream.lastValue;
  345. } else if (fontVariant === undefined && tokenStream.matches(VARIANT)) {
  346. fontVariant = [tokenStream.lastValue];
  347. } else {
  348. break;
  349. }
  350. tokenStream.expect(SPACE);
  351. numStyleWeightVariantMatched += 1;
  352. }
  353. var fontSize = tokenStream.expect(LENGTH, UNSUPPORTED_LENGTH_UNIT);
  354. if (tokenStream.matches(SLASH)) {
  355. lineHeight = tokenStream.expect(LENGTH, UNSUPPORTED_LENGTH_UNIT);
  356. }
  357. tokenStream.expect(SPACE);
  358. var _fontFamily = fontFamily(tokenStream),
  359. fontFamily$1 = _fontFamily.fontFamily;
  360. if (fontStyle === undefined) fontStyle = defaultFontStyle;
  361. if (fontWeight === undefined) fontWeight = defaultFontWeight;
  362. if (fontVariant === undefined) fontVariant = defaultFontVariant;
  363. var out = {
  364. fontStyle: fontStyle,
  365. fontWeight: fontWeight,
  366. fontVariant: fontVariant,
  367. fontSize: fontSize,
  368. fontFamily: fontFamily$1
  369. };
  370. if (lineHeight !== undefined) out.lineHeight = lineHeight;
  371. return out;
  372. };
  373. var fontVariant = function fontVariant(tokenStream) {
  374. var values = [tokenStream.expect(IDENT)];
  375. while (tokenStream.hasTokens()) {
  376. tokenStream.expect(SPACE);
  377. values.push(tokenStream.expect(IDENT));
  378. }
  379. return {
  380. fontVariant: values
  381. };
  382. };
  383. var ALIGN_CONTENT = regExpToken(/(flex-(?:start|end)|center|stretch|space-(?:between|around))/);
  384. var JUSTIFY_CONTENT = regExpToken(/(flex-(?:start|end)|center|space-(?:between|around|evenly))/);
  385. var placeContent = function placeContent(tokenStream) {
  386. var alignContent = tokenStream.expect(ALIGN_CONTENT);
  387. var justifyContent;
  388. if (tokenStream.hasTokens()) {
  389. tokenStream.expect(SPACE);
  390. justifyContent = tokenStream.expect(JUSTIFY_CONTENT);
  391. } else {
  392. justifyContent = 'stretch';
  393. }
  394. tokenStream.expectEmpty();
  395. return {
  396. alignContent: alignContent,
  397. justifyContent: justifyContent
  398. };
  399. };
  400. var STYLE$1 = regExpToken(/^(solid|double|dotted|dashed)$/);
  401. var defaultTextDecorationLine = 'none';
  402. var defaultTextDecorationStyle = 'solid';
  403. var defaultTextDecorationColor = 'black';
  404. var textDecoration = function textDecoration(tokenStream) {
  405. var line;
  406. var style;
  407. var color;
  408. var didParseFirst = false;
  409. while (tokenStream.hasTokens()) {
  410. if (didParseFirst) tokenStream.expect(SPACE);
  411. if (line === undefined && tokenStream.matches(LINE)) {
  412. var lines = [tokenStream.lastValue.toLowerCase()];
  413. tokenStream.saveRewindPoint();
  414. if (lines[0] !== 'none' && tokenStream.matches(SPACE) && tokenStream.matches(LINE)) {
  415. lines.push(tokenStream.lastValue.toLowerCase()); // Underline comes before line-through
  416. lines.sort().reverse();
  417. } else {
  418. tokenStream.rewind();
  419. }
  420. line = lines.join(' ');
  421. } else if (style === undefined && tokenStream.matches(STYLE$1)) {
  422. style = tokenStream.lastValue;
  423. } else if (color === undefined && tokenStream.matches(COLOR)) {
  424. color = tokenStream.lastValue;
  425. } else {
  426. tokenStream["throw"]();
  427. }
  428. didParseFirst = true;
  429. }
  430. return {
  431. textDecorationLine: line !== undefined ? line : defaultTextDecorationLine,
  432. textDecorationColor: color !== undefined ? color : defaultTextDecorationColor,
  433. textDecorationStyle: style !== undefined ? style : defaultTextDecorationStyle
  434. };
  435. };
  436. var textDecorationLine = function textDecorationLine(tokenStream) {
  437. var lines = [];
  438. var didParseFirst = false;
  439. while (tokenStream.hasTokens()) {
  440. if (didParseFirst) tokenStream.expect(SPACE);
  441. lines.push(tokenStream.expect(LINE).toLowerCase());
  442. didParseFirst = true;
  443. }
  444. lines.sort().reverse();
  445. return {
  446. textDecorationLine: lines.join(' ')
  447. };
  448. };
  449. var textShadow = function textShadow(tokenStream) {
  450. var _parseShadow2 = parseShadow(tokenStream),
  451. offset = _parseShadow2.offset,
  452. radius = _parseShadow2.radius,
  453. color = _parseShadow2.color;
  454. return {
  455. textShadowOffset: offset,
  456. textShadowRadius: radius,
  457. textShadowColor: color
  458. };
  459. };
  460. var oneOfType = function oneOfType(tokenType) {
  461. return function (functionStream) {
  462. var value = functionStream.expect(tokenType);
  463. functionStream.expectEmpty();
  464. return value;
  465. };
  466. };
  467. var singleNumber = oneOfType(NUMBER);
  468. var singleLength = oneOfType(LENGTH);
  469. var singleAngle = oneOfType(ANGLE);
  470. var xyTransformFactory = function xyTransformFactory(tokenType) {
  471. return function (key, valueIfOmitted) {
  472. return function (functionStream) {
  473. var _ref3, _ref4;
  474. var x = functionStream.expect(tokenType);
  475. var y;
  476. if (functionStream.hasTokens()) {
  477. functionStream.expect(COMMA);
  478. y = functionStream.expect(tokenType);
  479. } else if (valueIfOmitted !== undefined) {
  480. y = valueIfOmitted;
  481. } else {
  482. // Assumption, if x === y, then we can omit XY
  483. // I.e. scale(5) => [{ scale: 5 }] rather than [{ scaleX: 5 }, { scaleY: 5 }]
  484. return x;
  485. }
  486. functionStream.expectEmpty();
  487. return [(_ref3 = {}, _ref3[key + "Y"] = y, _ref3), (_ref4 = {}, _ref4[key + "X"] = x, _ref4)];
  488. };
  489. };
  490. };
  491. var xyNumber = xyTransformFactory(NUMBER);
  492. var xyLength = xyTransformFactory(LENGTH);
  493. var xyAngle = xyTransformFactory(ANGLE);
  494. var partTransforms = {
  495. perspective: singleNumber,
  496. scale: xyNumber('scale'),
  497. scaleX: singleNumber,
  498. scaleY: singleNumber,
  499. translate: xyLength('translate', 0),
  500. translateX: singleLength,
  501. translateY: singleLength,
  502. rotate: singleAngle,
  503. rotateX: singleAngle,
  504. rotateY: singleAngle,
  505. rotateZ: singleAngle,
  506. skewX: singleAngle,
  507. skewY: singleAngle,
  508. skew: xyAngle('skew', '0deg')
  509. };
  510. var transform = function transform(tokenStream) {
  511. var transforms = [];
  512. var didParseFirst = false;
  513. while (tokenStream.hasTokens()) {
  514. if (didParseFirst) tokenStream.expect(SPACE);
  515. var functionStream = tokenStream.expectFunction();
  516. var functionName = functionStream.functionName;
  517. var transformedValues = partTransforms[functionName](functionStream);
  518. if (!Array.isArray(transformedValues)) {
  519. var _ref5;
  520. transformedValues = [(_ref5 = {}, _ref5[functionName] = transformedValues, _ref5)];
  521. }
  522. transforms = transformedValues.concat(transforms);
  523. didParseFirst = true;
  524. }
  525. return {
  526. transform: transforms
  527. };
  528. };
  529. var background = function background(tokenStream) {
  530. return {
  531. backgroundColor: tokenStream.expect(COLOR)
  532. };
  533. };
  534. var borderColor = directionFactory({
  535. types: [COLOR],
  536. prefix: 'border',
  537. suffix: 'Color'
  538. });
  539. var borderRadius = directionFactory({
  540. directions: ['TopLeft', 'TopRight', 'BottomRight', 'BottomLeft'],
  541. prefix: 'border',
  542. suffix: 'Radius'
  543. });
  544. var borderWidth = directionFactory({
  545. prefix: 'border',
  546. suffix: 'Width'
  547. });
  548. var margin = directionFactory({
  549. types: [LENGTH, UNSUPPORTED_LENGTH_UNIT, PERCENT, AUTO],
  550. prefix: 'margin'
  551. });
  552. var padding = directionFactory({
  553. prefix: 'padding'
  554. });
  555. var fontWeight = function fontWeight(tokenStream) {
  556. return {
  557. fontWeight: tokenStream.expect(WORD) // Also match numbers as strings
  558. };
  559. };
  560. var shadowOffset = function shadowOffset(tokenStream) {
  561. return {
  562. shadowOffset: parseShadowOffset(tokenStream)
  563. };
  564. };
  565. var textShadowOffset = function textShadowOffset(tokenStream) {
  566. return {
  567. textShadowOffset: parseShadowOffset(tokenStream)
  568. };
  569. };
  570. var transforms = {
  571. aspectRatio: aspectRatio,
  572. background: background,
  573. border: border,
  574. borderColor: borderColor,
  575. borderRadius: borderRadius,
  576. borderWidth: borderWidth,
  577. boxShadow: boxShadow,
  578. flex: flex,
  579. flexFlow: flexFlow,
  580. font: font,
  581. fontFamily: fontFamily,
  582. fontVariant: fontVariant,
  583. fontWeight: fontWeight,
  584. margin: margin,
  585. padding: padding,
  586. placeContent: placeContent,
  587. shadowOffset: shadowOffset,
  588. textShadow: textShadow,
  589. textShadowOffset: textShadowOffset,
  590. textDecoration: textDecoration,
  591. textDecorationLine: textDecorationLine,
  592. transform: transform
  593. };
  594. var propertiesWithoutUnits;
  595. if (process.env.NODE_ENV !== 'production') {
  596. propertiesWithoutUnits = ['aspectRatio', 'elevation', 'flexGrow', 'flexShrink', 'opacity', 'shadowOpacity', 'zIndex'];
  597. }
  598. var devPropertiesWithUnitsRegExp = propertiesWithoutUnits != null ? new RegExp(propertiesWithoutUnits.join('|')) : null;
  599. var SYMBOL_MATCH = 'SYMBOL_MATCH';
  600. var TokenStream =
  601. /*#__PURE__*/
  602. function () {
  603. function TokenStream(nodes, parent) {
  604. this.index = 0;
  605. this.nodes = nodes;
  606. this.functionName = parent != null ? parent.value : null;
  607. this.lastValue = null;
  608. this.rewindIndex = -1;
  609. }
  610. var _proto = TokenStream.prototype;
  611. _proto.hasTokens = function hasTokens() {
  612. return this.index <= this.nodes.length - 1;
  613. };
  614. _proto[SYMBOL_MATCH] = function () {
  615. if (!this.hasTokens()) return null;
  616. var node = this.nodes[this.index];
  617. for (var i = 0; i < arguments.length; i += 1) {
  618. var tokenDescriptor = i < 0 || arguments.length <= i ? undefined : arguments[i];
  619. var value = tokenDescriptor(node);
  620. if (value !== null) {
  621. this.index += 1;
  622. this.lastValue = value;
  623. return value;
  624. }
  625. }
  626. return null;
  627. };
  628. _proto.matches = function matches() {
  629. return this[SYMBOL_MATCH].apply(this, arguments) !== null;
  630. };
  631. _proto.expect = function expect() {
  632. var value = this[SYMBOL_MATCH].apply(this, arguments);
  633. return value !== null ? value : this["throw"]();
  634. };
  635. _proto.matchesFunction = function matchesFunction() {
  636. var node = this.nodes[this.index];
  637. if (node.type !== 'function') return null;
  638. var value = new TokenStream(node.nodes, node);
  639. this.index += 1;
  640. this.lastValue = null;
  641. return value;
  642. };
  643. _proto.expectFunction = function expectFunction() {
  644. var value = this.matchesFunction();
  645. return value !== null ? value : this["throw"]();
  646. };
  647. _proto.expectEmpty = function expectEmpty() {
  648. if (this.hasTokens()) this["throw"]();
  649. };
  650. _proto["throw"] = function _throw() {
  651. throw new Error("Unexpected token type: " + this.nodes[this.index].type);
  652. };
  653. _proto.saveRewindPoint = function saveRewindPoint() {
  654. this.rewindIndex = this.index;
  655. };
  656. _proto.rewind = function rewind() {
  657. if (this.rewindIndex === -1) throw new Error('Internal error');
  658. this.index = this.rewindIndex;
  659. this.lastValue = null;
  660. };
  661. return TokenStream;
  662. }();
  663. /* eslint-disable no-param-reassign */
  664. // Note if this is wrong, you'll need to change tokenTypes.js too
  665. var numberOrLengthRe = /^([+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?)(?:px)?$/i;
  666. var numberOnlyRe = /^[+-]?(?:\d*\.\d*|[1-9]\d*)(?:e[+-]?\d+)?$/i;
  667. var boolRe = /^true|false$/i;
  668. var nullRe = /^null$/i;
  669. var undefinedRe = /^undefined$/i; // Undocumented export
  670. var transformRawValue = function transformRawValue(propName, value) {
  671. if (process.env.NODE_ENV !== 'production') {
  672. var needsUnit = !devPropertiesWithUnitsRegExp.test(propName);
  673. var isNumberWithoutUnit = numberOnlyRe.test(value);
  674. if (needsUnit && isNumberWithoutUnit) {
  675. // eslint-disable-next-line no-console
  676. console.warn("Expected style \"" + propName + ": " + value + "\" to contain units");
  677. }
  678. if (!needsUnit && value !== '0' && !isNumberWithoutUnit) {
  679. // eslint-disable-next-line no-console
  680. console.warn("Expected style \"" + propName + ": " + value + "\" to be unitless");
  681. }
  682. }
  683. var numberMatch = value.match(numberOrLengthRe);
  684. if (numberMatch !== null) return Number(numberMatch[1]);
  685. var boolMatch = value.match(boolRe);
  686. if (boolMatch !== null) return boolMatch[0].toLowerCase() === 'true';
  687. var nullMatch = value.match(nullRe);
  688. if (nullMatch !== null) return null;
  689. var undefinedMatch = value.match(undefinedRe);
  690. if (undefinedMatch !== null) return undefined;
  691. return value;
  692. };
  693. var baseTransformShorthandValue = function baseTransformShorthandValue(propName, value) {
  694. var ast = parse__default(value);
  695. var tokenStream = new TokenStream(ast.nodes);
  696. return transforms[propName](tokenStream);
  697. };
  698. var transformShorthandValue = process.env.NODE_ENV === 'production' ? baseTransformShorthandValue : function (propName, value) {
  699. try {
  700. return baseTransformShorthandValue(propName, value);
  701. } catch (e) {
  702. throw new Error("Failed to parse declaration \"" + propName + ": " + value + "\"");
  703. }
  704. };
  705. var getStylesForProperty = function getStylesForProperty(propName, inputValue, allowShorthand) {
  706. var _ref6;
  707. var isRawValue = allowShorthand === false || !(propName in transforms);
  708. var value = inputValue.trim();
  709. var propValues = isRawValue ? (_ref6 = {}, _ref6[propName] = transformRawValue(propName, value), _ref6) : transformShorthandValue(propName, value);
  710. return propValues;
  711. };
  712. var getPropertyName = function getPropertyName(propName) {
  713. var isCustomProp = /^--\w+/.test(propName);
  714. if (isCustomProp) {
  715. return propName;
  716. }
  717. return camelizeStyleName(propName);
  718. };
  719. var index = function index(rules, shorthandBlacklist) {
  720. if (shorthandBlacklist === void 0) {
  721. shorthandBlacklist = [];
  722. }
  723. return rules.reduce(function (accum, rule) {
  724. var propertyName = getPropertyName(rule[0]);
  725. var value = rule[1];
  726. var allowShorthand = shorthandBlacklist.indexOf(propertyName) === -1;
  727. return Object.assign(accum, getStylesForProperty(propertyName, value, allowShorthand));
  728. }, {});
  729. };
  730. exports["default"] = index;
  731. exports.getPropertyName = getPropertyName;
  732. exports.getStylesForProperty = getStylesForProperty;
  733. exports.transformRawValue = transformRawValue;