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:
87
node_modules/css-tree/lib/tokenizer/OffsetToLocation.js
generated
vendored
Normal file
87
node_modules/css-tree/lib/tokenizer/OffsetToLocation.js
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
import { adoptBuffer } from './adopt-buffer.js';
|
||||
import { isBOM } from './char-code-definitions.js';
|
||||
|
||||
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 ? isBOM(source.charCodeAt(0)) : 0;
|
||||
const lines = adoptBuffer(host.lines, sourceLength);
|
||||
const columns = 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;
|
||||
}
|
||||
|
||||
export 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]
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
316
node_modules/css-tree/lib/tokenizer/TokenStream.js
generated
vendored
Normal file
316
node_modules/css-tree/lib/tokenizer/TokenStream.js
generated
vendored
Normal file
@@ -0,0 +1,316 @@
|
||||
import { adoptBuffer } from './adopt-buffer.js';
|
||||
import { cmpStr } from './utils.js';
|
||||
import tokenNames from './names.js';
|
||||
import {
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
Delim,
|
||||
EOF,
|
||||
Function as FunctionToken,
|
||||
LeftParenthesis,
|
||||
RightParenthesis,
|
||||
LeftSquareBracket,
|
||||
RightSquareBracket,
|
||||
LeftCurlyBracket,
|
||||
RightCurlyBracket
|
||||
} from './types.js';
|
||||
|
||||
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[FunctionToken] = RightParenthesis;
|
||||
balancePair[LeftParenthesis] = RightParenthesis;
|
||||
balancePair[LeftSquareBracket] = RightSquareBracket;
|
||||
balancePair[LeftCurlyBracket] = RightCurlyBracket;
|
||||
|
||||
function isBlockOpenerToken(tokenType) {
|
||||
return balancePair[tokenType] !== 0;
|
||||
}
|
||||
|
||||
export 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(this.offsetAndType, source.length + 1); // +1 because of eof-token
|
||||
const balance = 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] = (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 EOF;
|
||||
}
|
||||
lookupTypeNonSC(idx) {
|
||||
for (let offset = this.tokenIndex; offset < this.tokenCount; offset++) {
|
||||
const tokenType = this.offsetAndType[offset] >> TYPE_SHIFT;
|
||||
|
||||
if (tokenType !== WhiteSpace && tokenType !== Comment) {
|
||||
if (idx-- === 0) {
|
||||
return tokenType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 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 !== WhiteSpace && tokenType !== Comment) {
|
||||
if (idx-- === 0) {
|
||||
return offset - this.tokenIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EOF;
|
||||
}
|
||||
lookupValue(offset, referenceStr) {
|
||||
offset += this.tokenIndex;
|
||||
|
||||
if (offset < this.tokenCount) {
|
||||
return 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) === Delim &&
|
||||
this.source.charCodeAt(this.lookupOffset(offset)) === code
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
this.tokenType === 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 = EOF;
|
||||
this.tokenStart = this.tokenEnd = this.source.length;
|
||||
}
|
||||
}
|
||||
skipSC() {
|
||||
while (this.tokenType === WhiteSpace || this.tokenType === 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: tokenNames[type],
|
||||
chunk: this.source.substring(start, end),
|
||||
balance: this.balance[index]
|
||||
};
|
||||
});
|
||||
|
||||
return tokens;
|
||||
}
|
||||
};
|
||||
9
node_modules/css-tree/lib/tokenizer/adopt-buffer.js
generated
vendored
Normal file
9
node_modules/css-tree/lib/tokenizer/adopt-buffer.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
const MIN_SIZE = 16 * 1024;
|
||||
|
||||
export function adoptBuffer(buffer = null, size) {
|
||||
if (buffer === null || buffer.length < size) {
|
||||
return new Uint32Array(Math.max(size + 1024, MIN_SIZE));
|
||||
}
|
||||
|
||||
return buffer;
|
||||
};
|
||||
113
node_modules/css-tree/lib/tokenizer/char-code-definitions.js
generated
vendored
113
node_modules/css-tree/lib/tokenizer/char-code-definitions.js
generated
vendored
@@ -1,18 +1,18 @@
|
||||
var EOF = 0;
|
||||
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) {
|
||||
export 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) {
|
||||
export function isHexDigit(code) {
|
||||
return (
|
||||
isDigit(code) || // 0 .. 9
|
||||
(code >= 0x0041 && code <= 0x0046) || // A .. F
|
||||
@@ -22,44 +22,49 @@ function isHexDigit(code) {
|
||||
|
||||
// uppercase letter
|
||||
// A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z).
|
||||
function isUppercaseLetter(code) {
|
||||
export 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) {
|
||||
export function isLowercaseLetter(code) {
|
||||
return code >= 0x0061 && code <= 0x007A;
|
||||
}
|
||||
|
||||
// letter
|
||||
// An uppercase letter or a lowercase letter.
|
||||
function isLetter(code) {
|
||||
export 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>.
|
||||
function isNonAscii(code) {
|
||||
//
|
||||
// 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.
|
||||
export 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) {
|
||||
export 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) {
|
||||
export 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) {
|
||||
export function isNonPrintable(code) {
|
||||
return (
|
||||
(code >= 0x0000 && code <= 0x0008) ||
|
||||
(code === 0x000B) ||
|
||||
@@ -72,18 +77,18 @@ function isNonPrintable(code) {
|
||||
// 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) {
|
||||
export function isNewline(code) {
|
||||
return code === 0x000A || code === 0x000D || code === 0x000C;
|
||||
}
|
||||
|
||||
// whitespace
|
||||
// A newline, U+0009 CHARACTER TABULATION, or U+0020 SPACE.
|
||||
function isWhiteSpace(code) {
|
||||
export 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) {
|
||||
export function isValidEscape(first, second) {
|
||||
// If the first code point is not U+005C REVERSE SOLIDUS (\), return false.
|
||||
if (first !== 0x005C) {
|
||||
return false;
|
||||
@@ -99,7 +104,7 @@ function isValidEscape(first, second) {
|
||||
}
|
||||
|
||||
// § 4.3.9. Check if three code points would start an identifier
|
||||
function isIdentifierStart(first, second, third) {
|
||||
export function isIdentifierStart(first, second, third) {
|
||||
// Look at the first code point:
|
||||
|
||||
// U+002D HYPHEN-MINUS
|
||||
@@ -131,7 +136,7 @@ function isIdentifierStart(first, second, third) {
|
||||
}
|
||||
|
||||
// § 4.3.10. Check if three code points would start a number
|
||||
function isNumberStart(first, second, third) {
|
||||
export function isNumberStart(first, second, third) {
|
||||
// Look at the first code point:
|
||||
|
||||
// U+002B PLUS SIGN (+)
|
||||
@@ -170,7 +175,7 @@ function isNumberStart(first, second, third) {
|
||||
//
|
||||
|
||||
// detect BOM (https://en.wikipedia.org/wiki/Byte_order_mark)
|
||||
function isBOM(code) {
|
||||
export function isBOM(code) {
|
||||
// UTF-16BE
|
||||
if (code === 0xFEFF) {
|
||||
return 1;
|
||||
@@ -185,65 +190,23 @@ function isBOM(code) {
|
||||
}
|
||||
|
||||
// Fast code category
|
||||
//
|
||||
// https://drafts.csswg.org/css-syntax/#tokenizer-definitions
|
||||
// > non-ASCII code point
|
||||
// > A code point with a value equal to or greater than U+0080 <control>
|
||||
// > name-start code point
|
||||
// > A letter, a non-ASCII code point, or U+005F LOW LINE (_).
|
||||
// > name code point
|
||||
// > A name-start code point, a digit, or U+002D HYPHEN-MINUS (-)
|
||||
// That means only ASCII code points has a special meaning and we define a maps for 0..127 codes only
|
||||
var CATEGORY = new Array(0x80);
|
||||
charCodeCategory.Eof = 0x80;
|
||||
charCodeCategory.WhiteSpace = 0x82;
|
||||
charCodeCategory.Digit = 0x83;
|
||||
charCodeCategory.NameStart = 0x84;
|
||||
charCodeCategory.NonPrintable = 0x85;
|
||||
// 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);
|
||||
export const EofCategory = 0x80;
|
||||
export const WhiteSpaceCategory = 0x82;
|
||||
export const DigitCategory = 0x83;
|
||||
export const NameStartCategory = 0x84;
|
||||
export const NonPrintableCategory = 0x85;
|
||||
|
||||
for (var i = 0; i < CATEGORY.length; i++) {
|
||||
switch (true) {
|
||||
case isWhiteSpace(i):
|
||||
CATEGORY[i] = charCodeCategory.WhiteSpace;
|
||||
break;
|
||||
|
||||
case isDigit(i):
|
||||
CATEGORY[i] = charCodeCategory.Digit;
|
||||
break;
|
||||
|
||||
case isNameStart(i):
|
||||
CATEGORY[i] = charCodeCategory.NameStart;
|
||||
break;
|
||||
|
||||
case isNonPrintable(i):
|
||||
CATEGORY[i] = charCodeCategory.NonPrintable;
|
||||
break;
|
||||
|
||||
default:
|
||||
CATEGORY[i] = i || charCodeCategory.Eof;
|
||||
}
|
||||
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] : charCodeCategory.NameStart;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
isDigit: isDigit,
|
||||
isHexDigit: isHexDigit,
|
||||
isUppercaseLetter: isUppercaseLetter,
|
||||
isLowercaseLetter: isLowercaseLetter,
|
||||
isLetter: isLetter,
|
||||
isNonAscii: isNonAscii,
|
||||
isNameStart: isNameStart,
|
||||
isName: isName,
|
||||
isNonPrintable: isNonPrintable,
|
||||
isNewline: isNewline,
|
||||
isWhiteSpace: isWhiteSpace,
|
||||
isValidEscape: isValidEscape,
|
||||
isIdentifierStart: isIdentifierStart,
|
||||
isNumberStart: isNumberStart,
|
||||
|
||||
isBOM: isBOM,
|
||||
charCodeCategory: charCodeCategory
|
||||
};
|
||||
export function charCodeCategory(code) {
|
||||
return code < 0x80 ? CATEGORY[code] : NameStartCategory;
|
||||
}
|
||||
|
||||
40
node_modules/css-tree/lib/tokenizer/const.js
generated
vendored
40
node_modules/css-tree/lib/tokenizer/const.js
generated
vendored
@@ -1,40 +0,0 @@
|
||||
// CSS Syntax Module Level 3
|
||||
// https://www.w3.org/TR/css-syntax-3/
|
||||
var TYPE = {
|
||||
EOF: 0, // <EOF-token>
|
||||
Ident: 1, // <ident-token>
|
||||
Function: 2, // <function-token>
|
||||
AtKeyword: 3, // <at-keyword-token>
|
||||
Hash: 4, // <hash-token>
|
||||
String: 5, // <string-token>
|
||||
BadString: 6, // <bad-string-token>
|
||||
Url: 7, // <url-token>
|
||||
BadUrl: 8, // <bad-url-token>
|
||||
Delim: 9, // <delim-token>
|
||||
Number: 10, // <number-token>
|
||||
Percentage: 11, // <percentage-token>
|
||||
Dimension: 12, // <dimension-token>
|
||||
WhiteSpace: 13, // <whitespace-token>
|
||||
CDO: 14, // <CDO-token>
|
||||
CDC: 15, // <CDC-token>
|
||||
Colon: 16, // <colon-token> :
|
||||
Semicolon: 17, // <semicolon-token> ;
|
||||
Comma: 18, // <comma-token> ,
|
||||
LeftSquareBracket: 19, // <[-token>
|
||||
RightSquareBracket: 20, // <]-token>
|
||||
LeftParenthesis: 21, // <(-token>
|
||||
RightParenthesis: 22, // <)-token>
|
||||
LeftCurlyBracket: 23, // <{-token>
|
||||
RightCurlyBracket: 24, // <}-token>
|
||||
Comment: 25
|
||||
};
|
||||
|
||||
var NAME = Object.keys(TYPE).reduce(function(result, key) {
|
||||
result[TYPE[key]] = key;
|
||||
return result;
|
||||
}, {});
|
||||
|
||||
module.exports = {
|
||||
TYPE: TYPE,
|
||||
NAME: NAME
|
||||
};
|
||||
194
node_modules/css-tree/lib/tokenizer/index.js
generated
vendored
194
node_modules/css-tree/lib/tokenizer/index.js
generated
vendored
@@ -1,31 +1,28 @@
|
||||
var TokenStream = require('../common/TokenStream');
|
||||
var adoptBuffer = require('../common/adopt-buffer');
|
||||
import * as TYPE from './types.js';
|
||||
import {
|
||||
isNewline,
|
||||
isName,
|
||||
isValidEscape,
|
||||
isNumberStart,
|
||||
isIdentifierStart,
|
||||
isBOM,
|
||||
charCodeCategory,
|
||||
WhiteSpaceCategory,
|
||||
DigitCategory,
|
||||
NameStartCategory,
|
||||
NonPrintableCategory
|
||||
} from './char-code-definitions.js';
|
||||
import {
|
||||
cmpStr,
|
||||
getNewlineLength,
|
||||
findWhiteSpaceEnd,
|
||||
consumeEscaped,
|
||||
consumeName,
|
||||
consumeNumber,
|
||||
consumeBadUrlRemnants
|
||||
} from './utils.js';
|
||||
|
||||
var constants = require('./const');
|
||||
var TYPE = constants.TYPE;
|
||||
|
||||
var charCodeDefinitions = require('./char-code-definitions');
|
||||
var isNewline = charCodeDefinitions.isNewline;
|
||||
var isName = charCodeDefinitions.isName;
|
||||
var isValidEscape = charCodeDefinitions.isValidEscape;
|
||||
var isNumberStart = charCodeDefinitions.isNumberStart;
|
||||
var isIdentifierStart = charCodeDefinitions.isIdentifierStart;
|
||||
var charCodeCategory = charCodeDefinitions.charCodeCategory;
|
||||
var isBOM = charCodeDefinitions.isBOM;
|
||||
|
||||
var utils = require('./utils');
|
||||
var cmpStr = utils.cmpStr;
|
||||
var getNewlineLength = utils.getNewlineLength;
|
||||
var findWhiteSpaceEnd = utils.findWhiteSpaceEnd;
|
||||
var consumeEscaped = utils.consumeEscaped;
|
||||
var consumeName = utils.consumeName;
|
||||
var consumeNumber = utils.consumeNumber;
|
||||
var consumeBadUrlRemnants = utils.consumeBadUrlRemnants;
|
||||
|
||||
var OFFSET_MASK = 0x00FFFFFF;
|
||||
var TYPE_SHIFT = 24;
|
||||
|
||||
function tokenize(source, stream) {
|
||||
export function tokenize(source, onToken) {
|
||||
function getCharCode(offset) {
|
||||
return offset < sourceLength ? source.charCodeAt(offset) : 0;
|
||||
}
|
||||
@@ -111,7 +108,7 @@ function tokenize(source, stream) {
|
||||
|
||||
// Repeatedly consume the next input code point from the stream:
|
||||
for (; offset < source.length; offset++) {
|
||||
var code = source.charCodeAt(offset);
|
||||
const code = source.charCodeAt(offset);
|
||||
|
||||
switch (charCodeCategory(code)) {
|
||||
// ending code point
|
||||
@@ -120,13 +117,13 @@ function tokenize(source, stream) {
|
||||
offset++;
|
||||
return;
|
||||
|
||||
// EOF
|
||||
case charCodeCategory.Eof:
|
||||
// EOF
|
||||
// case EofCategory:
|
||||
// This is a parse error. Return the <string-token>.
|
||||
return;
|
||||
// return;
|
||||
|
||||
// newline
|
||||
case charCodeCategory.WhiteSpace:
|
||||
case WhiteSpaceCategory:
|
||||
if (isNewline(code)) {
|
||||
// This is a parse error. Reconsume the current input code point,
|
||||
// create a <bad-string-token>, and return it.
|
||||
@@ -143,7 +140,7 @@ function tokenize(source, stream) {
|
||||
break;
|
||||
}
|
||||
|
||||
var nextCode = getCharCode(offset + 1);
|
||||
const nextCode = getCharCode(offset + 1);
|
||||
|
||||
// Otherwise, if the next input code point is a newline, consume it.
|
||||
if (isNewline(nextCode)) {
|
||||
@@ -176,7 +173,7 @@ function tokenize(source, stream) {
|
||||
|
||||
// Repeatedly consume the next input code point from the stream:
|
||||
for (; offset < source.length; offset++) {
|
||||
var code = source.charCodeAt(offset);
|
||||
const code = source.charCodeAt(offset);
|
||||
|
||||
switch (charCodeCategory(code)) {
|
||||
// U+0029 RIGHT PARENTHESIS ())
|
||||
@@ -185,13 +182,13 @@ function tokenize(source, stream) {
|
||||
offset++;
|
||||
return;
|
||||
|
||||
// EOF
|
||||
case charCodeCategory.Eof:
|
||||
// EOF
|
||||
// case EofCategory:
|
||||
// This is a parse error. Return the <url-token>.
|
||||
return;
|
||||
// return;
|
||||
|
||||
// whitespace
|
||||
case charCodeCategory.WhiteSpace:
|
||||
case WhiteSpaceCategory:
|
||||
// Consume as much whitespace as possible.
|
||||
offset = findWhiteSpaceEnd(source, offset);
|
||||
|
||||
@@ -218,7 +215,7 @@ function tokenize(source, stream) {
|
||||
case 0x0022:
|
||||
case 0x0027:
|
||||
case 0x0028:
|
||||
case charCodeCategory.NonPrintable:
|
||||
case NonPrintableCategory:
|
||||
// This is a parse error. Consume the remnants of a bad url,
|
||||
// create a <bad-url-token>, and return it.
|
||||
offset = consumeBadUrlRemnants(source, offset);
|
||||
@@ -246,34 +243,22 @@ function tokenize(source, stream) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!stream) {
|
||||
stream = new TokenStream();
|
||||
}
|
||||
|
||||
// ensure source is a string
|
||||
source = String(source || '');
|
||||
|
||||
var sourceLength = source.length;
|
||||
var offsetAndType = adoptBuffer(stream.offsetAndType, sourceLength + 1); // +1 because of eof-token
|
||||
var balance = adoptBuffer(stream.balance, sourceLength + 1);
|
||||
var tokenCount = 0;
|
||||
var start = isBOM(getCharCode(0));
|
||||
var offset = start;
|
||||
var balanceCloseType = 0;
|
||||
var balanceStart = 0;
|
||||
var balancePrev = 0;
|
||||
const sourceLength = source.length;
|
||||
let start = 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) {
|
||||
var code = source.charCodeAt(offset);
|
||||
var type = 0;
|
||||
|
||||
balance[tokenCount] = sourceLength;
|
||||
const code = source.charCodeAt(offset);
|
||||
|
||||
switch (charCodeCategory(code)) {
|
||||
// whitespace
|
||||
case charCodeCategory.WhiteSpace:
|
||||
case WhiteSpaceCategory:
|
||||
// Consume as much whitespace as possible. Return a <whitespace-token>.
|
||||
type = TYPE.WhiteSpace;
|
||||
offset = findWhiteSpaceEnd(source, offset + 1);
|
||||
@@ -395,10 +380,8 @@ function tokenize(source, stream) {
|
||||
// ... 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 = TYPE.Comment;
|
||||
offset = source.indexOf('*/', offset + 2) + 2;
|
||||
if (offset === 1) {
|
||||
offset = source.length;
|
||||
}
|
||||
offset = source.indexOf('*/', offset + 2);
|
||||
offset = offset === -1 ? source.length : offset + 2;
|
||||
} else {
|
||||
type = TYPE.Delim;
|
||||
offset++;
|
||||
@@ -493,21 +476,21 @@ function tokenize(source, stream) {
|
||||
break;
|
||||
|
||||
// digit
|
||||
case charCodeCategory.Digit:
|
||||
case DigitCategory:
|
||||
// Reconsume the current input code point, consume a numeric token, and return it.
|
||||
consumeNumericToken();
|
||||
break;
|
||||
|
||||
// name-start code point
|
||||
case charCodeCategory.NameStart:
|
||||
case NameStartCategory:
|
||||
// Reconsume the current input code point, consume an ident-like token, and return it.
|
||||
consumeIdentLikeToken();
|
||||
break;
|
||||
|
||||
// EOF
|
||||
case charCodeCategory.Eof:
|
||||
// EOF
|
||||
// case EofCategory:
|
||||
// Return an <EOF-token>.
|
||||
break;
|
||||
// break;
|
||||
|
||||
// anything else
|
||||
default:
|
||||
@@ -516,76 +499,15 @@ function tokenize(source, stream) {
|
||||
offset++;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case balanceCloseType:
|
||||
balancePrev = balanceStart & OFFSET_MASK;
|
||||
balanceStart = balance[balancePrev];
|
||||
balanceCloseType = balanceStart >> TYPE_SHIFT;
|
||||
balance[tokenCount] = balancePrev;
|
||||
balance[balancePrev++] = tokenCount;
|
||||
for (; balancePrev < tokenCount; balancePrev++) {
|
||||
if (balance[balancePrev] === sourceLength) {
|
||||
balance[balancePrev] = tokenCount;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE.LeftParenthesis:
|
||||
case TYPE.Function:
|
||||
balance[tokenCount] = balanceStart;
|
||||
balanceCloseType = TYPE.RightParenthesis;
|
||||
balanceStart = (balanceCloseType << TYPE_SHIFT) | tokenCount;
|
||||
break;
|
||||
|
||||
case TYPE.LeftSquareBracket:
|
||||
balance[tokenCount] = balanceStart;
|
||||
balanceCloseType = TYPE.RightSquareBracket;
|
||||
balanceStart = (balanceCloseType << TYPE_SHIFT) | tokenCount;
|
||||
break;
|
||||
|
||||
case TYPE.LeftCurlyBracket:
|
||||
balance[tokenCount] = balanceStart;
|
||||
balanceCloseType = TYPE.RightCurlyBracket;
|
||||
balanceStart = (balanceCloseType << TYPE_SHIFT) | tokenCount;
|
||||
break;
|
||||
}
|
||||
|
||||
offsetAndType[tokenCount++] = (type << TYPE_SHIFT) | offset;
|
||||
// put token to stream
|
||||
onToken(type, start, start = offset);
|
||||
}
|
||||
|
||||
// finalize buffers
|
||||
offsetAndType[tokenCount] = (TYPE.EOF << TYPE_SHIFT) | offset; // <EOF-token>
|
||||
balance[tokenCount] = sourceLength;
|
||||
balance[sourceLength] = sourceLength; // prevents false positive balance match with any token
|
||||
while (balanceStart !== 0) {
|
||||
balancePrev = balanceStart & OFFSET_MASK;
|
||||
balanceStart = balance[balancePrev];
|
||||
balance[balancePrev] = sourceLength;
|
||||
}
|
||||
|
||||
// update stream
|
||||
stream.source = source;
|
||||
stream.firstCharOffset = start;
|
||||
stream.offsetAndType = offsetAndType;
|
||||
stream.tokenCount = tokenCount;
|
||||
stream.balance = balance;
|
||||
stream.reset();
|
||||
stream.next();
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
// extend tokenizer with constants
|
||||
Object.keys(constants).forEach(function(key) {
|
||||
tokenize[key] = constants[key];
|
||||
});
|
||||
|
||||
// extend tokenizer with static methods from utils
|
||||
Object.keys(charCodeDefinitions).forEach(function(key) {
|
||||
tokenize[key] = charCodeDefinitions[key];
|
||||
});
|
||||
Object.keys(utils).forEach(function(key) {
|
||||
tokenize[key] = utils[key];
|
||||
});
|
||||
|
||||
module.exports = tokenize;
|
||||
export * from './types.js';
|
||||
export * as tokenTypes from './types.js';
|
||||
export { default as tokenNames } from './names.js';
|
||||
export * from './char-code-definitions.js';
|
||||
export * from './utils.js';
|
||||
export * from './OffsetToLocation.js';
|
||||
export * from './TokenStream.js';
|
||||
|
||||
28
node_modules/css-tree/lib/tokenizer/names.js
generated
vendored
Normal file
28
node_modules/css-tree/lib/tokenizer/names.js
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
export default [
|
||||
'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'
|
||||
];
|
||||
28
node_modules/css-tree/lib/tokenizer/types.js
generated
vendored
Normal file
28
node_modules/css-tree/lib/tokenizer/types.js
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
// CSS Syntax Module Level 3
|
||||
// https://www.w3.org/TR/css-syntax-3/
|
||||
export const EOF = 0; // <EOF-token>
|
||||
export const Ident = 1; // <ident-token>
|
||||
export const Function = 2; // <function-token>
|
||||
export const AtKeyword = 3; // <at-keyword-token>
|
||||
export const Hash = 4; // <hash-token>
|
||||
export const String = 5; // <string-token>
|
||||
export const BadString = 6; // <bad-string-token>
|
||||
export const Url = 7; // <url-token>
|
||||
export const BadUrl = 8; // <bad-url-token>
|
||||
export const Delim = 9; // <delim-token>
|
||||
export const Number = 10; // <number-token>
|
||||
export const Percentage = 11; // <percentage-token>
|
||||
export const Dimension = 12; // <dimension-token>
|
||||
export const WhiteSpace = 13; // <whitespace-token>
|
||||
export const CDO = 14; // <CDO-token>
|
||||
export const CDC = 15; // <CDC-token>
|
||||
export const Colon = 16; // <colon-token> :
|
||||
export const Semicolon = 17; // <semicolon-token> ;
|
||||
export const Comma = 18; // <comma-token> ,
|
||||
export const LeftSquareBracket = 19; // <[-token>
|
||||
export const RightSquareBracket = 20; // <]-token>
|
||||
export const LeftParenthesis = 21; // <(-token>
|
||||
export const RightParenthesis = 22; // <)-token>
|
||||
export const LeftCurlyBracket = 23; // <{-token>
|
||||
export const RightCurlyBracket = 24; // <}-token>
|
||||
export const Comment = 25;
|
||||
89
node_modules/css-tree/lib/tokenizer/utils.js
generated
vendored
89
node_modules/css-tree/lib/tokenizer/utils.js
generated
vendored
@@ -1,16 +1,17 @@
|
||||
var charCodeDef = require('./char-code-definitions');
|
||||
var isDigit = charCodeDef.isDigit;
|
||||
var isHexDigit = charCodeDef.isHexDigit;
|
||||
var isUppercaseLetter = charCodeDef.isUppercaseLetter;
|
||||
var isName = charCodeDef.isName;
|
||||
var isWhiteSpace = charCodeDef.isWhiteSpace;
|
||||
var isValidEscape = charCodeDef.isValidEscape;
|
||||
import {
|
||||
isDigit,
|
||||
isHexDigit,
|
||||
isUppercaseLetter,
|
||||
isName,
|
||||
isWhiteSpace,
|
||||
isValidEscape
|
||||
} from './char-code-definitions.js';
|
||||
|
||||
function getCharCode(source, offset) {
|
||||
return offset < source.length ? source.charCodeAt(offset) : 0;
|
||||
}
|
||||
|
||||
function getNewlineLength(source, offset, code) {
|
||||
export function getNewlineLength(source, offset, code) {
|
||||
if (code === 13 /* \r */ && getCharCode(source, offset + 1) === 10 /* \n */) {
|
||||
return 2;
|
||||
}
|
||||
@@ -18,8 +19,8 @@ function getNewlineLength(source, offset, code) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
function cmpChar(testStr, offset, referenceCode) {
|
||||
var code = testStr.charCodeAt(offset);
|
||||
export function cmpChar(testStr, offset, referenceCode) {
|
||||
let code = testStr.charCodeAt(offset);
|
||||
|
||||
// code.toLowerCase() for A..Z
|
||||
if (isUppercaseLetter(code)) {
|
||||
@@ -29,7 +30,7 @@ function cmpChar(testStr, offset, referenceCode) {
|
||||
return code === referenceCode;
|
||||
}
|
||||
|
||||
function cmpStr(testStr, start, end, referenceStr) {
|
||||
export function cmpStr(testStr, start, end, referenceStr) {
|
||||
if (end - start !== referenceStr.length) {
|
||||
return false;
|
||||
}
|
||||
@@ -38,9 +39,9 @@ function cmpStr(testStr, start, end, referenceStr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = start; i < end; i++) {
|
||||
var testCode = testStr.charCodeAt(i);
|
||||
var referenceCode = referenceStr.charCodeAt(i - start);
|
||||
for (let i = start; i < end; i++) {
|
||||
const referenceCode = referenceStr.charCodeAt(i - start);
|
||||
let testCode = testStr.charCodeAt(i);
|
||||
|
||||
// testCode.toLowerCase() for A..Z
|
||||
if (isUppercaseLetter(testCode)) {
|
||||
@@ -55,7 +56,7 @@ function cmpStr(testStr, start, end, referenceStr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function findWhiteSpaceStart(source, offset) {
|
||||
export function findWhiteSpaceStart(source, offset) {
|
||||
for (; offset >= 0; offset--) {
|
||||
if (!isWhiteSpace(source.charCodeAt(offset))) {
|
||||
break;
|
||||
@@ -65,7 +66,7 @@ function findWhiteSpaceStart(source, offset) {
|
||||
return offset + 1;
|
||||
}
|
||||
|
||||
function findWhiteSpaceEnd(source, offset) {
|
||||
export function findWhiteSpaceEnd(source, offset) {
|
||||
for (; offset < source.length; offset++) {
|
||||
if (!isWhiteSpace(source.charCodeAt(offset))) {
|
||||
break;
|
||||
@@ -75,7 +76,7 @@ function findWhiteSpaceEnd(source, offset) {
|
||||
return offset;
|
||||
}
|
||||
|
||||
function findDecimalNumberEnd(source, offset) {
|
||||
export function findDecimalNumberEnd(source, offset) {
|
||||
for (; offset < source.length; offset++) {
|
||||
if (!isDigit(source.charCodeAt(offset))) {
|
||||
break;
|
||||
@@ -86,7 +87,7 @@ function findDecimalNumberEnd(source, offset) {
|
||||
}
|
||||
|
||||
// § 4.3.7. Consume an escaped code point
|
||||
function consumeEscaped(source, offset) {
|
||||
export 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;
|
||||
@@ -95,14 +96,14 @@ function consumeEscaped(source, offset) {
|
||||
if (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 (var maxOffset = Math.min(source.length, offset + 5); offset < maxOffset; offset++) {
|
||||
for (const maxOffset = Math.min(source.length, offset + 5); offset < maxOffset; offset++) {
|
||||
if (!isHexDigit(getCharCode(source, offset))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the next input code point is whitespace, consume it as well.
|
||||
var code = getCharCode(source, offset);
|
||||
const code = getCharCode(source, offset);
|
||||
if (isWhiteSpace(code)) {
|
||||
offset += getNewlineLength(source, offset, code);
|
||||
}
|
||||
@@ -115,11 +116,11 @@ function consumeEscaped(source, offset) {
|
||||
// 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) {
|
||||
export 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++) {
|
||||
var code = source.charCodeAt(offset);
|
||||
const code = source.charCodeAt(offset);
|
||||
|
||||
// name code point
|
||||
if (isName(code)) {
|
||||
@@ -143,8 +144,8 @@ function consumeName(source, offset) {
|
||||
}
|
||||
|
||||
// §4.3.12. Consume a number
|
||||
function consumeNumber(source, offset) {
|
||||
var code = source.charCodeAt(offset);
|
||||
export 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.
|
||||
@@ -162,7 +163,7 @@ function consumeNumber(source, offset) {
|
||||
if (code === 0x002E && isDigit(source.charCodeAt(offset + 1))) {
|
||||
// 4.1 Consume them.
|
||||
// 4.2 Append them to repr.
|
||||
code = source.charCodeAt(offset += 2);
|
||||
offset += 2;
|
||||
|
||||
// 4.3 Set type to "number".
|
||||
// TODO
|
||||
@@ -175,7 +176,7 @@ function consumeNumber(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 */)) {
|
||||
var sign = 0;
|
||||
let sign = 0;
|
||||
code = source.charCodeAt(offset + 1);
|
||||
|
||||
// ... optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+) ...
|
||||
@@ -203,10 +204,10 @@ function consumeNumber(source, 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) {
|
||||
export function consumeBadUrlRemnants(source, offset) {
|
||||
// Repeatedly consume the next input code point from the stream:
|
||||
for (; offset < source.length; offset++) {
|
||||
var code = source.charCodeAt(offset);
|
||||
const code = source.charCodeAt(offset);
|
||||
|
||||
// U+0029 RIGHT PARENTHESIS ())
|
||||
// EOF
|
||||
@@ -228,16 +229,26 @@ function consumeBadUrlRemnants(source, offset) {
|
||||
return offset;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
consumeEscaped: consumeEscaped,
|
||||
consumeName: consumeName,
|
||||
consumeNumber: consumeNumber,
|
||||
consumeBadUrlRemnants: consumeBadUrlRemnants,
|
||||
// § 4.3.7. Consume an escaped code point
|
||||
// Note: This algorithm assumes that escaped is valid without leading U+005C REVERSE SOLIDUS (\)
|
||||
export function decodeEscaped(escaped) {
|
||||
// Single char escaped that's not a hex digit
|
||||
if (escaped.length === 1 && !isHexDigit(escaped.charCodeAt(0))) {
|
||||
return escaped[0];
|
||||
}
|
||||
|
||||
cmpChar: cmpChar,
|
||||
cmpStr: cmpStr,
|
||||
// Interpret the hex digits as a hexadecimal number.
|
||||
let code = parseInt(escaped, 16);
|
||||
|
||||
getNewlineLength: getNewlineLength,
|
||||
findWhiteSpaceStart: findWhiteSpaceStart,
|
||||
findWhiteSpaceEnd: findWhiteSpaceEnd
|
||||
};
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user