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.
		
		
		
		
		
			
		
			
				
					
					
						
							271 lines
						
					
					
						
							8.1 KiB
						
					
					
				
			
		
		
	
	
							271 lines
						
					
					
						
							8.1 KiB
						
					
					
				"use strict"; | 
						|
 | 
						|
exports.__esModule = true; | 
						|
exports["default"] = tokenize; | 
						|
exports.FIELDS = void 0; | 
						|
 | 
						|
var t = _interopRequireWildcard(require("./tokenTypes")); | 
						|
 | 
						|
var _unescapable, _wordDelimiters; | 
						|
 | 
						|
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } | 
						|
 | 
						|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } | 
						|
 | 
						|
var unescapable = (_unescapable = {}, _unescapable[t.tab] = true, _unescapable[t.newline] = true, _unescapable[t.cr] = true, _unescapable[t.feed] = true, _unescapable); | 
						|
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); | 
						|
var hex = {}; | 
						|
var hexChars = "0123456789abcdefABCDEF"; | 
						|
 | 
						|
for (var i = 0; i < hexChars.length; i++) { | 
						|
  hex[hexChars.charCodeAt(i)] = true; | 
						|
} | 
						|
/** | 
						|
 *  Returns the last index of the bar css word | 
						|
 * @param {string} css The string in which the word begins | 
						|
 * @param {number} start The index into the string where word's first letter occurs | 
						|
 */ | 
						|
 | 
						|
 | 
						|
function consumeWord(css, start) { | 
						|
  var next = start; | 
						|
  var code; | 
						|
 | 
						|
  do { | 
						|
    code = css.charCodeAt(next); | 
						|
 | 
						|
    if (wordDelimiters[code]) { | 
						|
      return next - 1; | 
						|
    } else if (code === t.backslash) { | 
						|
      next = consumeEscape(css, next) + 1; | 
						|
    } else { | 
						|
      // All other characters are part of the word | 
						|
      next++; | 
						|
    } | 
						|
  } while (next < css.length); | 
						|
 | 
						|
  return next - 1; | 
						|
} | 
						|
/** | 
						|
 *  Returns the last index of the escape sequence | 
						|
 * @param {string} css The string in which the sequence begins | 
						|
 * @param {number} start The index into the string where escape character (`\`) occurs. | 
						|
 */ | 
						|
 | 
						|
 | 
						|
function consumeEscape(css, start) { | 
						|
  var next = start; | 
						|
  var code = css.charCodeAt(next + 1); | 
						|
 | 
						|
  if (unescapable[code]) {// just consume the escape char | 
						|
  } else if (hex[code]) { | 
						|
    var hexDigits = 0; // consume up to 6 hex chars | 
						|
 | 
						|
    do { | 
						|
      next++; | 
						|
      hexDigits++; | 
						|
      code = css.charCodeAt(next + 1); | 
						|
    } while (hex[code] && hexDigits < 6); // if fewer than 6 hex chars, a trailing space ends the escape | 
						|
 | 
						|
 | 
						|
    if (hexDigits < 6 && code === t.space) { | 
						|
      next++; | 
						|
    } | 
						|
  } else { | 
						|
    // the next char is part of the current word | 
						|
    next++; | 
						|
  } | 
						|
 | 
						|
  return next; | 
						|
} | 
						|
 | 
						|
var FIELDS = { | 
						|
  TYPE: 0, | 
						|
  START_LINE: 1, | 
						|
  START_COL: 2, | 
						|
  END_LINE: 3, | 
						|
  END_COL: 4, | 
						|
  START_POS: 5, | 
						|
  END_POS: 6 | 
						|
}; | 
						|
exports.FIELDS = FIELDS; | 
						|
 | 
						|
