233 lines
7.0 KiB
Plaintext
233 lines
7.0 KiB
Plaintext
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.CSSTokenizer = void 0;
|
|
const EOF = -1;
|
|
const NULL = 0x00;
|
|
const TABULATION = 0x09;
|
|
const CARRIAGE_RETURN = 0x0d;
|
|
const LINE_FEED = 0x0a;
|
|
const FORM_FEED = 0x0c;
|
|
const SPACE = 0x20;
|
|
const QUOTATION_MARK = 0x22;
|
|
const APOSTROPHE = 0x27;
|
|
const LEFT_PARENTHESIS = 0x28;
|
|
const RIGHT_PARENTHESIS = 0x29;
|
|
const ASTERISK = 0x2a;
|
|
const COMMA = 0x2c;
|
|
const SOLIDUS = 0x2f;
|
|
const COLON = 0x3a;
|
|
const SEMICOLON = 0x3b;
|
|
const LEFT_SQUARE_BRACKET = 0x5b;
|
|
const REVERSE_SOLIDUS = 0x5c;
|
|
const RIGHT_SQUARE_BRACKET = 0x5d;
|
|
const LEFT_CURLY_BRACKET = 0x7b;
|
|
const RIGHT_CURLY_BRACKET = 0x7d;
|
|
function isWhitespace(cp) {
|
|
return (cp === TABULATION ||
|
|
cp === LINE_FEED ||
|
|
cp === FORM_FEED ||
|
|
cp === CARRIAGE_RETURN ||
|
|
cp === SPACE);
|
|
}
|
|
class CSSTokenizer {
|
|
constructor(text, startOffset, options) {
|
|
var _a;
|
|
this.text = text;
|
|
this.options = {
|
|
inlineComment: (_a = options === null || options === void 0 ? void 0 : options.inlineComment) !== null && _a !== void 0 ? _a : false,
|
|
};
|
|
this.cp = NULL;
|
|
this.offset = startOffset - 1;
|
|
this.nextOffset = startOffset;
|
|
this.reconsuming = false;
|
|
}
|
|
nextToken() {
|
|
let cp;
|
|
if (this.reconsuming) {
|
|
cp = this.cp;
|
|
this.reconsuming = false;
|
|
}
|
|
else {
|
|
cp = this.consumeNextCodePoint();
|
|
}
|
|
while (isWhitespace(cp)) {
|
|
cp = this.consumeNextCodePoint();
|
|
}
|
|
if (cp === EOF) {
|
|
return null;
|
|
}
|
|
const start = this.offset;
|
|
return this.consumeNextToken(cp, start);
|
|
}
|
|
nextCodePoint() {
|
|
if (this.nextOffset >= this.text.length) {
|
|
return EOF;
|
|
}
|
|
return this.text.codePointAt(this.nextOffset);
|
|
}
|
|
consumeNextCodePoint() {
|
|
if (this.offset >= this.text.length) {
|
|
this.cp = EOF;
|
|
return EOF;
|
|
}
|
|
this.offset = this.nextOffset;
|
|
if (this.offset >= this.text.length) {
|
|
this.cp = EOF;
|
|
return EOF;
|
|
}
|
|
let cp = this.text.codePointAt(this.offset);
|
|
if (cp === CARRIAGE_RETURN) {
|
|
this.nextOffset = this.offset + 1;
|
|
if (this.text.codePointAt(this.nextOffset) === LINE_FEED) {
|
|
this.nextOffset++;
|
|
}
|
|
cp = LINE_FEED;
|
|
}
|
|
else {
|
|
this.nextOffset = this.offset + (cp >= 0x10000 ? 2 : 1);
|
|
}
|
|
this.cp = cp;
|
|
return cp;
|
|
}
|
|
consumeNextToken(cp, start) {
|
|
if (cp === SOLIDUS) {
|
|
const nextCp = this.nextCodePoint();
|
|
if (nextCp === ASTERISK) {
|
|
return this.consumeComment(start);
|
|
}
|
|
if (nextCp === SOLIDUS && this.options.inlineComment) {
|
|
return this.consumeInlineComment(start);
|
|
}
|
|
}
|
|
if (isQuote(cp)) {
|
|
return this.consumeString(start, cp);
|
|
}
|
|
if (isPunctuator(cp)) {
|
|
return {
|
|
type: "Punctuator",
|
|
range: [start, start + 1],
|
|
value: String.fromCodePoint(cp),
|
|
};
|
|
}
|
|
return this.consumeWord(start);
|
|
}
|
|
consumeWord(start) {
|
|
let cp = this.consumeNextCodePoint();
|
|
while (!isWhitespace(cp) && !isPunctuator(cp) && !isQuote(cp)) {
|
|
cp = this.consumeNextCodePoint();
|
|
}
|
|
this.reconsuming = true;
|
|
const range = [start, this.offset];
|
|
const text = this.text;
|
|
let value;
|
|
return {
|
|
type: "Word",
|
|
range,
|
|
get value() {
|
|
return value !== null && value !== void 0 ? value : (value = text.slice(...range));
|
|
},
|
|
};
|
|
}
|
|
consumeString(start, quote) {
|
|
let valueEndOffset = null;
|
|
let cp = this.consumeNextCodePoint();
|
|
while (cp !== EOF) {
|
|
if (cp === quote) {
|
|
valueEndOffset = this.offset;
|
|
break;
|
|
}
|
|
if (cp === REVERSE_SOLIDUS) {
|
|
this.consumeNextCodePoint();
|
|
}
|
|
cp = this.consumeNextCodePoint();
|
|
}
|
|
const text = this.text;
|
|
let value;
|
|
const valueRange = [
|
|
start + 1,
|
|
valueEndOffset !== null && valueEndOffset !== void 0 ? valueEndOffset : this.nextOffset,
|
|
];
|
|
return {
|
|
type: "Quoted",
|
|
range: [start, this.nextOffset],
|
|
valueRange,
|
|
get value() {
|
|
return value !== null && value !== void 0 ? value : (value = text.slice(...valueRange));
|
|
},
|
|
quote: String.fromCodePoint(quote),
|
|
};
|
|
}
|
|
consumeComment(start) {
|
|
this.consumeNextCodePoint();
|
|
let valueEndOffset = null;
|
|
let cp = this.consumeNextCodePoint();
|
|
while (cp !== EOF) {
|
|
if (cp === ASTERISK) {
|
|
cp = this.consumeNextCodePoint();
|
|
if (cp === SOLIDUS) {
|
|
valueEndOffset = this.offset - 1;
|
|
break;
|
|
}
|
|
}
|
|
cp = this.consumeNextCodePoint();
|
|
}
|
|
const valueRange = [
|
|
start + 2,
|
|
valueEndOffset !== null && valueEndOffset !== void 0 ? valueEndOffset : this.nextOffset,
|
|
];
|
|
const text = this.text;
|
|
let value;
|
|
return {
|
|
type: "Block",
|
|
range: [start, this.nextOffset],
|
|
valueRange,
|
|
get value() {
|
|
return value !== null && value !== void 0 ? value : (value = text.slice(...valueRange));
|
|
},
|
|
};
|
|
}
|
|
consumeInlineComment(start) {
|
|
this.consumeNextCodePoint();
|
|
let valueEndOffset = null;
|
|
let cp = this.consumeNextCodePoint();
|
|
while (cp !== EOF) {
|
|
if (cp === LINE_FEED) {
|
|
valueEndOffset = this.offset - 1;
|
|
break;
|
|
}
|
|
cp = this.consumeNextCodePoint();
|
|
}
|
|
const valueRange = [
|
|
start + 2,
|
|
valueEndOffset !== null && valueEndOffset !== void 0 ? valueEndOffset : this.nextOffset,
|
|
];
|
|
const text = this.text;
|
|
let value;
|
|
return {
|
|
type: "Line",
|
|
range: [start, this.nextOffset],
|
|
valueRange,
|
|
get value() {
|
|
return value !== null && value !== void 0 ? value : (value = text.slice(...valueRange));
|
|
},
|
|
};
|
|
}
|
|
}
|
|
exports.CSSTokenizer = CSSTokenizer;
|
|
function isPunctuator(cp) {
|
|
return (cp === COLON ||
|
|
cp === SEMICOLON ||
|
|
cp === COMMA ||
|
|
cp === LEFT_PARENTHESIS ||
|
|
cp === RIGHT_PARENTHESIS ||
|
|
cp === LEFT_CURLY_BRACKET ||
|
|
cp === RIGHT_CURLY_BRACKET ||
|
|
cp === LEFT_SQUARE_BRACKET ||
|
|
cp === RIGHT_SQUARE_BRACKET ||
|
|
cp === SOLIDUS ||
|
|
cp === ASTERISK);
|
|
}
|
|
function isQuote(cp) {
|
|
return cp === APOSTROPHE || cp === QUOTATION_MARK;
|
|
}
|