mirror of
https://github.com/idanoo/GoScrobble
synced 2025-07-01 13:42:20 +00:00
0.2.0 - Mid migration
This commit is contained in:
parent
139e6a915e
commit
7e38fdbd7d
42393 changed files with 5358157 additions and 62 deletions
48
web/node_modules/postcss-values-parser/old-lib/container.js
generated
vendored
Normal file
48
web/node_modules/postcss-values-parser/old-lib/container.js
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
const Node = require('./node');
|
||||
|
||||
class Container extends Node {
|
||||
walk(callback) {
|
||||
return this.each((child, i) => {
|
||||
let result = callback(child, i);
|
||||
if (result !== false && child.walk) {
|
||||
result = child.walk(callback);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
walkType(type, callback) {
|
||||
if (!type || !callback) {
|
||||
throw new Error('Parameters {type} and {callback} are required.');
|
||||
}
|
||||
|
||||
// allow users to pass a constructor, or node type string; eg. Word.
|
||||
const isTypeCallable = typeof type === 'function';
|
||||
|
||||
return this.walk((node, index) => {
|
||||
if ((isTypeCallable && node instanceof type) || (!isTypeCallable && node.type === type)) {
|
||||
return callback.call(this, node, index);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Container.registerWalker = (constructor) => {
|
||||
let walkerName = `walk${constructor.name}`;
|
||||
|
||||
// plural sugar
|
||||
if (walkerName.lastIndexOf('s') !== walkerName.length - 1) {
|
||||
walkerName += 's';
|
||||
}
|
||||
|
||||
if (Container.prototype[walkerName]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// we need access to `this` so we can't use an arrow function
|
||||
Container.prototype[walkerName] = function(callback) {
|
||||
return this.walkType(constructor, callback);
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = Container;
|
576
web/node_modules/postcss-values-parser/old-lib/parser.js
generated
vendored
Normal file
576
web/node_modules/postcss-values-parser/old-lib/parser.js
generated
vendored
Normal file
|
@ -0,0 +1,576 @@
|
|||
'use strict';
|
||||
|
||||
const Root = require('./root');
|
||||
const Value = require('./value');
|
||||
|
||||
const AtWord = require('./atword');
|
||||
const Colon = require('./colon');
|
||||
const Comma = require('./comma');
|
||||
const Comment = require('./comment');
|
||||
const Func = require('./function');
|
||||
const Numbr = require('./number');
|
||||
const Operator = require('./operator');
|
||||
const Paren = require('./paren');
|
||||
const Str = require('./string');
|
||||
const Word = require('./word');
|
||||
const UnicodeRange = require('./unicode-range');
|
||||
|
||||
const tokenize = require('./tokenize');
|
||||
|
||||
const flatten = require('flatten');
|
||||
const indexesOf = require('indexes-of');
|
||||
const uniq = require('uniq');
|
||||
const ParserError = require('./errors/ParserError');
|
||||
|
||||
function sortAscending (list) {
|
||||
return list.sort((a, b) => a - b);
|
||||
}
|
||||
|
||||
module.exports = class Parser {
|
||||
constructor (input, options) {
|
||||
const defaults = { loose: false };
|
||||
|
||||
// cache needs to be an array for values with more than 1 level of function nesting
|
||||
this.cache = [];
|
||||
this.input = input;
|
||||
this.options = Object.assign({}, defaults, options);
|
||||
this.position = 0;
|
||||
// we'll use this to keep track of the paren balance
|
||||
this.unbalanced = 0;
|
||||
this.root = new Root();
|
||||
|
||||
let value = new Value();
|
||||
|
||||
this.root.append(value);
|
||||
|
||||
this.current = value;
|
||||
this.tokens = tokenize(input, this.options);
|
||||
}
|
||||
|
||||
parse () {
|
||||
return this.loop();
|
||||
}
|
||||
|
||||
colon () {
|
||||
let token = this.currToken;
|
||||
|
||||
this.newNode(new Colon({
|
||||
value: token[1],
|
||||
source: {
|
||||
start: {
|
||||
line: token[2],
|
||||
column: token[3]
|
||||
},
|
||||
end: {
|
||||
line: token[4],
|
||||
column: token[5]
|
||||
}
|
||||
},
|
||||
sourceIndex: token[6]
|
||||
}));
|
||||
|
||||
this.position ++;
|
||||
}
|
||||
|
||||
comma () {
|
||||
let token = this.currToken;
|
||||
|
||||
this.newNode(new Comma({
|
||||
value: token[1],
|
||||
source: {
|
||||
start: {
|
||||
line: token[2],
|
||||
column: token[3]
|
||||
},
|
||||
end: {
|
||||
line: token[4],
|
||||
column: token[5]
|
||||
}
|
||||
},
|
||||
sourceIndex: token[6]
|
||||
}));
|
||||
|
||||
this.position ++;
|
||||
}
|
||||
|
||||
comment () {
|
||||
let inline = false,
|
||||
value = this.currToken[1].replace(/\/\*|\*\//g, ''),
|
||||
node;
|
||||
|
||||
if (this.options.loose && value.startsWith("//")) {
|
||||
value = value.substring(2);
|
||||
inline = true;
|
||||
}
|
||||
|
||||
node = new Comment({
|
||||
value: value,
|
||||
inline: inline,
|
||||
source: {
|
||||
start: {
|
||||
line: this.currToken[2],
|
||||
column: this.currToken[3]
|
||||
},
|
||||
end: {
|
||||
line: this.currToken[4],
|
||||
column: this.currToken[5]
|
||||
}
|
||||
},
|
||||
sourceIndex: this.currToken[6]
|
||||
});
|
||||
|
||||
this.newNode(node);
|
||||
this.position++;
|
||||
}
|
||||
|
||||
error (message, token) {
|
||||
throw new ParserError(message + ` at line: ${token[2]}, column ${token[3]}`);
|
||||
}
|
||||
|
||||
loop () {
|
||||
while (this.position < this.tokens.length) {
|
||||
this.parseTokens();
|
||||
}
|
||||
|
||||
if (!this.current.last && this.spaces) {
|
||||
this.current.raws.before += this.spaces;
|
||||
}
|
||||
else if (this.spaces) {
|
||||
this.current.last.raws.after += this.spaces;
|
||||
}
|
||||
|
||||
this.spaces = '';
|
||||
|
||||
return this.root;
|
||||
}
|
||||
|
||||
operator () {
|
||||
|
||||
// if a +|- operator is followed by a non-word character (. is allowed) and
|
||||
// is preceded by a non-word character. (5+5)
|
||||
let char = this.currToken[1],
|
||||
node;
|
||||
|
||||
if (char === '+' || char === '-') {
|
||||
// only inspect if the operator is not the first token, and we're only
|
||||
// within a calc() function: the only spec-valid place for math expressions
|
||||
if (!this.options.loose) {
|
||||
if (this.position > 0) {
|
||||
if (this.current.type === 'func' && this.current.value === 'calc') {
|
||||
// allow operators to be proceeded by spaces and opening parens
|
||||
if (this.prevToken[0] !== 'space' && this.prevToken[0] !== '(') {
|
||||
this.error('Syntax Error', this.currToken);
|
||||
}
|
||||
// valid: calc(1 - +2)
|
||||
// invalid: calc(1 -+2)
|
||||
else if (this.nextToken[0] !== 'space' && this.nextToken[0] !== 'word') {
|
||||
this.error('Syntax Error', this.currToken);
|
||||
}
|
||||
// valid: calc(1 - +2)
|
||||
// valid: calc(-0.5 + 2)
|
||||
// invalid: calc(1 -2)
|
||||
else if (this.nextToken[0] === 'word' && this.current.last.type !== 'operator' &&
|
||||
this.current.last.value !== '(') {
|
||||
this.error('Syntax Error', this.currToken);
|
||||
}
|
||||
}
|
||||
// if we're not in a function and someone has doubled up on operators,
|
||||
// or they're trying to perform a calc outside of a calc
|
||||
// eg. +-4px or 5+ 5, throw an error
|
||||
else if (this.nextToken[0] === 'space'
|
||||
|| this.nextToken[0] === 'operator'
|
||||
|| this.prevToken[0] === 'operator') {
|
||||
this.error('Syntax Error', this.currToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.options.loose) {
|
||||
if (this.nextToken[0] === 'word') {
|
||||
return this.word();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((!this.current.nodes.length || (this.current.last && this.current.last.type === 'operator')) && this.nextToken[0] === 'word') {
|
||||
return this.word();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
node = new Operator({
|
||||
value: this.currToken[1],
|
||||
source: {
|
||||
start: {
|
||||
line: this.currToken[2],
|
||||
column: this.currToken[3]
|
||||
},
|
||||
end: {
|
||||
line: this.currToken[2],
|
||||
column: this.currToken[3]
|
||||
}
|
||||
},
|
||||
sourceIndex: this.currToken[4]
|
||||
});
|
||||
|
||||
this.position ++;
|
||||
|
||||
return this.newNode(node);
|
||||
}
|
||||
|
||||
parseTokens () {
|
||||
switch (this.currToken[0]) {
|
||||
case 'space':
|
||||
this.space();
|
||||
break;
|
||||
case 'colon':
|
||||
this.colon();
|
||||
break;
|
||||
case 'comma':
|
||||
this.comma();
|
||||
break;
|
||||
case 'comment':
|
||||
this.comment();
|
||||
break;
|
||||
case '(':
|
||||
this.parenOpen();
|
||||
break;
|
||||
case ')':
|
||||
this.parenClose();
|
||||
break;
|
||||
case 'atword':
|
||||
case 'word':
|
||||
this.word();
|
||||
break;
|
||||
case 'operator':
|
||||
this.operator();
|
||||
break;
|
||||
case 'string':
|
||||
this.string();
|
||||
break;
|
||||
case 'unicoderange':
|
||||
this.unicodeRange();
|
||||
break;
|
||||
default:
|
||||
this.word();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
parenOpen () {
|
||||
let unbalanced = 1,
|
||||
pos = this.position + 1,
|
||||
token = this.currToken,
|
||||
last;
|
||||
|
||||
// check for balanced parens
|
||||
while (pos < this.tokens.length && unbalanced) {
|
||||
let tkn = this.tokens[pos];
|
||||
|
||||
if (tkn[0] === '(') {
|
||||
unbalanced++;
|
||||
}
|
||||
if (tkn[0] === ')') {
|
||||
unbalanced--;
|
||||
}
|
||||
pos ++;
|
||||
}
|
||||
|
||||
if (unbalanced) {
|
||||
this.error('Expected closing parenthesis', token);
|
||||
}
|
||||
|
||||
// ok, all parens are balanced. continue on
|
||||
|
||||
last = this.current.last;
|
||||
|
||||
if (last && last.type === 'func' && last.unbalanced < 0) {
|
||||
last.unbalanced = 0; // ok we're ready to add parens now
|
||||
this.current = last;
|
||||
}
|
||||
|
||||
this.current.unbalanced ++;
|
||||
|
||||
this.newNode(new Paren({
|
||||
value: token[1],
|
||||
source: {
|
||||
start: {
|
||||
line: token[2],
|
||||
column: token[3]
|
||||
},
|
||||
end: {
|
||||
line: token[4],
|
||||
column: token[5]
|
||||
}
|
||||
},
|
||||
sourceIndex: token[6]
|
||||
}));
|
||||
|
||||
this.position ++;
|
||||
|
||||
// url functions get special treatment, and anything between the function
|
||||
// parens get treated as one word, if the contents aren't not a string.
|
||||
if (this.current.type === 'func' && this.current.unbalanced &&
|
||||
this.current.value === 'url' && this.currToken[0] !== 'string' &&
|
||||
this.currToken[0] !== ')' && !this.options.loose) {
|
||||
|
||||
let nextToken = this.nextToken,
|
||||
value = this.currToken[1],
|
||||
start = {
|
||||
line: this.currToken[2],
|
||||
column: this.currToken[3]
|
||||
};
|
||||
|
||||
while (nextToken && nextToken[0] !== ')' && this.current.unbalanced) {
|
||||
this.position ++;
|
||||
value += this.currToken[1];
|
||||
nextToken = this.nextToken;
|
||||
}
|
||||
|
||||
if (this.position !== this.tokens.length - 1) {
|
||||
// skip the following word definition, or it'll be a duplicate
|
||||
this.position ++;
|
||||
|
||||
this.newNode(new Word({
|
||||
value,
|
||||
source: {
|
||||
start,
|
||||
end: {
|
||||
line: this.currToken[4],
|
||||
column: this.currToken[5]
|
||||
}
|
||||
},
|
||||
sourceIndex: this.currToken[6]
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parenClose () {
|
||||
let token = this.currToken;
|
||||
|
||||
this.newNode(new Paren({
|
||||
value: token[1],
|
||||
source: {
|
||||
start: {
|
||||
line: token[2],
|
||||
column: token[3]
|
||||
},
|
||||
end: {
|
||||
line: token[4],
|
||||
column: token[5]
|
||||
}
|
||||
},
|
||||
sourceIndex: token[6]
|
||||
}));
|
||||
|
||||
this.position ++;
|
||||
|
||||
if (this.position >= this.tokens.length - 1 && !this.current.unbalanced) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.current.unbalanced --;
|
||||
|
||||
if (this.current.unbalanced < 0) {
|
||||
this.error('Expected opening parenthesis', token);
|
||||
}
|
||||
|
||||
if (!this.current.unbalanced && this.cache.length) {
|
||||
this.current = this.cache.pop();
|
||||
}
|
||||
}
|
||||
|
||||
space () {
|
||||
let token = this.currToken;
|
||||
// Handle space before and after the selector
|
||||
if (this.position === (this.tokens.length - 1) || this.nextToken[0] === ',' || this.nextToken[0] === ')') {
|
||||
this.current.last.raws.after += token[1];
|
||||
this.position ++;
|
||||
}
|
||||
else {
|
||||
this.spaces = token[1];
|
||||
this.position ++;
|
||||
}
|
||||
}
|
||||
|
||||
unicodeRange () {
|
||||
let token = this.currToken;
|
||||
|
||||
this.newNode(new UnicodeRange({
|
||||
value: token[1],
|
||||
source: {
|
||||
start: {
|
||||
line: token[2],
|
||||
column: token[3]
|
||||
},
|
||||
end: {
|
||||
line: token[4],
|
||||
column: token[5]
|
||||
}
|
||||
},
|
||||
sourceIndex: token[6]
|
||||
}));
|
||||
|
||||
this.position ++;
|
||||
}
|
||||
|
||||
splitWord () {
|
||||
let nextToken = this.nextToken,
|
||||
word = this.currToken[1],
|
||||
rNumber = /^[\+\-]?((\d+(\.\d*)?)|(\.\d+))([eE][\+\-]?\d+)?/,
|
||||
|
||||
// treat css-like groupings differently so they can be inspected,
|
||||
// but don't address them as anything but a word, but allow hex values
|
||||
// to pass through.
|
||||
rNoFollow = /^(?!\#([a-z0-9]+))[\#\{\}]/gi,
|
||||
|
||||
hasAt, indices;
|
||||
|
||||
if (!rNoFollow.test(word)) {
|
||||
while (nextToken && nextToken[0] === 'word') {
|
||||
this.position ++;
|
||||
|
||||
let current = this.currToken[1];
|
||||
word += current;
|
||||
|
||||
nextToken = this.nextToken;
|
||||
}
|
||||
}
|
||||
|
||||
hasAt = indexesOf(word, '@');
|
||||
indices = sortAscending(uniq(flatten([[0], hasAt])));
|
||||
|
||||
indices.forEach((ind, i) => {
|
||||
let index = indices[i + 1] || word.length,
|
||||
value = word.slice(ind, index),
|
||||
node;
|
||||
|
||||
if (~hasAt.indexOf(ind)) {
|
||||
node = new AtWord({
|
||||
value: value.slice(1),
|
||||
source: {
|
||||
start: {
|
||||
line: this.currToken[2],
|
||||
column: this.currToken[3] + ind
|
||||
},
|
||||
end: {
|
||||
line: this.currToken[4],
|
||||
column: this.currToken[3] + (index - 1)
|
||||
}
|
||||
},
|
||||
sourceIndex: this.currToken[6] + indices[i]
|
||||
});
|
||||
}
|
||||
else if (rNumber.test(this.currToken[1])) {
|
||||
let unit = value.replace(rNumber, '');
|
||||
|
||||
node = new Numbr({
|
||||
value: value.replace(unit, ''),
|
||||
source: {
|
||||
start: {
|
||||
line: this.currToken[2],
|
||||
column: this.currToken[3] + ind
|
||||
},
|
||||
end: {
|
||||
line: this.currToken[4],
|
||||
column: this.currToken[3] + (index - 1)
|
||||
}
|
||||
},
|
||||
sourceIndex: this.currToken[6] + indices[i],
|
||||
unit
|
||||
});
|
||||
}
|
||||
else {
|
||||
node = new (nextToken && nextToken[0] === '(' ? Func : Word)({
|
||||
value,
|
||||
source: {
|
||||
start: {
|
||||
line: this.currToken[2],
|
||||
column: this.currToken[3] + ind
|
||||
},
|
||||
end: {
|
||||
line: this.currToken[4],
|
||||
column: this.currToken[3] + (index - 1)
|
||||
}
|
||||
},
|
||||
sourceIndex: this.currToken[6] + indices[i]
|
||||
});
|
||||
|
||||
if (node.constructor.name === 'Word') {
|
||||
node.isHex = /^#(.+)/.test(value);
|
||||
node.isColor = /^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(value);
|
||||
}
|
||||
else {
|
||||
this.cache.push(this.current);
|
||||
}
|
||||
}
|
||||
|
||||
this.newNode(node);
|
||||
|
||||
});
|
||||
|
||||
this.position ++;
|
||||
}
|
||||
|
||||
string () {
|
||||
let token = this.currToken,
|
||||
value = this.currToken[1],
|
||||
rQuote = /^(\"|\')/,
|
||||
quoted = rQuote.test(value),
|
||||
quote = '',
|
||||
node;
|
||||
|
||||
if (quoted) {
|
||||
quote = value.match(rQuote)[0];
|
||||
// set value to the string within the quotes
|
||||
// quotes are stored in raws
|
||||
value = value.slice(1, value.length - 1);
|
||||
}
|
||||
|
||||
node = new Str({
|
||||
value,
|
||||
source: {
|
||||
start: {
|
||||
line: token[2],
|
||||
column: token[3]
|
||||
},
|
||||
end: {
|
||||
line: token[4],
|
||||
column: token[5]
|
||||
}
|
||||
},
|
||||
sourceIndex: token[6],
|
||||
quoted
|
||||
});
|
||||
|
||||
node.raws.quote = quote;
|
||||
|
||||
this.newNode(node);
|
||||
this.position++;
|
||||
}
|
||||
|
||||
word () {
|
||||
return this.splitWord();
|
||||
}
|
||||
|
||||
newNode (node) {
|
||||
if (this.spaces) {
|
||||
node.raws.before += this.spaces;
|
||||
this.spaces = '';
|
||||
}
|
||||
|
||||
return this.current.append(node);
|
||||
}
|
||||
|
||||
get currToken () {
|
||||
return this.tokens[this.position];
|
||||
}
|
||||
|
||||
get nextToken () {
|
||||
return this.tokens[this.position + 1];
|
||||
}
|
||||
|
||||
get prevToken () {
|
||||
return this.tokens[this.position - 1];
|
||||
}
|
||||
};
|
416
web/node_modules/postcss-values-parser/old-lib/tokenize.js
generated
vendored
Normal file
416
web/node_modules/postcss-values-parser/old-lib/tokenize.js
generated
vendored
Normal file
|
@ -0,0 +1,416 @@
|
|||
const openBracket = '{'.charCodeAt(0);
|
||||
const closeBracket = '}'.charCodeAt(0);
|
||||
const openParen = '('.charCodeAt(0);
|
||||
const closeParen = ')'.charCodeAt(0);
|
||||
const singleQuote = "'".charCodeAt(0);
|
||||
const doubleQuote = '"'.charCodeAt(0);
|
||||
const backslash = '\\'.charCodeAt(0);
|
||||
const slash = '/'.charCodeAt(0);
|
||||
const period = '.'.charCodeAt(0);
|
||||
const comma = ','.charCodeAt(0);
|
||||
const colon = ':'.charCodeAt(0);
|
||||
const asterisk = '*'.charCodeAt(0);
|
||||
const minus = '-'.charCodeAt(0);
|
||||
const plus = '+'.charCodeAt(0);
|
||||
const pound = '#'.charCodeAt(0);
|
||||
const newline = '\n'.charCodeAt(0);
|
||||
const space = ' '.charCodeAt(0);
|
||||
const feed = '\f'.charCodeAt(0);
|
||||
const tab = '\t'.charCodeAt(0);
|
||||
const cr = '\r'.charCodeAt(0);
|
||||
const at = '@'.charCodeAt(0);
|
||||
const lowerE = 'e'.charCodeAt(0);
|
||||
const upperE = 'E'.charCodeAt(0);
|
||||
const digit0 = '0'.charCodeAt(0);
|
||||
const digit9 = '9'.charCodeAt(0);
|
||||
const lowerU = 'u'.charCodeAt(0);
|
||||
const upperU = 'U'.charCodeAt(0);
|
||||
const atEnd = /[ \n\t\r\{\(\)'"\\;,/]/g;
|
||||
const wordEnd = /[ \n\t\r\(\)\{\}\*:;@!&'"\+\|~>,\[\]\\]|\/(?=\*)/g;
|
||||
const wordEndNum = /[ \n\t\r\(\)\{\}\*:;@!&'"\-\+\|~>,\[\]\\]|\//g;
|
||||
const alphaNum = /^[a-z0-9]/i;
|
||||
const unicodeRange = /^[a-f0-9?\-]/i;
|
||||
|
||||
const util = require('util');
|
||||
|
||||
const TokenizeError = require('./errors/TokenizeError');
|
||||
|
||||
module.exports = function tokenize(input, options) {
|
||||
options = options || {};
|
||||
|
||||
const tokens = [];
|
||||
|
||||
const css = input.valueOf();
|
||||
|
||||
const length = css.length;
|
||||
|
||||
let offset = -1;
|
||||
|
||||
let line = 1;
|
||||
|
||||
let pos = 0;
|
||||
|
||||
let parentCount = 0;
|
||||
|
||||
let isURLArg = null;
|
||||
|
||||
let code;
|
||||
let next;
|
||||
let quote;
|
||||
let lines;
|
||||
let last;
|
||||
let content;
|
||||
let escape;
|
||||
let nextLine;
|
||||
let nextOffset;
|
||||
|
||||
let escaped;
|
||||
let escapePos;
|
||||
let nextChar;
|
||||
|
||||
function unclosed(what) {
|
||||
const message = util.format(
|
||||
'Unclosed %s at line: %d, column: %d, token: %d',
|
||||
what,
|
||||
line,
|
||||
pos - offset,
|
||||
pos
|
||||
);
|
||||
throw new TokenizeError(message);
|
||||
}
|
||||
|
||||
function tokenizeError() {
|
||||
const message = util.format(
|
||||
'Syntax error at line: %d, column: %d, token: %d',
|
||||
line,
|
||||
pos - offset,
|
||||
pos
|
||||
);
|
||||
throw new TokenizeError(message);
|
||||
}
|
||||
|
||||
while (pos < length) {
|
||||
code = css.charCodeAt(pos);
|
||||
|
||||
if (code === newline) {
|
||||
offset = pos;
|
||||
line += 1;
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
case newline:
|
||||
case space:
|
||||
case tab:
|
||||
case cr:
|
||||
case feed:
|
||||
next = pos;
|
||||
do {
|
||||
next += 1;
|
||||
code = css.charCodeAt(next);
|
||||
if (code === newline) {
|
||||
offset = next;
|
||||
line += 1;
|
||||
}
|
||||
} while (
|
||||
code === space ||
|
||||
code === newline ||
|
||||
code === tab ||
|
||||
code === cr ||
|
||||
code === feed
|
||||
);
|
||||
|
||||
tokens.push(['space', css.slice(pos, next), line, pos - offset, line, next - offset, pos]);
|
||||
|
||||
pos = next - 1;
|
||||
break;
|
||||
|
||||
case colon:
|
||||
next = pos + 1;
|
||||
tokens.push(['colon', css.slice(pos, next), line, pos - offset, line, next - offset, pos]);
|
||||
|
||||
pos = next - 1;
|
||||
break;
|
||||
|
||||
case comma:
|
||||
next = pos + 1;
|
||||
tokens.push(['comma', css.slice(pos, next), line, pos - offset, line, next - offset, pos]);
|
||||
|
||||
pos = next - 1;
|
||||
break;
|
||||
|
||||
case openBracket:
|
||||
tokens.push(['{', '{', line, pos - offset, line, next - offset, pos]);
|
||||
break;
|
||||
|
||||
case closeBracket:
|
||||
tokens.push(['}', '}', line, pos - offset, line, next - offset, pos]);
|
||||
break;
|
||||
|
||||
case openParen:
|
||||
parentCount++;
|
||||
isURLArg =
|
||||
!isURLArg &&
|
||||
parentCount === 1 &&
|
||||
tokens.length > 0 &&
|
||||
tokens[tokens.length - 1][0] === 'word' &&
|
||||
tokens[tokens.length - 1][1] === 'url';
|
||||
tokens.push(['(', '(', line, pos - offset, line, next - offset, pos]);
|
||||
break;
|
||||
|
||||
case closeParen:
|
||||
parentCount--;
|
||||
isURLArg = !isURLArg && parentCount === 1;
|
||||
tokens.push([')', ')', line, pos - offset, line, next - offset, pos]);
|
||||
break;
|
||||
|
||||
case singleQuote:
|
||||
case doubleQuote:
|
||||
quote = code === singleQuote ? "'" : '"';
|
||||
next = pos;
|
||||
do {
|
||||
escaped = false;
|
||||
next = css.indexOf(quote, next + 1);
|
||||
if (next === -1) {
|
||||
unclosed('quote', quote);
|
||||
}
|
||||
escapePos = next;
|
||||
while (css.charCodeAt(escapePos - 1) === backslash) {
|
||||
escapePos -= 1;
|
||||
escaped = !escaped;
|
||||
}
|
||||
} while (escaped);
|
||||
|
||||
tokens.push([
|
||||
'string',
|
||||
css.slice(pos, next + 1),
|
||||
line,
|
||||
pos - offset,
|
||||
line,
|
||||
next - offset,
|
||||
pos
|
||||
]);
|
||||
pos = next;
|
||||
break;
|
||||
|
||||
case at:
|
||||
atEnd.lastIndex = pos + 1;
|
||||
atEnd.test(css);
|
||||
|
||||
if (atEnd.lastIndex === 0) {
|
||||
next = css.length - 1;
|
||||
} else {
|
||||
next = atEnd.lastIndex - 2;
|
||||
}
|
||||
|
||||
tokens.push([
|
||||
'atword',
|
||||
css.slice(pos, next + 1),
|
||||
line,
|
||||
pos - offset,
|
||||
line,
|
||||
next - offset,
|
||||
pos
|
||||
]);
|
||||
pos = next;
|
||||
break;
|
||||
|
||||
case backslash:
|
||||
next = pos;
|
||||
code = css.charCodeAt(next + 1);
|
||||
|
||||
if (
|
||||
escape &&
|
||||
(code !== slash &&
|
||||
code !== space &&
|
||||
code !== newline &&
|
||||
code !== tab &&
|
||||
code !== cr &&
|
||||
code !== feed)
|
||||
) {
|
||||
next += 1;
|
||||
}
|
||||
|
||||
tokens.push([
|
||||
'word',
|
||||
css.slice(pos, next + 1),
|
||||
line,
|
||||
pos - offset,
|
||||
line,
|
||||
next - offset,
|
||||
pos
|
||||
]);
|
||||
|
||||
pos = next;
|
||||
break;
|
||||
|
||||
case plus:
|
||||
case minus:
|
||||
case asterisk:
|
||||
next = pos + 1;
|
||||
nextChar = css.slice(pos + 1, next + 1);
|
||||
|
||||
const prevChar = css.slice(pos - 1, pos);
|
||||
|
||||
// if the operator is immediately followed by a word character, then we
|
||||
// have a prefix of some kind, and should fall-through. eg. -webkit
|
||||
|
||||
// look for --* for custom variables
|
||||
if (code === minus && nextChar.charCodeAt(0) === minus) {
|
||||
next++;
|
||||
|
||||
tokens.push(['word', css.slice(pos, next), line, pos - offset, line, next - offset, pos]);
|
||||
|
||||
pos = next - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
tokens.push([
|
||||
'operator',
|
||||
css.slice(pos, next),
|
||||
line,
|
||||
pos - offset,
|
||||
line,
|
||||
next - offset,
|
||||
pos
|
||||
]);
|
||||
|
||||
pos = next - 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (
|
||||
code === slash &&
|
||||
(css.charCodeAt(pos + 1) === asterisk ||
|
||||
(options.loose && !isURLArg && css.charCodeAt(pos + 1) === slash))
|
||||
) {
|
||||
const isStandardComment = css.charCodeAt(pos + 1) === asterisk;
|
||||
|
||||
if (isStandardComment) {
|
||||
next = css.indexOf('*/', pos + 2) + 1;
|
||||
if (next === 0) {
|
||||
unclosed('comment', '*/');
|
||||
}
|
||||
} else {
|
||||
const newlinePos = css.indexOf('\n', pos + 2);
|
||||
|
||||
next = newlinePos !== -1 ? newlinePos - 1 : length;
|
||||
}
|
||||
|
||||
content = css.slice(pos, 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;
|
||||
}
|
||||
|
||||
tokens.push(['comment', content, line, pos - offset, nextLine, next - nextOffset, pos]);
|
||||
|
||||
offset = nextOffset;
|
||||
line = nextLine;
|
||||
pos = next;
|
||||
} else if (code === pound && !alphaNum.test(css.slice(pos + 1, pos + 2))) {
|
||||
next = pos + 1;
|
||||
|
||||
tokens.push(['#', css.slice(pos, next), line, pos - offset, line, next - offset, pos]);
|
||||
|
||||
pos = next - 1;
|
||||
} else if ((code === lowerU || code === upperU) && css.charCodeAt(pos + 1) === plus) {
|
||||
next = pos + 2;
|
||||
|
||||
do {
|
||||
next += 1;
|
||||
code = css.charCodeAt(next);
|
||||
} while (next < length && unicodeRange.test(css.slice(next, next + 1)));
|
||||
|
||||
tokens.push([
|
||||
'unicoderange',
|
||||
css.slice(pos, next),
|
||||
line,
|
||||
pos - offset,
|
||||
line,
|
||||
next - offset,
|
||||
pos
|
||||
]);
|
||||
pos = next - 1;
|
||||
}
|
||||
// catch a regular slash, that isn't a comment
|
||||
else if (code === slash) {
|
||||
next = pos + 1;
|
||||
|
||||
tokens.push([
|
||||
'operator',
|
||||
css.slice(pos, next),
|
||||
line,
|
||||
pos - offset,
|
||||
line,
|
||||
next - offset,
|
||||
pos
|
||||
]);
|
||||
|
||||
pos = next - 1;
|
||||
} else {
|
||||
let regex = wordEnd;
|
||||
|
||||
// we're dealing with a word that starts with a number
|
||||
// those get treated differently
|
||||
if (code >= digit0 && code <= digit9) {
|
||||
regex = wordEndNum;
|
||||
}
|
||||
|
||||
regex.lastIndex = pos + 1;
|
||||
regex.test(css);
|
||||
|
||||
if (regex.lastIndex === 0) {
|
||||
next = css.length - 1;
|
||||
} else {
|
||||
next = regex.lastIndex - 2;
|
||||
}
|
||||
|
||||
// Exponential number notation with minus or plus: 1e-10, 1e+10
|
||||
if (regex === wordEndNum || code === period) {
|
||||
const ncode = css.charCodeAt(next);
|
||||
|
||||
const ncode1 = css.charCodeAt(next + 1);
|
||||
|
||||
const ncode2 = css.charCodeAt(next + 2);
|
||||
|
||||
if (
|
||||
(ncode === lowerE || ncode === upperE) &&
|
||||
(ncode1 === minus || ncode1 === plus) &&
|
||||
(ncode2 >= digit0 && ncode2 <= digit9)
|
||||
) {
|
||||
wordEndNum.lastIndex = next + 2;
|
||||
wordEndNum.test(css);
|
||||
|
||||
if (wordEndNum.lastIndex === 0) {
|
||||
next = css.length - 1;
|
||||
} else {
|
||||
next = wordEndNum.lastIndex - 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tokens.push([
|
||||
'word',
|
||||
css.slice(pos, next + 1),
|
||||
line,
|
||||
pos - offset,
|
||||
line,
|
||||
next - offset,
|
||||
pos
|
||||
]);
|
||||
pos = next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
return tokens;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue