web 3d图形渲染器
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
7.6 KiB

  1. "use strict";
  2. exports.__esModule = true;
  3. exports.default = tokenize;
  4. exports.FIELDS = void 0;
  5. var t = _interopRequireWildcard(require("./tokenTypes"));
  6. var _unescapable, _wordDelimiters;
  7. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
  8. var unescapable = (_unescapable = {}, _unescapable[t.tab] = true, _unescapable[t.newline] = true, _unescapable[t.cr] = true, _unescapable[t.feed] = true, _unescapable);
  9. var wordDelimiters = (_wordDelimiters = {}, _wordDelimiters[t.space] = true, _wordDelimiters[t.tab] = true, _wordDelimiters[t.newline] = true, _wordDelimiters[t.cr] = true, _wordDelimiters[t.feed] = true, _wordDelimiters[t.ampersand] = true, _wordDelimiters[t.asterisk] = true, _wordDelimiters[t.bang] = true, _wordDelimiters[t.comma] = true, _wordDelimiters[t.colon] = true, _wordDelimiters[t.semicolon] = true, _wordDelimiters[t.openParenthesis] = true, _wordDelimiters[t.closeParenthesis] = true, _wordDelimiters[t.openSquare] = true, _wordDelimiters[t.closeSquare] = true, _wordDelimiters[t.singleQuote] = true, _wordDelimiters[t.doubleQuote] = true, _wordDelimiters[t.plus] = true, _wordDelimiters[t.pipe] = true, _wordDelimiters[t.tilde] = true, _wordDelimiters[t.greaterThan] = true, _wordDelimiters[t.equals] = true, _wordDelimiters[t.dollar] = true, _wordDelimiters[t.caret] = true, _wordDelimiters[t.slash] = true, _wordDelimiters);
  10. var hex = {};
  11. var hexChars = "0123456789abcdefABCDEF";
  12. for (var i = 0; i < hexChars.length; i++) {
  13. hex[hexChars.charCodeAt(i)] = true;
  14. }
  15. /**
  16. * Returns the last index of the bar css word
  17. * @param {string} css The string in which the word begins
  18. * @param {number} start The index into the string where word's first letter occurs
  19. */
  20. function consumeWord(css, start) {
  21. var next = start;
  22. var code;
  23. do {
  24. code = css.charCodeAt(next);
  25. if (wordDelimiters[code]) {
  26. return next - 1;
  27. } else if (code === t.backslash) {
  28. next = consumeEscape(css, next) + 1;
  29. } else {
  30. // All other characters are part of the word
  31. next++;
  32. }
  33. } while (next < css.length);
  34. return next - 1;
  35. }
  36. /**
  37. * Returns the last index of the escape sequence
  38. * @param {string} css The string in which the sequence begins
  39. * @param {number} start The index into the string where escape character (`\`) occurs.
  40. */
  41. function consumeEscape(css, start) {
  42. var next = start;
  43. var code = css.charCodeAt(next + 1);
  44. if (unescapable[code]) {// just consume the escape char
  45. } else if (hex[code]) {
  46. var hexDigits = 0; // consume up to 6 hex chars
  47. do {
  48. next++;
  49. hexDigits++;
  50. code = css.charCodeAt(next + 1);
  51. } while (hex[code] && hexDigits < 6); // if fewer than 6 hex chars, a trailing space ends the escape
  52. if (hexDigits < 6 && code === t.space) {
  53. next++;
  54. }
  55. } else {
  56. // the next char is part of the current word
  57. next++;
  58. }
  59. return next;
  60. }
  61. var FIELDS = {
  62. TYPE: 0,
  63. START_LINE: 1,
  64. START_COL: 2,
  65. END_LINE: 3,
  66. END_COL: 4,
  67. START_POS: 5,
  68. END_POS: 6
  69. };
  70. exports.FIELDS = FIELDS;
  71. function tokenize(input) {
  72. var tokens = [];
  73. var css = input.css.valueOf();
  74. var _css = css,
  75. length = _css.length;
  76. var offset = -1;
  77. var line = 1;
  78. var start = 0;
  79. var end = 0;
  80. var code, content, endColumn, endLine, escaped, escapePos, last, lines, next, nextLine, nextOffset, quote, tokenType;
  81. function unclosed(what, fix) {
  82. if (input.safe) {
  83. // fyi: this is never set to true.
  84. css += fix;
  85. next = css.length - 1;
  86. } else {
  87. throw input.error('Unclosed ' + what, line, start - offset, start);
  88. }
  89. }
  90. while (start < length) {
  91. code = css.charCodeAt(start);
  92. if (code === t.newline) {
  93. offset = start;
  94. line += 1;
  95. }
  96. switch (code) {
  97. case t.space:
  98. case t.tab:
  99. case t.newline:
  100. case t.cr:
  101. case t.feed:
  102. next = start;
  103. do {
  104. next += 1;
  105. code = css.charCodeAt(next);
  106. if (code === t.newline) {
  107. offset = next;
  108. line += 1;
  109. }
  110. } while (code === t.space || code === t.newline || code === t.tab || code === t.cr || code === t.feed);
  111. tokenType = t.space;
  112. endLine = line;
  113. endColumn = next - offset - 1;
  114. end = next;
  115. break;
  116. case t.plus:
  117. case t.greaterThan:
  118. case t.tilde:
  119. case t.pipe:
  120. next = start;
  121. do {
  122. next += 1;
  123. code = css.charCodeAt(next);
  124. } while (code === t.plus || code === t.greaterThan || code === t.tilde || code === t.pipe);
  125. tokenType = t.combinator;
  126. endLine = line;
  127. endColumn = start - offset;
  128. end = next;
  129. break;
  130. // Consume these characters as single tokens.
  131. case t.asterisk:
  132. case t.ampersand:
  133. case t.bang:
  134. case t.comma:
  135. case t.equals:
  136. case t.dollar:
  137. case t.caret:
  138. case t.openSquare:
  139. case t.closeSquare:
  140. case t.colon:
  141. case t.semicolon:
  142. case t.openParenthesis:
  143. case t.closeParenthesis:
  144. next = start;
  145. tokenType = code;
  146. endLine = line;
  147. endColumn = start - offset;
  148. end = next + 1;
  149. break;
  150. case t.singleQuote:
  151. case t.doubleQuote:
  152. quote = code === t.singleQuote ? "'" : '"';
  153. next = start;
  154. do {
  155. escaped = false;
  156. next = css.indexOf(quote, next + 1);
  157. if (next === -1) {
  158. unclosed('quote', quote);
  159. }
  160. escapePos = next;
  161. while (css.charCodeAt(escapePos - 1) === t.backslash) {
  162. escapePos -= 1;
  163. escaped = !escaped;
  164. }
  165. } while (escaped);
  166. tokenType = t.str;
  167. endLine = line;
  168. endColumn = start - offset;
  169. end = next + 1;
  170. break;
  171. default:
  172. if (code === t.slash && css.charCodeAt(start + 1) === t.asterisk) {
  173. next = css.indexOf('*/', start + 2) + 1;
  174. if (next === 0) {
  175. unclosed('comment', '*/');
  176. }
  177. content = css.slice(start, next + 1);
  178. lines = content.split('\n');
  179. last = lines.length - 1;
  180. if (last > 0) {
  181. nextLine = line + last;
  182. nextOffset = next - lines[last].length;
  183. } else {
  184. nextLine = line;
  185. nextOffset = offset;
  186. }
  187. tokenType = t.comment;
  188. line = nextLine;
  189. endLine = nextLine;
  190. endColumn = next - nextOffset;
  191. } else if (code === t.slash) {
  192. next = start;
  193. tokenType = code;
  194. endLine = line;
  195. endColumn = start - offset;
  196. end = next + 1;
  197. } else {
  198. next = consumeWord(css, start);
  199. tokenType = t.word;
  200. endLine = line;
  201. endColumn = next - offset;
  202. }
  203. end = next + 1;
  204. break;
  205. } // Ensure that the token structure remains consistent
  206. tokens.push([tokenType, // [0] Token type
  207. line, // [1] Starting line
  208. start - offset, // [2] Starting column
  209. endLine, // [3] Ending line
  210. endColumn, // [4] Ending column
  211. start, // [5] Start position / Source index
  212. end]); // Reset offset for the next token
  213. if (nextOffset) {
  214. offset = nextOffset;
  215. nextOffset = null;
  216. }
  217. start = end;
  218. }
  219. return tokens;
  220. }