Fix code quality violations and exclude Manifest from checks
Document application modes (development/debug/production) Add global file drop handler, order column normalization, SPA hash fix Serve CDN assets via /_vendor/ URLs instead of merging into bundles Add production minification with license preservation Improve JSON formatting for debugging and production optimization Add CDN asset caching with CSS URL inlining for production builds Add three-mode system (development, debug, production) Update Manifest CLAUDE.md to reflect helper class architecture Refactor Manifest.php into helper classes for better organization Pre-manifest-refactor checkpoint: Add app_mode documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
91
node_modules/css-tree/cjs/tokenizer/OffsetToLocation.cjs
generated
vendored
Executable file
91
node_modules/css-tree/cjs/tokenizer/OffsetToLocation.cjs
generated
vendored
Executable file
@@ -0,0 +1,91 @@
|
||||
'use strict';
|
||||
|
||||
const adoptBuffer = require('./adopt-buffer.cjs');
|
||||
const charCodeDefinitions = require('./char-code-definitions.cjs');
|
||||
|
||||
const N = 10;
|
||||
const F = 12;
|
||||
const R = 13;
|
||||
|
||||
function computeLinesAndColumns(host) {
|
||||
const source = host.source;
|
||||
const sourceLength = source.length;
|
||||
const startOffset = source.length > 0 ? charCodeDefinitions.isBOM(source.charCodeAt(0)) : 0;
|
||||
const lines = adoptBuffer.adoptBuffer(host.lines, sourceLength);
|
||||
const columns = adoptBuffer.adoptBuffer(host.columns, sourceLength);
|
||||
let line = host.startLine;
|
||||
let column = host.startColumn;
|
||||
|
||||
for (let i = startOffset; i < sourceLength; i++) {
|
||||
const code = source.charCodeAt(i);
|
||||
|
||||
lines[i] = line;
|
||||
columns[i] = column++;
|
||||
|
||||
if (code === N || code === R || code === F) {
|
||||
if (code === R && i + 1 < sourceLength && source.charCodeAt(i + 1) === N) {
|
||||
i++;
|
||||
lines[i] = line;
|
||||
columns[i] = column;
|
||||
}
|
||||
|
||||
line++;
|
||||
column = 1;
|
||||
}
|
||||
}
|
||||
|
||||
lines[sourceLength] = line;
|
||||
columns[sourceLength] = column;
|
||||
|
||||
host.lines = lines;
|
||||
host.columns = columns;
|
||||
host.computed = true;
|
||||
}
|
||||
|
||||
class OffsetToLocation {
|
||||
constructor(source, startOffset, startLine, startColumn) {
|
||||
this.setSource(source, startOffset, startLine, startColumn);
|
||||
this.lines = null;
|
||||
this.columns = null;
|
||||
}
|
||||
setSource(source = '', startOffset = 0, startLine = 1, startColumn = 1) {
|
||||
this.source = source;
|
||||
this.startOffset = startOffset;
|
||||
this.startLine = startLine;
|
||||
this.startColumn = startColumn;
|
||||
this.computed = false;
|
||||
}
|
||||
getLocation(offset, filename) {
|
||||
if (!this.computed) {
|
||||
computeLinesAndColumns(this);
|
||||
}
|
||||
|
||||
return {
|
||||
source: filename,
|
||||
offset: this.startOffset + offset,
|
||||
line: this.lines[offset],
|
||||
column: this.columns[offset]
|
||||
};
|
||||
}
|
||||
getLocationRange(start, end, filename) {
|
||||
if (!this.computed) {
|
||||
computeLinesAndColumns(this);
|
||||
}
|
||||
|
||||
return {
|
||||
source: filename,
|
||||
start: {
|
||||
offset: this.startOffset + start,
|
||||
line: this.lines[start],
|
||||
column: this.columns[start]
|
||||
},
|
||||
end: {
|
||||
offset: this.startOffset + end,
|
||||
line: this.lines[end],
|
||||
column: this.columns[end]
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
exports.OffsetToLocation = OffsetToLocation;
|
||||
308
node_modules/css-tree/cjs/tokenizer/TokenStream.cjs
generated
vendored
Executable file
308
node_modules/css-tree/cjs/tokenizer/TokenStream.cjs
generated
vendored
Executable file
@@ -0,0 +1,308 @@
|
||||
'use strict';
|
||||
|
||||
const adoptBuffer = require('./adopt-buffer.cjs');
|
||||
const utils = require('./utils.cjs');
|
||||
const names = require('./names.cjs');
|
||||
const types = require('./types.cjs');
|
||||
|
||||
const OFFSET_MASK = 0x00FFFFFF;
|
||||
const TYPE_SHIFT = 24;
|
||||
const balancePair = new Uint8Array(32); // 32b of memory ought to be enough for anyone (any number of tokens)
|
||||
balancePair[types.Function] = types.RightParenthesis;
|
||||
balancePair[types.LeftParenthesis] = types.RightParenthesis;
|
||||
balancePair[types.LeftSquareBracket] = types.RightSquareBracket;
|
||||
balancePair[types.LeftCurlyBracket] = types.RightCurlyBracket;
|
||||
|
||||
function isBlockOpenerToken(tokenType) {
|
||||
return balancePair[tokenType] !== 0;
|
||||
}
|
||||
|
||||
class TokenStream {
|
||||
constructor(source, tokenize) {
|
||||
this.setSource(source, tokenize);
|
||||
}
|
||||
reset() {
|
||||
this.eof = false;
|
||||
this.tokenIndex = -1;
|
||||
this.tokenType = 0;
|
||||
this.tokenStart = this.firstCharOffset;
|
||||
this.tokenEnd = this.firstCharOffset;
|
||||
}
|
||||
setSource(source = '', tokenize = () => {}) {
|
||||
source = String(source || '');
|
||||
|
||||
const sourceLength = source.length;
|
||||
const offsetAndType = adoptBuffer.adoptBuffer(this.offsetAndType, source.length + 1); // +1 because of eof-token
|
||||
const balance = adoptBuffer.adoptBuffer(this.balance, source.length + 1);
|
||||
let tokenCount = 0;
|
||||
let firstCharOffset = -1;
|
||||
let balanceCloseType = 0;
|
||||
let balanceStart = source.length;
|
||||
|
||||
// capture buffers
|
||||
this.offsetAndType = null;
|
||||
this.balance = null;
|
||||
balance.fill(0);
|
||||
|
||||
tokenize(source, (type, start, end) => {
|
||||
const index = tokenCount++;
|
||||
|
||||
// type & offset
|
||||
offsetAndType[index] = (type << TYPE_SHIFT) | end;
|
||||
|
||||
if (firstCharOffset === -1) {
|
||||
firstCharOffset = start;
|
||||
}
|
||||
|
||||
// balance
|
||||
balance[index] = balanceStart;
|
||||
|
||||
if (type === balanceCloseType) {
|
||||
const prevBalanceStart = balance[balanceStart];
|
||||
|
||||
// set reference to balance end for a block opener
|
||||
balance[balanceStart] = index;
|
||||
|
||||
// pop state
|
||||
balanceStart = prevBalanceStart;
|
||||
balanceCloseType = balancePair[offsetAndType[prevBalanceStart] >> TYPE_SHIFT];
|
||||
} else if (isBlockOpenerToken(type)) { // check for FunctionToken, <(-token>, <[-token> and <{-token>
|
||||
// push state
|
||||
balanceStart = index;
|
||||
balanceCloseType = balancePair[type];
|
||||
}
|
||||
});
|
||||
|
||||
// finalize buffers
|
||||
offsetAndType[tokenCount] = (types.EOF << TYPE_SHIFT) | sourceLength; // <EOF-token>
|
||||
balance[tokenCount] = tokenCount; // prevents false positive balance match with any token
|
||||
|
||||
// reverse references from balance start to end
|
||||
// tokens
|
||||
// token: a ( [ b c ] d e ) {
|
||||
// index: 0 1 2 3 4 5 6 7 8 9
|
||||
// before
|
||||
// balance: 0 8 5 2 2 2 1 1 1 0
|
||||
// - > > < < < < < < -
|
||||
// after
|
||||
// balance: 9 8 5 5 5 2 8 8 1 9
|
||||
// > > > > > < > > < >
|
||||
for (let i = 0; i < tokenCount; i++) {
|
||||
const balanceStart = balance[i];
|
||||
|
||||
if (balanceStart <= i) {
|
||||
const balanceEnd = balance[balanceStart];
|
||||
|
||||
if (balanceEnd !== i) {
|
||||
balance[i] = balanceEnd;
|
||||
}
|
||||
} else if (balanceStart > tokenCount) {
|
||||
balance[i] = tokenCount;
|
||||
}
|
||||
}
|
||||
|
||||
// balance[0] = tokenCount;
|
||||
|
||||
this.source = source;
|
||||
this.firstCharOffset = firstCharOffset === -1 ? 0 : firstCharOffset;
|
||||
this.tokenCount = tokenCount;
|
||||
this.offsetAndType = offsetAndType;
|
||||
this.balance = balance;
|
||||
|
||||
this.reset();
|
||||
this.next();
|
||||
}
|
||||
|
||||
lookupType(offset) {
|
||||
offset += this.tokenIndex;
|
||||
|
||||
if (offset < this.tokenCount) {
|
||||
return this.offsetAndType[offset] >> TYPE_SHIFT;
|
||||
}
|
||||
|
||||
return types.EOF;
|
||||
}
|
||||
lookupTypeNonSC(idx) {
|
||||
for (let offset = this.tokenIndex; offset < this.tokenCount; offset++) {
|
||||
const tokenType = this.offsetAndType[offset] >> TYPE_SHIFT;
|
||||
|
||||
if (tokenType !== types.WhiteSpace && tokenType !== types.Comment) {
|
||||
if (idx-- === 0) {
|
||||
return tokenType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return types.EOF;
|
||||
}
|
||||
lookupOffset(offset) {
|
||||
offset += this.tokenIndex;
|
||||
|
||||
if (offset < this.tokenCount) {
|
||||
return this.offsetAndType[offset - 1] & OFFSET_MASK;
|
||||
}
|
||||
|
||||
return this.source.length;
|
||||
}
|
||||
lookupOffsetNonSC(idx) {
|
||||
for (let offset = this.tokenIndex; offset < this.tokenCount; offset++) {
|
||||
const tokenType = this.offsetAndType[offset] >> TYPE_SHIFT;
|
||||
|
||||
if (tokenType !== types.WhiteSpace && tokenType !== types.Comment) {
|
||||
if (idx-- === 0) {
|
||||
return offset - this.tokenIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return types.EOF;
|
||||
}
|
||||
lookupValue(offset, referenceStr) {
|
||||
offset += this.tokenIndex;
|
||||
|
||||
if (offset < this.tokenCount) {
|
||||
return utils.cmpStr(
|
||||
this.source,
|
||||
this.offsetAndType[offset - 1] & OFFSET_MASK,
|
||||
this.offsetAndType[offset] & OFFSET_MASK,
|
||||
referenceStr
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
getTokenStart(tokenIndex) {
|
||||
if (tokenIndex === this.tokenIndex) {
|
||||
return this.tokenStart;
|
||||
}
|
||||
|
||||
if (tokenIndex > 0) {
|
||||
return tokenIndex < this.tokenCount
|
||||
? this.offsetAndType[tokenIndex - 1] & OFFSET_MASK
|
||||
: this.offsetAndType[this.tokenCount] & OFFSET_MASK;
|
||||
}
|
||||
|
||||
return this.firstCharOffset;
|
||||
}
|
||||
substrToCursor(start) {
|
||||
return this.source.substring(start, this.tokenStart);
|
||||
}
|
||||
|
||||
isBalanceEdge(pos) {
|
||||
return this.balance[this.tokenIndex] < pos;
|
||||
// return this.balance[this.balance[pos]] !== this.tokenIndex;
|
||||
}
|
||||
isDelim(code, offset) {
|
||||
if (offset) {
|
||||
return (
|
||||
this.lookupType(offset) === types.Delim &&
|
||||
this.source.charCodeAt(this.lookupOffset(offset)) === code
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
this.tokenType === types.Delim &&
|
||||
this.source.charCodeAt(this.tokenStart) === code
|
||||
);
|
||||
}
|
||||
|
||||
skip(tokenCount) {
|
||||
let next = this.tokenIndex + tokenCount;
|
||||
|
||||
if (next < this.tokenCount) {
|
||||
this.tokenIndex = next;
|
||||
this.tokenStart = this.offsetAndType[next - 1] & OFFSET_MASK;
|
||||
next = this.offsetAndType[next];
|
||||
this.tokenType = next >> TYPE_SHIFT;
|
||||
this.tokenEnd = next & OFFSET_MASK;
|
||||
} else {
|
||||
this.tokenIndex = this.tokenCount;
|
||||
this.next();
|
||||
}
|
||||
}
|
||||
next() {
|
||||
let next = this.tokenIndex + 1;
|
||||
|
||||
if (next < this.tokenCount) {
|
||||
this.tokenIndex = next;
|
||||
this.tokenStart = this.tokenEnd;
|
||||
next = this.offsetAndType[next];
|
||||
this.tokenType = next >> TYPE_SHIFT;
|
||||
this.tokenEnd = next & OFFSET_MASK;
|
||||
} else {
|
||||
this.eof = true;
|
||||
this.tokenIndex = this.tokenCount;
|
||||
this.tokenType = types.EOF;
|
||||
this.tokenStart = this.tokenEnd = this.source.length;
|
||||
}
|
||||
}
|
||||
skipSC() {
|
||||
while (this.tokenType === types.WhiteSpace || this.tokenType === types.Comment) {
|
||||
this.next();
|
||||
}
|
||||
}
|
||||
skipUntilBalanced(startToken, stopConsume) {
|
||||
let cursor = startToken;
|
||||
let balanceEnd = 0;
|
||||
let offset = 0;
|
||||
|
||||
loop:
|
||||
for (; cursor < this.tokenCount; cursor++) {
|
||||
balanceEnd = this.balance[cursor];
|
||||
|
||||
// stop scanning on balance edge that points to offset before start token
|
||||
if (balanceEnd < startToken) {
|
||||
break loop;
|
||||
}
|
||||
|
||||
offset = cursor > 0 ? this.offsetAndType[cursor - 1] & OFFSET_MASK : this.firstCharOffset;
|
||||
|
||||
// check stop condition
|
||||
switch (stopConsume(this.source.charCodeAt(offset))) {
|
||||
case 1: // just stop
|
||||
break loop;
|
||||
|
||||
case 2: // stop & included
|
||||
cursor++;
|
||||
break loop;
|
||||
|
||||
default:
|
||||
// fast forward to the end of balanced block for an open block tokens
|
||||
if (isBlockOpenerToken(this.offsetAndType[cursor] >> TYPE_SHIFT)) {
|
||||
cursor = balanceEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.skip(cursor - this.tokenIndex);
|
||||
}
|
||||
|
||||
forEachToken(fn) {
|
||||
for (let i = 0, offset = this.firstCharOffset; i < this.tokenCount; i++) {
|
||||
const start = offset;
|
||||
const item = this.offsetAndType[i];
|
||||
const end = item & OFFSET_MASK;
|
||||
const type = item >> TYPE_SHIFT;
|
||||
|
||||
offset = end;
|
||||
|
||||
fn(type, start, end, i);
|
||||
}
|
||||
}
|
||||
dump() {
|
||||
const tokens = new Array(this.tokenCount);
|
||||
|
||||
this.forEachToken((type, start, end, index) => {
|
||||
tokens[index] = {
|
||||
idx: index,
|
||||
type: names[type],
|
||||
chunk: this.source.substring(start, end),
|
||||
balance: this.balance[index]
|
||||
};
|
||||
});
|
||||
|
||||
return tokens;
|
||||
}
|
||||
}
|
||||
|
||||
exports.TokenStream = TokenStream;
|
||||
13
node_modules/css-tree/cjs/tokenizer/adopt-buffer.cjs
generated
vendored
Executable file
13
node_modules/css-tree/cjs/tokenizer/adopt-buffer.cjs
generated
vendored
Executable file
@@ -0,0 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
const MIN_SIZE = 16 * 1024;
|
||||
|
||||
function adoptBuffer(buffer = null, size) {
|
||||
if (buffer === null || buffer.length < size) {
|
||||
return new Uint32Array(Math.max(size + 1024, MIN_SIZE));
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
exports.adoptBuffer = adoptBuffer;
|
||||
236
node_modules/css-tree/cjs/tokenizer/char-code-definitions.cjs
generated
vendored
Executable file
236
node_modules/css-tree/cjs/tokenizer/char-code-definitions.cjs
generated
vendored
Executable file
@@ -0,0 +1,236 @@
|
||||
'use strict';
|
||||
|
||||
const EOF = 0;
|
||||
|
||||
// https://drafts.csswg.org/css-syntax-3/
|
||||
// § 4.2. Definitions
|
||||
|
||||
// digit
|
||||
// A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9).
|
||||
function isDigit(code) {
|
||||
return code >= 0x0030 && code <= 0x0039;
|
||||
}
|
||||
|
||||
// hex digit
|
||||
// A digit, or a code point between U+0041 LATIN CAPITAL LETTER A (A) and U+0046 LATIN CAPITAL LETTER F (F),
|
||||
// or a code point between U+0061 LATIN SMALL LETTER A (a) and U+0066 LATIN SMALL LETTER F (f).
|
||||
function isHexDigit(code) {
|
||||
return (
|
||||
isDigit(code) || // 0 .. 9
|
||||
(code >= 0x0041 && code <= 0x0046) || // A .. F
|
||||
(code >= 0x0061 && code <= 0x0066) // a .. f
|
||||
);
|
||||
}
|
||||
|
||||
// uppercase letter
|
||||
// A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z).
|
||||
function isUppercaseLetter(code) {
|
||||
return code >= 0x0041 && code <= 0x005A;
|
||||
}
|
||||
|
||||
// lowercase letter
|
||||
// A code point between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z).
|
||||
function isLowercaseLetter(code) {
|
||||
return code >= 0x0061 && code <= 0x007A;
|
||||
}
|
||||
|
||||
// letter
|
||||
// An uppercase letter or a lowercase letter.
|
||||
function isLetter(code) {
|
||||
return isUppercaseLetter(code) || isLowercaseLetter(code);
|
||||
}
|
||||
|
||||
// non-ASCII code point
|
||||
// A code point with a value equal to or greater than U+0080 <control>.
|
||||
//
|
||||
// 2024-09-02: The latest spec narrows the range for non-ASCII characters (see https://github.com/csstree/csstree/issues/188).
|
||||
// However, all modern browsers support a wider range, and strictly following the latest spec could result
|
||||
// in some CSS being parsed incorrectly, even though it works in the browser. Therefore, this function adheres
|
||||
// to the previous, broader definition of non-ASCII characters.
|
||||
function isNonAscii(code) {
|
||||
return code >= 0x0080;
|
||||
}
|
||||
|
||||
// name-start code point
|
||||
// A letter, a non-ASCII code point, or U+005F LOW LINE (_).
|
||||
function isNameStart(code) {
|
||||
return isLetter(code) || isNonAscii(code) || code === 0x005F;
|
||||
}
|
||||
|
||||
// name code point
|
||||
// A name-start code point, a digit, or U+002D HYPHEN-MINUS (-).
|
||||
function isName(code) {
|
||||
return isNameStart(code) || isDigit(code) || code === 0x002D;
|
||||
}
|
||||
|
||||
// non-printable code point
|
||||
// A code point between U+0000 NULL and U+0008 BACKSPACE, or U+000B LINE TABULATION,
|
||||
// or a code point between U+000E SHIFT OUT and U+001F INFORMATION SEPARATOR ONE, or U+007F DELETE.
|
||||
function isNonPrintable(code) {
|
||||
return (
|
||||
(code >= 0x0000 && code <= 0x0008) ||
|
||||
(code === 0x000B) ||
|
||||
(code >= 0x000E && code <= 0x001F) ||
|
||||
(code === 0x007F)
|
||||
);
|
||||
}
|
||||
|
||||
// newline
|
||||
// U+000A LINE FEED. Note that U+000D CARRIAGE RETURN and U+000C FORM FEED are not included in this definition,
|
||||
// as they are converted to U+000A LINE FEED during preprocessing.
|
||||
// TODO: we doesn't do a preprocessing, so check a code point for U+000D CARRIAGE RETURN and U+000C FORM FEED
|
||||
function isNewline(code) {
|
||||
return code === 0x000A || code === 0x000D || code === 0x000C;
|
||||
}
|
||||
|
||||
// whitespace
|
||||
// A newline, U+0009 CHARACTER TABULATION, or U+0020 SPACE.
|
||||
function isWhiteSpace(code) {
|
||||
return isNewline(code) || code === 0x0020 || code === 0x0009;
|
||||
}
|
||||
|
||||
// § 4.3.8. Check if two code points are a valid escape
|
||||
function isValidEscape(first, second) {
|
||||
// If the first code point is not U+005C REVERSE SOLIDUS (\), return false.
|
||||
if (first !== 0x005C) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, if the second code point is a newline or EOF, return false.
|
||||
if (isNewline(second) || second === EOF) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, return true.
|
||||
return true;
|
||||
}
|
||||
|
||||
// § 4.3.9. Check if three code points would start an identifier
|
||||
function isIdentifierStart(first, second, third) {
|
||||
// Look at the first code point:
|
||||
|
||||
// U+002D HYPHEN-MINUS
|
||||
if (first === 0x002D) {
|
||||
// If the second code point is a name-start code point or a U+002D HYPHEN-MINUS,
|
||||
// or the second and third code points are a valid escape, return true. Otherwise, return false.
|
||||
return (
|
||||
isNameStart(second) ||
|
||||
second === 0x002D ||
|
||||
isValidEscape(second, third)
|
||||
);
|
||||
}
|
||||
|
||||
// name-start code point
|
||||
if (isNameStart(first)) {
|
||||
// Return true.
|
||||
return true;
|
||||
}
|
||||
|
||||
// U+005C REVERSE SOLIDUS (\)
|
||||
if (first === 0x005C) {
|
||||
// If the first and second code points are a valid escape, return true. Otherwise, return false.
|
||||
return isValidEscape(first, second);
|
||||
}
|
||||
|
||||
// anything else
|
||||
// Return false.
|
||||
return false;
|
||||
}
|
||||
|
||||
// § 4.3.10. Check if three code points would start a number
|
||||
function isNumberStart(first, second, third) {
|
||||
// Look at the first code point:
|
||||
|
||||
// U+002B PLUS SIGN (+)
|
||||
// U+002D HYPHEN-MINUS (-)
|
||||
if (first === 0x002B || first === 0x002D) {
|
||||
// If the second code point is a digit, return true.
|
||||
if (isDigit(second)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Otherwise, if the second code point is a U+002E FULL STOP (.)
|
||||
// and the third code point is a digit, return true.
|
||||
// Otherwise, return false.
|
||||
return second === 0x002E && isDigit(third) ? 3 : 0;
|
||||
}
|
||||
|
||||
// U+002E FULL STOP (.)
|
||||
if (first === 0x002E) {
|
||||
// If the second code point is a digit, return true. Otherwise, return false.
|
||||
return isDigit(second) ? 2 : 0;
|
||||
}
|
||||
|
||||
// digit
|
||||
if (isDigit(first)) {
|
||||
// Return true.
|
||||
return 1;
|
||||
}
|
||||
|
||||
// anything else
|
||||
// Return false.
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Misc
|
||||
//
|
||||
|
||||
// detect BOM (https://en.wikipedia.org/wiki/Byte_order_mark)
|
||||
function isBOM(code) {
|
||||
// UTF-16BE
|
||||
if (code === 0xFEFF) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// UTF-16LE
|
||||
if (code === 0xFFFE) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Fast code category
|
||||
// Only ASCII code points has a special meaning, that's why we define a maps for 0..127 codes only
|
||||
const CATEGORY = new Array(0x80);
|
||||
const EofCategory = 0x80;
|
||||
const WhiteSpaceCategory = 0x82;
|
||||
const DigitCategory = 0x83;
|
||||
const NameStartCategory = 0x84;
|
||||
const NonPrintableCategory = 0x85;
|
||||
|
||||
for (let i = 0; i < CATEGORY.length; i++) {
|
||||
CATEGORY[i] =
|
||||
isWhiteSpace(i) && WhiteSpaceCategory ||
|
||||
isDigit(i) && DigitCategory ||
|
||||
isNameStart(i) && NameStartCategory ||
|
||||
isNonPrintable(i) && NonPrintableCategory ||
|
||||
i || EofCategory;
|
||||
}
|
||||
|
||||
function charCodeCategory(code) {
|
||||
return code < 0x80 ? CATEGORY[code] : NameStartCategory;
|
||||
}
|
||||
|
||||
exports.DigitCategory = DigitCategory;
|
||||
exports.EofCategory = EofCategory;
|
||||
exports.NameStartCategory = NameStartCategory;
|
||||
exports.NonPrintableCategory = NonPrintableCategory;
|
||||
exports.WhiteSpaceCategory = WhiteSpaceCategory;
|
||||
exports.charCodeCategory = charCodeCategory;
|
||||
exports.isBOM = isBOM;
|
||||
exports.isDigit = isDigit;
|
||||
exports.isHexDigit = isHexDigit;
|
||||
exports.isIdentifierStart = isIdentifierStart;
|
||||
exports.isLetter = isLetter;
|
||||
exports.isLowercaseLetter = isLowercaseLetter;
|
||||
exports.isName = isName;
|
||||
exports.isNameStart = isNameStart;
|
||||
exports.isNewline = isNewline;
|
||||
exports.isNonAscii = isNonAscii;
|
||||
exports.isNonPrintable = isNonPrintable;
|
||||
exports.isNumberStart = isNumberStart;
|
||||
exports.isUppercaseLetter = isUppercaseLetter;
|
||||
exports.isValidEscape = isValidEscape;
|
||||
exports.isWhiteSpace = isWhiteSpace;
|
||||
554
node_modules/css-tree/cjs/tokenizer/index.cjs
generated
vendored
Executable file
554
node_modules/css-tree/cjs/tokenizer/index.cjs
generated
vendored
Executable file
@@ -0,0 +1,554 @@
|
||||
'use strict';
|
||||
|
||||
const types = require('./types.cjs');
|
||||
const charCodeDefinitions = require('./char-code-definitions.cjs');
|
||||
const utils = require('./utils.cjs');
|
||||
const names = require('./names.cjs');
|
||||
const OffsetToLocation = require('./OffsetToLocation.cjs');
|
||||
const TokenStream = require('./TokenStream.cjs');
|
||||
|
||||
function tokenize(source, onToken) {
|
||||
function getCharCode(offset) {
|
||||
return offset < sourceLength ? source.charCodeAt(offset) : 0;
|
||||
}
|
||||
|
||||
// § 4.3.3. Consume a numeric token
|
||||
function consumeNumericToken() {
|
||||
// Consume a number and let number be the result.
|
||||
offset = utils.consumeNumber(source, offset);
|
||||
|
||||
// If the next 3 input code points would start an identifier, then:
|
||||
if (charCodeDefinitions.isIdentifierStart(getCharCode(offset), getCharCode(offset + 1), getCharCode(offset + 2))) {
|
||||
// Create a <dimension-token> with the same value and type flag as number, and a unit set initially to the empty string.
|
||||
// Consume a name. Set the <dimension-token>’s unit to the returned value.
|
||||
// Return the <dimension-token>.
|
||||
type = types.Dimension;
|
||||
offset = utils.consumeName(source, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, if the next input code point is U+0025 PERCENTAGE SIGN (%), consume it.
|
||||
if (getCharCode(offset) === 0x0025) {
|
||||
// Create a <percentage-token> with the same value as number, and return it.
|
||||
type = types.Percentage;
|
||||
offset++;
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, create a <number-token> with the same value and type flag as number, and return it.
|
||||
type = types.Number;
|
||||
}
|
||||
|
||||
// § 4.3.4. Consume an ident-like token
|
||||
function consumeIdentLikeToken() {
|
||||
const nameStartOffset = offset;
|
||||
|
||||
// Consume a name, and let string be the result.
|
||||
offset = utils.consumeName(source, offset);
|
||||
|
||||
// If string’s value is an ASCII case-insensitive match for "url",
|
||||
// and the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
|
||||
if (utils.cmpStr(source, nameStartOffset, offset, 'url') && getCharCode(offset) === 0x0028) {
|
||||
// While the next two input code points are whitespace, consume the next input code point.
|
||||
offset = utils.findWhiteSpaceEnd(source, offset + 1);
|
||||
|
||||
// If the next one or two input code points are U+0022 QUOTATION MARK ("), U+0027 APOSTROPHE ('),
|
||||
// or whitespace followed by U+0022 QUOTATION MARK (") or U+0027 APOSTROPHE ('),
|
||||
// then create a <function-token> with its value set to string and return it.
|
||||
if (getCharCode(offset) === 0x0022 ||
|
||||
getCharCode(offset) === 0x0027) {
|
||||
type = types.Function;
|
||||
offset = nameStartOffset + 4;
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, consume a url token, and return it.
|
||||
consumeUrlToken();
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, if the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
|
||||
// Create a <function-token> with its value set to string and return it.
|
||||
if (getCharCode(offset) === 0x0028) {
|
||||
type = types.Function;
|
||||
offset++;
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, create an <ident-token> with its value set to string and return it.
|
||||
type = types.Ident;
|
||||
}
|
||||
|
||||
// § 4.3.5. Consume a string token
|
||||
function consumeStringToken(endingCodePoint) {
|
||||
// This algorithm may be called with an ending code point, which denotes the code point
|
||||
// that ends the string. If an ending code point is not specified,
|
||||
// the current input code point is used.
|
||||
if (!endingCodePoint) {
|
||||
endingCodePoint = getCharCode(offset++);
|
||||
}
|
||||
|
||||
// Initially create a <string-token> with its value set to the empty string.
|
||||
type = types.String;
|
||||
|
||||
// Repeatedly consume the next input code point from the stream:
|
||||
for (; offset < source.length; offset++) {
|
||||
const code = source.charCodeAt(offset);
|
||||
|
||||
switch (charCodeDefinitions.charCodeCategory(code)) {
|
||||
// ending code point
|
||||
case endingCodePoint:
|
||||
// Return the <string-token>.
|
||||
offset++;
|
||||
return;
|
||||
|
||||
// EOF
|
||||
// case EofCategory:
|
||||
// This is a parse error. Return the <string-token>.
|
||||
// return;
|
||||
|
||||
// newline
|
||||
case charCodeDefinitions.WhiteSpaceCategory:
|
||||
if (charCodeDefinitions.isNewline(code)) {
|
||||
// This is a parse error. Reconsume the current input code point,
|
||||
// create a <bad-string-token>, and return it.
|
||||
offset += utils.getNewlineLength(source, offset, code);
|
||||
type = types.BadString;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
// U+005C REVERSE SOLIDUS (\)
|
||||
case 0x005C:
|
||||
// If the next input code point is EOF, do nothing.
|
||||
if (offset === source.length - 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
const nextCode = getCharCode(offset + 1);
|
||||
|
||||
// Otherwise, if the next input code point is a newline, consume it.
|
||||
if (charCodeDefinitions.isNewline(nextCode)) {
|
||||
offset += utils.getNewlineLength(source, offset + 1, nextCode);
|
||||
} else if (charCodeDefinitions.isValidEscape(code, nextCode)) {
|
||||
// Otherwise, (the stream starts with a valid escape) consume
|
||||
// an escaped code point and append the returned code point to
|
||||
// the <string-token>’s value.
|
||||
offset = utils.consumeEscaped(source, offset) - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
// anything else
|
||||
// Append the current input code point to the <string-token>’s value.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// § 4.3.6. Consume a url token
|
||||
// Note: This algorithm assumes that the initial "url(" has already been consumed.
|
||||
// This algorithm also assumes that it’s being called to consume an "unquoted" value, like url(foo).
|
||||
// A quoted value, like url("foo"), is parsed as a <function-token>. Consume an ident-like token
|
||||
// automatically handles this distinction; this algorithm shouldn’t be called directly otherwise.
|
||||
function consumeUrlToken() {
|
||||
// Initially create a <url-token> with its value set to the empty string.
|
||||
type = types.Url;
|
||||
|
||||
// Consume as much whitespace as possible.
|
||||
offset = utils.findWhiteSpaceEnd(source, offset);
|
||||
|
||||
// Repeatedly consume the next input code point from the stream:
|
||||
for (; offset < source.length; offset++) {
|
||||
const code = source.charCodeAt(offset);
|
||||
|
||||
switch (charCodeDefinitions.charCodeCategory(code)) {
|
||||
// U+0029 RIGHT PARENTHESIS ())
|
||||
case 0x0029:
|
||||
// Return the <url-token>.
|
||||
offset++;
|
||||
return;
|
||||
|
||||
// EOF
|
||||
// case EofCategory:
|
||||
// This is a parse error. Return the <url-token>.
|
||||
// return;
|
||||
|
||||
// whitespace
|
||||
case charCodeDefinitions.WhiteSpaceCategory:
|
||||
// Consume as much whitespace as possible.
|
||||
offset = utils.findWhiteSpaceEnd(source, offset);
|
||||
|
||||
// If the next input code point is U+0029 RIGHT PARENTHESIS ()) or EOF,
|
||||
// consume it and return the <url-token>
|
||||
// (if EOF was encountered, this is a parse error);
|
||||
if (getCharCode(offset) === 0x0029 || offset >= source.length) {
|
||||
if (offset < source.length) {
|
||||
offset++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise, consume the remnants of a bad url, create a <bad-url-token>,
|
||||
// and return it.
|
||||
offset = utils.consumeBadUrlRemnants(source, offset);
|
||||
type = types.BadUrl;
|
||||
return;
|
||||
|
||||
// U+0022 QUOTATION MARK (")
|
||||
// U+0027 APOSTROPHE (')
|
||||
// U+0028 LEFT PARENTHESIS (()
|
||||
// non-printable code point
|
||||
case 0x0022:
|
||||
case 0x0027:
|
||||
case 0x0028:
|
||||
case charCodeDefinitions.NonPrintableCategory:
|
||||
// This is a parse error. Consume the remnants of a bad url,
|
||||
// create a <bad-url-token>, and return it.
|
||||
offset = utils.consumeBadUrlRemnants(source, offset);
|
||||
type = types.BadUrl;
|
||||
return;
|
||||
|
||||
// U+005C REVERSE SOLIDUS (\)
|
||||
case 0x005C:
|
||||
// If the stream starts with a valid escape, consume an escaped code point and
|
||||
// append the returned code point to the <url-token>’s value.
|
||||
if (charCodeDefinitions.isValidEscape(code, getCharCode(offset + 1))) {
|
||||
offset = utils.consumeEscaped(source, offset) - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// Otherwise, this is a parse error. Consume the remnants of a bad url,
|
||||
// create a <bad-url-token>, and return it.
|
||||
offset = utils.consumeBadUrlRemnants(source, offset);
|
||||
type = types.BadUrl;
|
||||
return;
|
||||
|
||||
// anything else
|
||||
// Append the current input code point to the <url-token>’s value.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ensure source is a string
|
||||
source = String(source || '');
|
||||
|
||||
const sourceLength = source.length;
|
||||
let start = charCodeDefinitions.isBOM(getCharCode(0));
|
||||
let offset = start;
|
||||
let type;
|
||||
|
||||
// https://drafts.csswg.org/css-syntax-3/#consume-token
|
||||
// § 4.3.1. Consume a token
|
||||
while (offset < sourceLength) {
|
||||
const code = source.charCodeAt(offset);
|
||||
|
||||
switch (charCodeDefinitions.charCodeCategory(code)) {
|
||||
// whitespace
|
||||
case charCodeDefinitions.WhiteSpaceCategory:
|
||||
// Consume as much whitespace as possible. Return a <whitespace-token>.
|
||||
type = types.WhiteSpace;
|
||||
offset = utils.findWhiteSpaceEnd(source, offset + 1);
|
||||
break;
|
||||
|
||||
// U+0022 QUOTATION MARK (")
|
||||
case 0x0022:
|
||||
// Consume a string token and return it.
|
||||
consumeStringToken();
|
||||
break;
|
||||
|
||||
// U+0023 NUMBER SIGN (#)
|
||||
case 0x0023:
|
||||
// If the next input code point is a name code point or the next two input code points are a valid escape, then:
|
||||
if (charCodeDefinitions.isName(getCharCode(offset + 1)) || charCodeDefinitions.isValidEscape(getCharCode(offset + 1), getCharCode(offset + 2))) {
|
||||
// Create a <hash-token>.
|
||||
type = types.Hash;
|
||||
|
||||
// If the next 3 input code points would start an identifier, set the <hash-token>’s type flag to "id".
|
||||
// if (isIdentifierStart(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {
|
||||
// // TODO: set id flag
|
||||
// }
|
||||
|
||||
// Consume a name, and set the <hash-token>’s value to the returned string.
|
||||
offset = utils.consumeName(source, offset + 1);
|
||||
|
||||
// Return the <hash-token>.
|
||||
} else {
|
||||
// Otherwise, return a <delim-token> with its value set to the current input code point.
|
||||
type = types.Delim;
|
||||
offset++;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// U+0027 APOSTROPHE (')
|
||||
case 0x0027:
|
||||
// Consume a string token and return it.
|
||||
consumeStringToken();
|
||||
break;
|
||||
|
||||
// U+0028 LEFT PARENTHESIS (()
|
||||
case 0x0028:
|
||||
// Return a <(-token>.
|
||||
type = types.LeftParenthesis;
|
||||
offset++;
|
||||
break;
|
||||
|
||||
// U+0029 RIGHT PARENTHESIS ())
|
||||
case 0x0029:
|
||||
// Return a <)-token>.
|
||||
type = types.RightParenthesis;
|
||||
offset++;
|
||||
break;
|
||||
|
||||
// U+002B PLUS SIGN (+)
|
||||
case 0x002B:
|
||||
// If the input stream starts with a number, ...
|
||||
if (charCodeDefinitions.isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
|
||||
// ... reconsume the current input code point, consume a numeric token, and return it.
|
||||
consumeNumericToken();
|
||||
} else {
|
||||
// Otherwise, return a <delim-token> with its value set to the current input code point.
|
||||
type = types.Delim;
|
||||
offset++;
|
||||
}
|
||||
break;
|
||||
|
||||
// U+002C COMMA (,)
|
||||
case 0x002C:
|
||||
// Return a <comma-token>.
|
||||
type = types.Comma;
|
||||
offset++;
|
||||
break;
|
||||
|
||||
// U+002D HYPHEN-MINUS (-)
|
||||
case 0x002D:
|
||||
// If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it.
|
||||
if (charCodeDefinitions.isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
|
||||
consumeNumericToken();
|
||||
} else {
|
||||
// Otherwise, if the next 2 input code points are U+002D HYPHEN-MINUS U+003E GREATER-THAN SIGN (->), consume them and return a <CDC-token>.
|
||||
if (getCharCode(offset + 1) === 0x002D &&
|
||||
getCharCode(offset + 2) === 0x003E) {
|
||||
type = types.CDC;
|
||||
offset = offset + 3;
|
||||
} else {
|
||||
// Otherwise, if the input stream starts with an identifier, ...
|
||||
if (charCodeDefinitions.isIdentifierStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
|
||||
// ... reconsume the current input code point, consume an ident-like token, and return it.
|
||||
consumeIdentLikeToken();
|
||||
} else {
|
||||
// Otherwise, return a <delim-token> with its value set to the current input code point.
|
||||
type = types.Delim;
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// U+002E FULL STOP (.)
|
||||
case 0x002E:
|
||||
// If the input stream starts with a number, ...
|
||||
if (charCodeDefinitions.isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
|
||||
// ... reconsume the current input code point, consume a numeric token, and return it.
|
||||
consumeNumericToken();
|
||||
} else {
|
||||
// Otherwise, return a <delim-token> with its value set to the current input code point.
|
||||
type = types.Delim;
|
||||
offset++;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// U+002F SOLIDUS (/)
|
||||
case 0x002F:
|
||||
// If the next two input code point are U+002F SOLIDUS (/) followed by a U+002A ASTERISK (*),
|
||||
if (getCharCode(offset + 1) === 0x002A) {
|
||||
// ... consume them and all following code points up to and including the first U+002A ASTERISK (*)
|
||||
// followed by a U+002F SOLIDUS (/), or up to an EOF code point.
|
||||
type = types.Comment;
|
||||
offset = source.indexOf('*/', offset + 2);
|
||||
offset = offset === -1 ? source.length : offset + 2;
|
||||
} else {
|
||||
type = types.Delim;
|
||||
offset++;
|
||||
}
|
||||
break;
|
||||
|
||||
// U+003A COLON (:)
|
||||
case 0x003A:
|
||||
// Return a <colon-token>.
|
||||
type = types.Colon;
|
||||
offset++;
|
||||
break;
|
||||
|
||||
// U+003B SEMICOLON (;)
|
||||
case 0x003B:
|
||||
// Return a <semicolon-token>.
|
||||
type = types.Semicolon;
|
||||
offset++;
|
||||
break;
|
||||
|
||||
// U+003C LESS-THAN SIGN (<)
|
||||
case 0x003C:
|
||||
// If the next 3 input code points are U+0021 EXCLAMATION MARK U+002D HYPHEN-MINUS U+002D HYPHEN-MINUS (!--), ...
|
||||
if (getCharCode(offset + 1) === 0x0021 &&
|
||||
getCharCode(offset + 2) === 0x002D &&
|
||||
getCharCode(offset + 3) === 0x002D) {
|
||||
// ... consume them and return a <CDO-token>.
|
||||
type = types.CDO;
|
||||
offset = offset + 4;
|
||||
} else {
|
||||
// Otherwise, return a <delim-token> with its value set to the current input code point.
|
||||
type = types.Delim;
|
||||
offset++;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// U+0040 COMMERCIAL AT (@)
|
||||
case 0x0040:
|
||||
// If the next 3 input code points would start an identifier, ...
|
||||
if (charCodeDefinitions.isIdentifierStart(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {
|
||||
// ... consume a name, create an <at-keyword-token> with its value set to the returned value, and return it.
|
||||
type = types.AtKeyword;
|
||||
offset = utils.consumeName(source, offset + 1);
|
||||
} else {
|
||||
// Otherwise, return a <delim-token> with its value set to the current input code point.
|
||||
type = types.Delim;
|
||||
offset++;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// U+005B LEFT SQUARE BRACKET ([)
|
||||
case 0x005B:
|
||||
// Return a <[-token>.
|
||||
type = types.LeftSquareBracket;
|
||||
offset++;
|
||||
break;
|
||||
|
||||
// U+005C REVERSE SOLIDUS (\)
|
||||
case 0x005C:
|
||||
// If the input stream starts with a valid escape, ...
|
||||
if (charCodeDefinitions.isValidEscape(code, getCharCode(offset + 1))) {
|
||||
// ... reconsume the current input code point, consume an ident-like token, and return it.
|
||||
consumeIdentLikeToken();
|
||||
} else {
|
||||
// Otherwise, this is a parse error. Return a <delim-token> with its value set to the current input code point.
|
||||
type = types.Delim;
|
||||
offset++;
|
||||
}
|
||||
break;
|
||||
|
||||
// U+005D RIGHT SQUARE BRACKET (])
|
||||
case 0x005D:
|
||||
// Return a <]-token>.
|
||||
type = types.RightSquareBracket;
|
||||
offset++;
|
||||
break;
|
||||
|
||||
// U+007B LEFT CURLY BRACKET ({)
|
||||
case 0x007B:
|
||||
// Return a <{-token>.
|
||||
type = types.LeftCurlyBracket;
|
||||
offset++;
|
||||
break;
|
||||
|
||||
// U+007D RIGHT CURLY BRACKET (})
|
||||
case 0x007D:
|
||||
// Return a <}-token>.
|
||||
type = types.RightCurlyBracket;
|
||||
offset++;
|
||||
break;
|
||||
|
||||
// digit
|
||||
case charCodeDefinitions.DigitCategory:
|
||||
// Reconsume the current input code point, consume a numeric token, and return it.
|
||||
consumeNumericToken();
|
||||
break;
|
||||
|
||||
// name-start code point
|
||||
case charCodeDefinitions.NameStartCategory:
|
||||
// Reconsume the current input code point, consume an ident-like token, and return it.
|
||||
consumeIdentLikeToken();
|
||||
break;
|
||||
|
||||
// EOF
|
||||
// case EofCategory:
|
||||
// Return an <EOF-token>.
|
||||
// break;
|
||||
|
||||
// anything else
|
||||
default:
|
||||
// Return a <delim-token> with its value set to the current input code point.
|
||||
type = types.Delim;
|
||||
offset++;
|
||||
}
|
||||
|
||||
// put token to stream
|
||||
onToken(type, start, start = offset);
|
||||
}
|
||||
}
|
||||
|
||||
exports.AtKeyword = types.AtKeyword;
|
||||
exports.BadString = types.BadString;
|
||||
exports.BadUrl = types.BadUrl;
|
||||
exports.CDC = types.CDC;
|
||||
exports.CDO = types.CDO;
|
||||
exports.Colon = types.Colon;
|
||||
exports.Comma = types.Comma;
|
||||
exports.Comment = types.Comment;
|
||||
exports.Delim = types.Delim;
|
||||
exports.Dimension = types.Dimension;
|
||||
exports.EOF = types.EOF;
|
||||
exports.Function = types.Function;
|
||||
exports.Hash = types.Hash;
|
||||
exports.Ident = types.Ident;
|
||||
exports.LeftCurlyBracket = types.LeftCurlyBracket;
|
||||
exports.LeftParenthesis = types.LeftParenthesis;
|
||||
exports.LeftSquareBracket = types.LeftSquareBracket;
|
||||
exports.Number = types.Number;
|
||||
exports.Percentage = types.Percentage;
|
||||
exports.RightCurlyBracket = types.RightCurlyBracket;
|
||||
exports.RightParenthesis = types.RightParenthesis;
|
||||
exports.RightSquareBracket = types.RightSquareBracket;
|
||||
exports.Semicolon = types.Semicolon;
|
||||
exports.String = types.String;
|
||||
exports.Url = types.Url;
|
||||
exports.WhiteSpace = types.WhiteSpace;
|
||||
exports.tokenTypes = types;
|
||||
exports.DigitCategory = charCodeDefinitions.DigitCategory;
|
||||
exports.EofCategory = charCodeDefinitions.EofCategory;
|
||||
exports.NameStartCategory = charCodeDefinitions.NameStartCategory;
|
||||
exports.NonPrintableCategory = charCodeDefinitions.NonPrintableCategory;
|
||||
exports.WhiteSpaceCategory = charCodeDefinitions.WhiteSpaceCategory;
|
||||
exports.charCodeCategory = charCodeDefinitions.charCodeCategory;
|
||||
exports.isBOM = charCodeDefinitions.isBOM;
|
||||
exports.isDigit = charCodeDefinitions.isDigit;
|
||||
exports.isHexDigit = charCodeDefinitions.isHexDigit;
|
||||
exports.isIdentifierStart = charCodeDefinitions.isIdentifierStart;
|
||||
exports.isLetter = charCodeDefinitions.isLetter;
|
||||
exports.isLowercaseLetter = charCodeDefinitions.isLowercaseLetter;
|
||||
exports.isName = charCodeDefinitions.isName;
|
||||
exports.isNameStart = charCodeDefinitions.isNameStart;
|
||||
exports.isNewline = charCodeDefinitions.isNewline;
|
||||
exports.isNonAscii = charCodeDefinitions.isNonAscii;
|
||||
exports.isNonPrintable = charCodeDefinitions.isNonPrintable;
|
||||
exports.isNumberStart = charCodeDefinitions.isNumberStart;
|
||||
exports.isUppercaseLetter = charCodeDefinitions.isUppercaseLetter;
|
||||
exports.isValidEscape = charCodeDefinitions.isValidEscape;
|
||||
exports.isWhiteSpace = charCodeDefinitions.isWhiteSpace;
|
||||
exports.cmpChar = utils.cmpChar;
|
||||
exports.cmpStr = utils.cmpStr;
|
||||
exports.consumeBadUrlRemnants = utils.consumeBadUrlRemnants;
|
||||
exports.consumeEscaped = utils.consumeEscaped;
|
||||
exports.consumeName = utils.consumeName;
|
||||
exports.consumeNumber = utils.consumeNumber;
|
||||
exports.decodeEscaped = utils.decodeEscaped;
|
||||
exports.findDecimalNumberEnd = utils.findDecimalNumberEnd;
|
||||
exports.findWhiteSpaceEnd = utils.findWhiteSpaceEnd;
|
||||
exports.findWhiteSpaceStart = utils.findWhiteSpaceStart;
|
||||
exports.getNewlineLength = utils.getNewlineLength;
|
||||
exports.tokenNames = names;
|
||||
exports.OffsetToLocation = OffsetToLocation.OffsetToLocation;
|
||||
exports.TokenStream = TokenStream.TokenStream;
|
||||
exports.tokenize = tokenize;
|
||||
32
node_modules/css-tree/cjs/tokenizer/names.cjs
generated
vendored
Executable file
32
node_modules/css-tree/cjs/tokenizer/names.cjs
generated
vendored
Executable file
@@ -0,0 +1,32 @@
|
||||
'use strict';
|
||||
|
||||
const tokenNames = [
|
||||
'EOF-token',
|
||||
'ident-token',
|
||||
'function-token',
|
||||
'at-keyword-token',
|
||||
'hash-token',
|
||||
'string-token',
|
||||
'bad-string-token',
|
||||
'url-token',
|
||||
'bad-url-token',
|
||||
'delim-token',
|
||||
'number-token',
|
||||
'percentage-token',
|
||||
'dimension-token',
|
||||
'whitespace-token',
|
||||
'CDO-token',
|
||||
'CDC-token',
|
||||
'colon-token',
|
||||
'semicolon-token',
|
||||
'comma-token',
|
||||
'[-token',
|
||||
']-token',
|
||||
'(-token',
|
||||
')-token',
|
||||
'{-token',
|
||||
'}-token',
|
||||
'comment-token'
|
||||
];
|
||||
|
||||
module.exports = tokenNames;
|
||||
57
node_modules/css-tree/cjs/tokenizer/types.cjs
generated
vendored
Executable file
57
node_modules/css-tree/cjs/tokenizer/types.cjs
generated
vendored
Executable file
@@ -0,0 +1,57 @@
|
||||
'use strict';
|
||||
|
||||
// CSS Syntax Module Level 3
|
||||
// https://www.w3.org/TR/css-syntax-3/
|
||||
const EOF = 0; // <EOF-token>
|
||||
const Ident = 1; // <ident-token>
|
||||
const Function = 2; // <function-token>
|
||||
const AtKeyword = 3; // <at-keyword-token>
|
||||
const Hash = 4; // <hash-token>
|
||||
const String = 5; // <string-token>
|
||||
const BadString = 6; // <bad-string-token>
|
||||
const Url = 7; // <url-token>
|
||||
const BadUrl = 8; // <bad-url-token>
|
||||
const Delim = 9; // <delim-token>
|
||||
const Number = 10; // <number-token>
|
||||
const Percentage = 11; // <percentage-token>
|
||||
const Dimension = 12; // <dimension-token>
|
||||
const WhiteSpace = 13; // <whitespace-token>
|
||||
const CDO = 14; // <CDO-token>
|
||||
const CDC = 15; // <CDC-token>
|
||||
const Colon = 16; // <colon-token> :
|
||||
const Semicolon = 17; // <semicolon-token> ;
|
||||
const Comma = 18; // <comma-token> ,
|
||||
const LeftSquareBracket = 19; // <[-token>
|
||||
const RightSquareBracket = 20; // <]-token>
|
||||
const LeftParenthesis = 21; // <(-token>
|
||||
const RightParenthesis = 22; // <)-token>
|
||||
const LeftCurlyBracket = 23; // <{-token>
|
||||
const RightCurlyBracket = 24; // <}-token>
|
||||
const Comment = 25;
|
||||
|
||||
exports.AtKeyword = AtKeyword;
|
||||
exports.BadString = BadString;
|
||||
exports.BadUrl = BadUrl;
|
||||
exports.CDC = CDC;
|
||||
exports.CDO = CDO;
|
||||
exports.Colon = Colon;
|
||||
exports.Comma = Comma;
|
||||
exports.Comment = Comment;
|
||||
exports.Delim = Delim;
|
||||
exports.Dimension = Dimension;
|
||||
exports.EOF = EOF;
|
||||
exports.Function = Function;
|
||||
exports.Hash = Hash;
|
||||
exports.Ident = Ident;
|
||||
exports.LeftCurlyBracket = LeftCurlyBracket;
|
||||
exports.LeftParenthesis = LeftParenthesis;
|
||||
exports.LeftSquareBracket = LeftSquareBracket;
|
||||
exports.Number = Number;
|
||||
exports.Percentage = Percentage;
|
||||
exports.RightCurlyBracket = RightCurlyBracket;
|
||||
exports.RightParenthesis = RightParenthesis;
|
||||
exports.RightSquareBracket = RightSquareBracket;
|
||||
exports.Semicolon = Semicolon;
|
||||
exports.String = String;
|
||||
exports.Url = Url;
|
||||
exports.WhiteSpace = WhiteSpace;
|
||||
261
node_modules/css-tree/cjs/tokenizer/utils.cjs
generated
vendored
Executable file
261
node_modules/css-tree/cjs/tokenizer/utils.cjs
generated
vendored
Executable file
@@ -0,0 +1,261 @@
|
||||
'use strict';
|
||||
|
||||
const charCodeDefinitions = require('./char-code-definitions.cjs');
|
||||
|
||||
function getCharCode(source, offset) {
|
||||
return offset < source.length ? source.charCodeAt(offset) : 0;
|
||||
}
|
||||
|
||||
function getNewlineLength(source, offset, code) {
|
||||
if (code === 13 /* \r */ && getCharCode(source, offset + 1) === 10 /* \n */) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
function cmpChar(testStr, offset, referenceCode) {
|
||||
let code = testStr.charCodeAt(offset);
|
||||
|
||||
// code.toLowerCase() for A..Z
|
||||
if (charCodeDefinitions.isUppercaseLetter(code)) {
|
||||
code = code | 32;
|
||||
}
|
||||
|
||||
return code === referenceCode;
|
||||
}
|
||||
|
||||
function cmpStr(testStr, start, end, referenceStr) {
|
||||
if (end - start !== referenceStr.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (start < 0 || end > testStr.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = start; i < end; i++) {
|
||||
const referenceCode = referenceStr.charCodeAt(i - start);
|
||||
let testCode = testStr.charCodeAt(i);
|
||||
|
||||
// testCode.toLowerCase() for A..Z
|
||||
if (charCodeDefinitions.isUppercaseLetter(testCode)) {
|
||||
testCode = testCode | 32;
|
||||
}
|
||||
|
||||
if (testCode !== referenceCode) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function findWhiteSpaceStart(source, offset) {
|
||||
for (; offset >= 0; offset--) {
|
||||
if (!charCodeDefinitions.isWhiteSpace(source.charCodeAt(offset))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return offset + 1;
|
||||
}
|
||||
|
||||
function findWhiteSpaceEnd(source, offset) {
|
||||
for (; offset < source.length; offset++) {
|
||||
if (!charCodeDefinitions.isWhiteSpace(source.charCodeAt(offset))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
function findDecimalNumberEnd(source, offset) {
|
||||
for (; offset < source.length; offset++) {
|
||||
if (!charCodeDefinitions.isDigit(source.charCodeAt(offset))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
// § 4.3.7. Consume an escaped code point
|
||||
function consumeEscaped(source, offset) {
|
||||
// It assumes that the U+005C REVERSE SOLIDUS (\) has already been consumed and
|
||||
// that the next input code point has already been verified to be part of a valid escape.
|
||||
offset += 2;
|
||||
|
||||
// hex digit
|
||||
if (charCodeDefinitions.isHexDigit(getCharCode(source, offset - 1))) {
|
||||
// Consume as many hex digits as possible, but no more than 5.
|
||||
// Note that this means 1-6 hex digits have been consumed in total.
|
||||
for (const maxOffset = Math.min(source.length, offset + 5); offset < maxOffset; offset++) {
|
||||
if (!charCodeDefinitions.isHexDigit(getCharCode(source, offset))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the next input code point is whitespace, consume it as well.
|
||||
const code = getCharCode(source, offset);
|
||||
if (charCodeDefinitions.isWhiteSpace(code)) {
|
||||
offset += getNewlineLength(source, offset, code);
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
// §4.3.11. Consume a name
|
||||
// Note: This algorithm does not do the verification of the first few code points that are necessary
|
||||
// to ensure the returned code points would constitute an <ident-token>. If that is the intended use,
|
||||
// ensure that the stream starts with an identifier before calling this algorithm.
|
||||
function consumeName(source, offset) {
|
||||
// Let result initially be an empty string.
|
||||
// Repeatedly consume the next input code point from the stream:
|
||||
for (; offset < source.length; offset++) {
|
||||
const code = source.charCodeAt(offset);
|
||||
|
||||
// name code point
|
||||
if (charCodeDefinitions.isName(code)) {
|
||||
// Append the code point to result.
|
||||
continue;
|
||||
}
|
||||
|
||||
// the stream starts with a valid escape
|
||||
if (charCodeDefinitions.isValidEscape(code, getCharCode(source, offset + 1))) {
|
||||
// Consume an escaped code point. Append the returned code point to result.
|
||||
offset = consumeEscaped(source, offset) - 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// anything else
|
||||
// Reconsume the current input code point. Return result.
|
||||
break;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
// §4.3.12. Consume a number
|
||||
function consumeNumber(source, offset) {
|
||||
let code = source.charCodeAt(offset);
|
||||
|
||||
// 2. If the next input code point is U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-),
|
||||
// consume it and append it to repr.
|
||||
if (code === 0x002B || code === 0x002D) {
|
||||
code = source.charCodeAt(offset += 1);
|
||||
}
|
||||
|
||||
// 3. While the next input code point is a digit, consume it and append it to repr.
|
||||
if (charCodeDefinitions.isDigit(code)) {
|
||||
offset = findDecimalNumberEnd(source, offset + 1);
|
||||
code = source.charCodeAt(offset);
|
||||
}
|
||||
|
||||
// 4. If the next 2 input code points are U+002E FULL STOP (.) followed by a digit, then:
|
||||
if (code === 0x002E && charCodeDefinitions.isDigit(source.charCodeAt(offset + 1))) {
|
||||
// 4.1 Consume them.
|
||||
// 4.2 Append them to repr.
|
||||
offset += 2;
|
||||
|
||||
// 4.3 Set type to "number".
|
||||
// TODO
|
||||
|
||||
// 4.4 While the next input code point is a digit, consume it and append it to repr.
|
||||
|
||||
offset = findDecimalNumberEnd(source, offset);
|
||||
}
|
||||
|
||||
// 5. If the next 2 or 3 input code points are U+0045 LATIN CAPITAL LETTER E (E)
|
||||
// or U+0065 LATIN SMALL LETTER E (e), ... , followed by a digit, then:
|
||||
if (cmpChar(source, offset, 101 /* e */)) {
|
||||
let sign = 0;
|
||||
code = source.charCodeAt(offset + 1);
|
||||
|
||||
// ... optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+) ...
|
||||
if (code === 0x002D || code === 0x002B) {
|
||||
sign = 1;
|
||||
code = source.charCodeAt(offset + 2);
|
||||
}
|
||||
|
||||
// ... followed by a digit
|
||||
if (charCodeDefinitions.isDigit(code)) {
|
||||
// 5.1 Consume them.
|
||||
// 5.2 Append them to repr.
|
||||
|
||||
// 5.3 Set type to "number".
|
||||
// TODO
|
||||
|
||||
// 5.4 While the next input code point is a digit, consume it and append it to repr.
|
||||
offset = findDecimalNumberEnd(source, offset + 1 + sign + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
// § 4.3.14. Consume the remnants of a bad url
|
||||
// ... its sole use is to consume enough of the input stream to reach a recovery point
|
||||
// where normal tokenizing can resume.
|
||||
function consumeBadUrlRemnants(source, offset) {
|
||||
// Repeatedly consume the next input code point from the stream:
|
||||
for (; offset < source.length; offset++) {
|
||||
const code = source.charCodeAt(offset);
|
||||
|
||||
// U+0029 RIGHT PARENTHESIS ())
|
||||
// EOF
|
||||
if (code === 0x0029) {
|
||||
// Return.
|
||||
offset++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (charCodeDefinitions.isValidEscape(code, getCharCode(source, offset + 1))) {
|
||||
// Consume an escaped code point.
|
||||
// Note: This allows an escaped right parenthesis ("\)") to be encountered
|
||||
// without ending the <bad-url-token>. This is otherwise identical to
|
||||
// the "anything else" clause.
|
||||
offset = consumeEscaped(source, offset);
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
// § 4.3.7. Consume an escaped code point
|
||||
// Note: This algorithm assumes that escaped is valid without leading U+005C REVERSE SOLIDUS (\)
|
||||
function decodeEscaped(escaped) {
|
||||
// Single char escaped that's not a hex digit
|
||||
if (escaped.length === 1 && !charCodeDefinitions.isHexDigit(escaped.charCodeAt(0))) {
|
||||
return escaped[0];
|
||||
}
|
||||
|
||||
// Interpret the hex digits as a hexadecimal number.
|
||||
let code = parseInt(escaped, 16);
|
||||
|
||||
if (
|
||||
(code === 0) || // If this number is zero,
|
||||
(code >= 0xD800 && code <= 0xDFFF) || // or is for a surrogate,
|
||||
(code > 0x10FFFF) // or is greater than the maximum allowed code point
|
||||
) {
|
||||
// ... return U+FFFD REPLACEMENT CHARACTER
|
||||
code = 0xFFFD;
|
||||
}
|
||||
|
||||
// Otherwise, return the code point with that value.
|
||||
return String.fromCodePoint(code);
|
||||
}
|
||||
|
||||
exports.cmpChar = cmpChar;
|
||||
exports.cmpStr = cmpStr;
|
||||
exports.consumeBadUrlRemnants = consumeBadUrlRemnants;
|
||||
exports.consumeEscaped = consumeEscaped;
|
||||
exports.consumeName = consumeName;
|
||||
exports.consumeNumber = consumeNumber;
|
||||
exports.decodeEscaped = decodeEscaped;
|
||||
exports.findDecimalNumberEnd = findDecimalNumberEnd;
|
||||
exports.findWhiteSpaceEnd = findWhiteSpaceEnd;
|
||||
exports.findWhiteSpaceStart = findWhiteSpaceStart;
|
||||
exports.getNewlineLength = getNewlineLength;
|
||||
Reference in New Issue
Block a user