function tokenize(input) { | 
						|
  var tokens = []; | 
						|
  var css = input.css.valueOf(); | 
						|
  var _css = css, | 
						|
      length = _css.length; | 
						|
  var offset = -1; | 
						|
  var line = 1; | 
						|
  var start = 0; | 
						|
  var end = 0; | 
						|
  var code, content, endColumn, endLine, escaped, escapePos, last, lines, next, nextLine, nextOffset, quote, tokenType; | 
						|
 | 
						|
  function unclosed(what, fix) { | 
						|
    if (input.safe) { | 
						|
      // fyi: this is never set to true. | 
						|
      css += fix; | 
						|
      next = css.length - 1; | 
						|
    } else { | 
						|
      throw input.error('Unclosed ' + what, line, start - offset, start); | 
						|
    } | 
						|
  } | 
						|
 | 
						|
  while (start < length) { | 
						|
    code = css.charCodeAt(start); | 
						|
 | 
						|
    if (code === t.newline) { | 
						|
      offset = start; | 
						|
      line += 1; | 
						|
    } | 
						|
 | 
						|
    switch (code) { | 
						|
      case t.space: | 
						|
      case t.tab: | 
						|
      case t.newline: | 
						|
      case t.cr: | 
						|
      case t.feed: | 
						|
        next = start; | 
						|
 | 
						|
        do { | 
						|
          next += 1; | 
						|
          code = css.charCodeAt(next); | 
						|
 | 
						|
          if (code === t.newline) { | 
						|
            offset = next; | 
						|
            line += 1; | 
						|
          } | 
						|
        } while (code === t.space || code === t.newline || code === t.tab || code === t.cr || code === t.feed); | 
						|
 | 
						|
        tokenType = t.space; | 
						|
        endLine = line; | 
						|
        endColumn = next - offset - 1; | 
						|
        end = next; | 
						|
        break; | 
						|
 | 
						|
      case t.plus: | 
						|
      case t.greaterThan: | 
						|
      case t.tilde: | 
						|
      case t.pipe: | 
						|
        next = start; | 
						|
 | 
						|
        do { | 
						|
          next += 1; | 
						|
          code = css.charCodeAt(next); | 
						|
        } while (code === t.plus || code === t.greaterThan || code === t.tilde || code === t.pipe); | 
						|
 | 
						|
        tokenType = t.combinator; | 
						|
        endLine = line; | 
						|
        endColumn = start - offset; | 
						|
        end = next; | 
						|
        break; | 
						|
      // Consume these characters as single tokens. | 
						|
 | 
						|
      case t.asterisk: | 
						|
      case t.ampersand: | 
						|
      case t.bang: | 
						|
      case t.comma: | 
						|
      case t.equals: | 
						|
      case t.dollar: | 
						|
      case t.caret: | 
						|
      case t.openSquare: | 
						|
      case t.closeSquare: | 
						|
      case t.colon: | 
						|
      case t.semicolon: | 
						|
      case t.openParenthesis: | 
						|
      case t.closeParenthesis: | 
						|
        next = start; | 
						|
        tokenType = code; | 
						|
        endLine = line; | 
						|
        endColumn = start - offset; | 
						|
        end = next + 1; | 
						|
        break; | 
						|
 | 
						|
      case t.singleQuote: | 
						|
      case t.doubleQuote: | 
						|
        quote = code === t.singleQuote ? "'" : '"'; | 
						|
        next = start; | 
						|
 | 
						|
        do { | 
						|
          escaped = false; | 
						|
          next = css.indexOf(quote, next + 1); | 
						|
 | 
						|
          if (next === -1) { | 
						|
            unclosed('quote', quote); | 
						|
          } | 
						|
 | 
						|
          escapePos = next; | 
						|
 | 
						|
          while (css.charCodeAt(escapePos - 1) === t.backslash) { | 
						|
            escapePos -= 1; | 
						|
            escaped = !escaped; | 
						|
          } | 
						|
        } while (escaped); | 
						|
 | 
						|
        tokenType = t.str; | 
						|
        endLine = line; | 
						|
        endColumn = start - offset; | 
						|
        end = next + 1; | 
						|
        break; | 
						|
 | 
						|
      default: | 
						|
        if (code === t.slash && css.charCodeAt(start + 1) === t.asterisk) { | 
						|
          next = css.indexOf('*/', start + 2) + 1; | 
						|
 | 
						|
          if (next === 0) { | 
						|
            unclosed('comment', '*/'); | 
						|
          } | 
						|
 | 
						|
          content = css.slice(start, next + 1); | 
						|
          lines = content.split('\n'); | 
						|
          last = lines.length - 1; | 
						|
 | 
						|
          if (last > 0) { | 
						|
            nextLine = line + last; | 
						|
            nextOffset = next - lines[last].length; | 
						|
          } else { | 
						|
            nextLine = line; | 
						|
            nextOffset = offset; | 
						|
          } | 
						|
 | 
						|
          tokenType = t.comment; | 
						|
          line = nextLine; | 
						|
          endLine = nextLine; | 
						|
          endColumn = next - nextOffset; | 
						|
        } else if (code === t.slash) { | 
						|
          next = start; | 
						|
          tokenType = code; | 
						|
          endLine = line; | 
						|
          endColumn = start - offset; | 
						|
          end = next + 1; | 
						|
        } else { | 
						|
          next = consumeWord(css, start); | 
						|
          tokenType = t.word; | 
						|
          endLine = line; | 
						|
          endColumn = next - offset; | 
						|
        } | 
						|
 | 
						|
        end = next + 1; | 
						|
        break; | 
						|
    } // Ensure that the token structure remains consistent | 
						|
 | 
						|
 | 
						|
    tokens.push([tokenType, // [0] Token type | 
						|
    line, // [1] Starting line | 
						|
    start - offset, // [2] Starting column | 
						|
    endLine, // [3] Ending line | 
						|
    endColumn, // [4] Ending column | 
						|
    start, // [5] Start position / Source index | 
						|
    end // [6] End position | 
						|
    ]); // Reset offset for the next token | 
						|
 | 
						|
    if (nextOffset) { | 
						|
      offset = nextOffset; | 
						|
      nextOffset = null; | 
						|
    } | 
						|
 | 
						|
    start = end; | 
						|
  } | 
						|
 | 
						|
  return tokens; | 
						|
} |