dep-2056ae8a.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. 'use strict';
  2. var openParentheses = "(".charCodeAt(0);
  3. var closeParentheses = ")".charCodeAt(0);
  4. var singleQuote = "'".charCodeAt(0);
  5. var doubleQuote = '"'.charCodeAt(0);
  6. var backslash = "\\".charCodeAt(0);
  7. var slash = "/".charCodeAt(0);
  8. var comma = ",".charCodeAt(0);
  9. var colon = ":".charCodeAt(0);
  10. var star = "*".charCodeAt(0);
  11. var uLower = "u".charCodeAt(0);
  12. var uUpper = "U".charCodeAt(0);
  13. var plus$1 = "+".charCodeAt(0);
  14. var isUnicodeRange = /^[a-f0-9?-]+$/i;
  15. var parse$1 = function(input) {
  16. var tokens = [];
  17. var value = input;
  18. var next,
  19. quote,
  20. prev,
  21. token,
  22. escape,
  23. escapePos,
  24. whitespacePos,
  25. parenthesesOpenPos;
  26. var pos = 0;
  27. var code = value.charCodeAt(pos);
  28. var max = value.length;
  29. var stack = [{ nodes: tokens }];
  30. var balanced = 0;
  31. var parent;
  32. var name = "";
  33. var before = "";
  34. var after = "";
  35. while (pos < max) {
  36. // Whitespaces
  37. if (code <= 32) {
  38. next = pos;
  39. do {
  40. next += 1;
  41. code = value.charCodeAt(next);
  42. } while (code <= 32);
  43. token = value.slice(pos, next);
  44. prev = tokens[tokens.length - 1];
  45. if (code === closeParentheses && balanced) {
  46. after = token;
  47. } else if (prev && prev.type === "div") {
  48. prev.after = token;
  49. prev.sourceEndIndex += token.length;
  50. } else if (
  51. code === comma ||
  52. code === colon ||
  53. (code === slash &&
  54. value.charCodeAt(next + 1) !== star &&
  55. (!parent ||
  56. (parent && parent.type === "function" && parent.value !== "calc")))
  57. ) {
  58. before = token;
  59. } else {
  60. tokens.push({
  61. type: "space",
  62. sourceIndex: pos,
  63. sourceEndIndex: next,
  64. value: token
  65. });
  66. }
  67. pos = next;
  68. // Quotes
  69. } else if (code === singleQuote || code === doubleQuote) {
  70. next = pos;
  71. quote = code === singleQuote ? "'" : '"';
  72. token = {
  73. type: "string",
  74. sourceIndex: pos,
  75. quote: quote
  76. };
  77. do {
  78. escape = false;
  79. next = value.indexOf(quote, next + 1);
  80. if (~next) {
  81. escapePos = next;
  82. while (value.charCodeAt(escapePos - 1) === backslash) {
  83. escapePos -= 1;
  84. escape = !escape;
  85. }
  86. } else {
  87. value += quote;
  88. next = value.length - 1;
  89. token.unclosed = true;
  90. }
  91. } while (escape);
  92. token.value = value.slice(pos + 1, next);
  93. token.sourceEndIndex = token.unclosed ? next : next + 1;
  94. tokens.push(token);
  95. pos = next + 1;
  96. code = value.charCodeAt(pos);
  97. // Comments
  98. } else if (code === slash && value.charCodeAt(pos + 1) === star) {
  99. next = value.indexOf("*/", pos);
  100. token = {
  101. type: "comment",
  102. sourceIndex: pos,
  103. sourceEndIndex: next + 2
  104. };
  105. if (next === -1) {
  106. token.unclosed = true;
  107. next = value.length;
  108. token.sourceEndIndex = next;
  109. }
  110. token.value = value.slice(pos + 2, next);
  111. tokens.push(token);
  112. pos = next + 2;
  113. code = value.charCodeAt(pos);
  114. // Operation within calc
  115. } else if (
  116. (code === slash || code === star) &&
  117. parent &&
  118. parent.type === "function" &&
  119. parent.value === "calc"
  120. ) {
  121. token = value[pos];
  122. tokens.push({
  123. type: "word",
  124. sourceIndex: pos - before.length,
  125. sourceEndIndex: pos + token.length,
  126. value: token
  127. });
  128. pos += 1;
  129. code = value.charCodeAt(pos);
  130. // Dividers
  131. } else if (code === slash || code === comma || code === colon) {
  132. token = value[pos];
  133. tokens.push({
  134. type: "div",
  135. sourceIndex: pos - before.length,
  136. sourceEndIndex: pos + token.length,
  137. value: token,
  138. before: before,
  139. after: ""
  140. });
  141. before = "";
  142. pos += 1;
  143. code = value.charCodeAt(pos);
  144. // Open parentheses
  145. } else if (openParentheses === code) {
  146. // Whitespaces after open parentheses
  147. next = pos;
  148. do {
  149. next += 1;
  150. code = value.charCodeAt(next);
  151. } while (code <= 32);
  152. parenthesesOpenPos = pos;
  153. token = {
  154. type: "function",
  155. sourceIndex: pos - name.length,
  156. value: name,
  157. before: value.slice(parenthesesOpenPos + 1, next)
  158. };
  159. pos = next;
  160. if (name === "url" && code !== singleQuote && code !== doubleQuote) {
  161. next -= 1;
  162. do {
  163. escape = false;
  164. next = value.indexOf(")", next + 1);
  165. if (~next) {
  166. escapePos = next;
  167. while (value.charCodeAt(escapePos - 1) === backslash) {
  168. escapePos -= 1;
  169. escape = !escape;
  170. }
  171. } else {
  172. value += ")";
  173. next = value.length - 1;
  174. token.unclosed = true;
  175. }
  176. } while (escape);
  177. // Whitespaces before closed
  178. whitespacePos = next;
  179. do {
  180. whitespacePos -= 1;
  181. code = value.charCodeAt(whitespacePos);
  182. } while (code <= 32);
  183. if (parenthesesOpenPos < whitespacePos) {
  184. if (pos !== whitespacePos + 1) {
  185. token.nodes = [
  186. {
  187. type: "word",
  188. sourceIndex: pos,
  189. sourceEndIndex: whitespacePos + 1,
  190. value: value.slice(pos, whitespacePos + 1)
  191. }
  192. ];
  193. } else {
  194. token.nodes = [];
  195. }
  196. if (token.unclosed && whitespacePos + 1 !== next) {
  197. token.after = "";
  198. token.nodes.push({
  199. type: "space",
  200. sourceIndex: whitespacePos + 1,
  201. sourceEndIndex: next,
  202. value: value.slice(whitespacePos + 1, next)
  203. });
  204. } else {
  205. token.after = value.slice(whitespacePos + 1, next);
  206. token.sourceEndIndex = next;
  207. }
  208. } else {
  209. token.after = "";
  210. token.nodes = [];
  211. }
  212. pos = next + 1;
  213. token.sourceEndIndex = token.unclosed ? next : pos;
  214. code = value.charCodeAt(pos);
  215. tokens.push(token);
  216. } else {
  217. balanced += 1;
  218. token.after = "";
  219. token.sourceEndIndex = pos + 1;
  220. tokens.push(token);
  221. stack.push(token);
  222. tokens = token.nodes = [];
  223. parent = token;
  224. }
  225. name = "";
  226. // Close parentheses
  227. } else if (closeParentheses === code && balanced) {
  228. pos += 1;
  229. code = value.charCodeAt(pos);
  230. parent.after = after;
  231. parent.sourceEndIndex += after.length;
  232. after = "";
  233. balanced -= 1;
  234. stack[stack.length - 1].sourceEndIndex = pos;
  235. stack.pop();
  236. parent = stack[balanced];
  237. tokens = parent.nodes;
  238. // Words
  239. } else {
  240. next = pos;
  241. do {
  242. if (code === backslash) {
  243. next += 1;
  244. }
  245. next += 1;
  246. code = value.charCodeAt(next);
  247. } while (
  248. next < max &&
  249. !(
  250. code <= 32 ||
  251. code === singleQuote ||
  252. code === doubleQuote ||
  253. code === comma ||
  254. code === colon ||
  255. code === slash ||
  256. code === openParentheses ||
  257. (code === star &&
  258. parent &&
  259. parent.type === "function" &&
  260. parent.value === "calc") ||
  261. (code === slash &&
  262. parent.type === "function" &&
  263. parent.value === "calc") ||
  264. (code === closeParentheses && balanced)
  265. )
  266. );
  267. token = value.slice(pos, next);
  268. if (openParentheses === code) {
  269. name = token;
  270. } else if (
  271. (uLower === token.charCodeAt(0) || uUpper === token.charCodeAt(0)) &&
  272. plus$1 === token.charCodeAt(1) &&
  273. isUnicodeRange.test(token.slice(2))
  274. ) {
  275. tokens.push({
  276. type: "unicode-range",
  277. sourceIndex: pos,
  278. sourceEndIndex: next,
  279. value: token
  280. });
  281. } else {
  282. tokens.push({
  283. type: "word",
  284. sourceIndex: pos,
  285. sourceEndIndex: next,
  286. value: token
  287. });
  288. }
  289. pos = next;
  290. }
  291. }
  292. for (pos = stack.length - 1; pos; pos -= 1) {
  293. stack[pos].unclosed = true;
  294. stack[pos].sourceEndIndex = value.length;
  295. }
  296. return stack[0].nodes;
  297. };
  298. var walk$1 = function walk(nodes, cb, bubble) {
  299. var i, max, node, result;
  300. for (i = 0, max = nodes.length; i < max; i += 1) {
  301. node = nodes[i];
  302. if (!bubble) {
  303. result = cb(node, i, nodes);
  304. }
  305. if (
  306. result !== false &&
  307. node.type === "function" &&
  308. Array.isArray(node.nodes)
  309. ) {
  310. walk(node.nodes, cb, bubble);
  311. }
  312. if (bubble) {
  313. cb(node, i, nodes);
  314. }
  315. }
  316. };
  317. function stringifyNode(node, custom) {
  318. var type = node.type;
  319. var value = node.value;
  320. var buf;
  321. var customResult;
  322. if (custom && (customResult = custom(node)) !== undefined) {
  323. return customResult;
  324. } else if (type === "word" || type === "space") {
  325. return value;
  326. } else if (type === "string") {
  327. buf = node.quote || "";
  328. return buf + value + (node.unclosed ? "" : buf);
  329. } else if (type === "comment") {
  330. return "/*" + value + (node.unclosed ? "" : "*/");
  331. } else if (type === "div") {
  332. return (node.before || "") + value + (node.after || "");
  333. } else if (Array.isArray(node.nodes)) {
  334. buf = stringify$1(node.nodes, custom);
  335. if (type !== "function") {
  336. return buf;
  337. }
  338. return (
  339. value +
  340. "(" +
  341. (node.before || "") +
  342. buf +
  343. (node.after || "") +
  344. (node.unclosed ? "" : ")")
  345. );
  346. }
  347. return value;
  348. }
  349. function stringify$1(nodes, custom) {
  350. var result, i;
  351. if (Array.isArray(nodes)) {
  352. result = "";
  353. for (i = nodes.length - 1; ~i; i -= 1) {
  354. result = stringifyNode(nodes[i], custom) + result;
  355. }
  356. return result;
  357. }
  358. return stringifyNode(nodes, custom);
  359. }
  360. var stringify_1 = stringify$1;
  361. var minus = "-".charCodeAt(0);
  362. var plus = "+".charCodeAt(0);
  363. var dot = ".".charCodeAt(0);
  364. var exp = "e".charCodeAt(0);
  365. var EXP = "E".charCodeAt(0);
  366. // Check if three code points would start a number
  367. // https://www.w3.org/TR/css-syntax-3/#starts-with-a-number
  368. function likeNumber(value) {
  369. var code = value.charCodeAt(0);
  370. var nextCode;
  371. if (code === plus || code === minus) {
  372. nextCode = value.charCodeAt(1);
  373. if (nextCode >= 48 && nextCode <= 57) {
  374. return true;
  375. }
  376. var nextNextCode = value.charCodeAt(2);
  377. if (nextCode === dot && nextNextCode >= 48 && nextNextCode <= 57) {
  378. return true;
  379. }
  380. return false;
  381. }
  382. if (code === dot) {
  383. nextCode = value.charCodeAt(1);
  384. if (nextCode >= 48 && nextCode <= 57) {
  385. return true;
  386. }
  387. return false;
  388. }
  389. if (code >= 48 && code <= 57) {
  390. return true;
  391. }
  392. return false;
  393. }
  394. // Consume a number
  395. // https://www.w3.org/TR/css-syntax-3/#consume-number
  396. var unit = function(value) {
  397. var pos = 0;
  398. var length = value.length;
  399. var code;
  400. var nextCode;
  401. var nextNextCode;
  402. if (length === 0 || !likeNumber(value)) {
  403. return false;
  404. }
  405. code = value.charCodeAt(pos);
  406. if (code === plus || code === minus) {
  407. pos++;
  408. }
  409. while (pos < length) {
  410. code = value.charCodeAt(pos);
  411. if (code < 48 || code > 57) {
  412. break;
  413. }
  414. pos += 1;
  415. }
  416. code = value.charCodeAt(pos);
  417. nextCode = value.charCodeAt(pos + 1);
  418. if (code === dot && nextCode >= 48 && nextCode <= 57) {
  419. pos += 2;
  420. while (pos < length) {
  421. code = value.charCodeAt(pos);
  422. if (code < 48 || code > 57) {
  423. break;
  424. }
  425. pos += 1;
  426. }
  427. }
  428. code = value.charCodeAt(pos);
  429. nextCode = value.charCodeAt(pos + 1);
  430. nextNextCode = value.charCodeAt(pos + 2);
  431. if (
  432. (code === exp || code === EXP) &&
  433. ((nextCode >= 48 && nextCode <= 57) ||
  434. ((nextCode === plus || nextCode === minus) &&
  435. nextNextCode >= 48 &&
  436. nextNextCode <= 57))
  437. ) {
  438. pos += nextCode === plus || nextCode === minus ? 3 : 2;
  439. while (pos < length) {
  440. code = value.charCodeAt(pos);
  441. if (code < 48 || code > 57) {
  442. break;
  443. }
  444. pos += 1;
  445. }
  446. }
  447. return {
  448. number: value.slice(0, pos),
  449. unit: value.slice(pos)
  450. };
  451. };
  452. var parse = parse$1;
  453. var walk = walk$1;
  454. var stringify = stringify_1;
  455. function ValueParser(value) {
  456. if (this instanceof ValueParser) {
  457. this.nodes = parse(value);
  458. return this;
  459. }
  460. return new ValueParser(value);
  461. }
  462. ValueParser.prototype.toString = function() {
  463. return Array.isArray(this.nodes) ? stringify(this.nodes) : "";
  464. };
  465. ValueParser.prototype.walk = function(cb, bubble) {
  466. walk(this.nodes, cb, bubble);
  467. return this;
  468. };
  469. ValueParser.unit = unit;
  470. ValueParser.walk = walk;
  471. ValueParser.stringify = stringify;
  472. var lib = ValueParser;
  473. exports.lib = lib;