Files
Monkey-Test/WebDriverAgent/Inspector/node_modules/postcss-value-parser/lib/tokenize.js
T
2019-01-25 17:01:52 +08:00

174 lines
5.4 KiB
JavaScript

'use strict';
var singleQuote = '\''.charCodeAt(0);
var doubleQuote = '"'.charCodeAt(0);
var backslash = '\\'.charCodeAt(0);
var slash = '/'.charCodeAt(0);
var newline = '\n'.charCodeAt(0);
var space = ' '.charCodeAt(0);
var feed = '\f'.charCodeAt(0);
var tab = '\t'.charCodeAt(0);
var cr = '\r'.charCodeAt(0);
var comma = ','.charCodeAt(0);
var colon = ':'.charCodeAt(0);
var openBracket = '('.charCodeAt(0);
var closeBracket = ')'.charCodeAt(0);
module.exports = function (input) {
var tokens = [];
var value = input;
var code, next, quote, escape, escapePos, last, nodes;
var length = value.length;
var pos = 0;
var stack = [tokens];
var balanced = 0;
while (pos < length) {
code = value.charCodeAt(pos);
last = tokens[tokens.length - 1];
switch (code) {
case newline:
case space:
case tab:
case cr:
case feed:
next = pos;
do {
next += 1;
if (next === length) {
break;
}
code = value.charCodeAt(next);
} while (code === space ||
code === newline ||
code === tab ||
code === cr ||
code === feed);
if (last && last.type === 'div') {
last.after = value.slice(pos, next);
} else {
tokens.push({
type: 'space',
value: value.slice(pos, next)
});
}
pos = next - 1;
break;
case comma:
case colon:
case slash:
last = last && last.type === 'space' ? tokens.pop() : null;
tokens.push({
type: 'div',
value: String.fromCharCode(code),
before: last && last.type === 'space' ? last.value : '',
after: ''
});
break;
case openBracket:
balanced += 1;
nodes = [];
tokens.push({
type: 'function',
value: last && last.type === 'word' ? tokens.pop().value : '',
nodes: nodes
});
stack.push(nodes);
tokens = nodes;
break;
case closeBracket:
balanced -= 1;
tokens = stack[balanced];
break;
case singleQuote:
case doubleQuote:
quote = String.fromCharCode(code);
next = pos;
do {
escape = false;
next = value.indexOf(quote, next + 1);
if (next === -1) {
value += quote;
next = value.length - 1;
}
escapePos = next;
while (value.charCodeAt(escapePos - 1) === backslash) {
escapePos -= 1;
escape = !escape;
}
} while (escape);
tokens.push({
type: 'string',
quote: quote,
value: value.slice(pos + 1, next)
});
pos = next;
break;
case backslash:
next = pos;
escape = true;
while (value.charCodeAt(next + 1) === backslash) {
next += 1;
escape = !escape;
}
code = value.charCodeAt(next + 1);
if (escape && code !== slash &&
code !== space &&
code !== newline &&
code !== tab &&
code !== cr &&
code !== feed) {
next += 1;
}
tokens.push({
type: 'word',
value: value.slice(pos, next + 1)
});
pos = next;
break;
default:
next = pos;
do {
next += 1;
if (next === length) {
break;
}
code = value.charCodeAt(next);
} while (code !== singleQuote &&
code !== doubleQuote &&
code !== backslash &&
code !== slash &&
code !== newline &&
code !== space &&
code !== feed &&
code !== tab &&
code !== cr &&
code !== comma &&
code !== colon &&
code !== openBracket &&
code !== closeBracket);
tokens.push({
type: 'word',
value: value.slice(pos, next)
});
pos = next - 1;
break;
}
pos += 1;
}
return stack[0];
};