format: prettify entire project
This commit is contained in:
46
node_modules/css-tree/lib/convertor/create.js
generated
vendored
46
node_modules/css-tree/lib/convertor/create.js
generated
vendored
@ -1,28 +1,28 @@
|
||||
import { List } from '../utils/List.js';
|
||||
|
||||
export function createConvertor(walk) {
|
||||
return {
|
||||
fromPlainObject(ast) {
|
||||
walk(ast, {
|
||||
enter(node) {
|
||||
if (node.children && node.children instanceof List === false) {
|
||||
node.children = new List().fromArray(node.children);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return ast;
|
||||
return {
|
||||
fromPlainObject(ast) {
|
||||
walk(ast, {
|
||||
enter(node) {
|
||||
if (node.children && node.children instanceof List === false) {
|
||||
node.children = new List().fromArray(node.children);
|
||||
}
|
||||
},
|
||||
toPlainObject(ast) {
|
||||
walk(ast, {
|
||||
leave(node) {
|
||||
if (node.children && node.children instanceof List) {
|
||||
node.children = node.children.toArray();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return ast;
|
||||
}
|
||||
};
|
||||
};
|
||||
return ast;
|
||||
},
|
||||
toPlainObject(ast) {
|
||||
walk(ast, {
|
||||
leave(node) {
|
||||
if (node.children && node.children instanceof List) {
|
||||
node.children = node.children.toArray();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return ast;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
137
node_modules/css-tree/lib/data.js
generated
vendored
137
node_modules/css-tree/lib/data.js
generated
vendored
@ -9,87 +9,100 @@ const mdnSyntaxes = require('mdn-data/css/syntaxes.json');
|
||||
const extendSyntax = /^\s*\|\s*/;
|
||||
|
||||
function preprocessAtrules(dict) {
|
||||
const result = Object.create(null);
|
||||
const result = Object.create(null);
|
||||
|
||||
for (const atruleName in dict) {
|
||||
const atrule = dict[atruleName];
|
||||
let descriptors = null;
|
||||
for (const atruleName in dict) {
|
||||
const atrule = dict[atruleName];
|
||||
let descriptors = null;
|
||||
|
||||
if (atrule.descriptors) {
|
||||
descriptors = Object.create(null);
|
||||
if (atrule.descriptors) {
|
||||
descriptors = Object.create(null);
|
||||
|
||||
for (const descriptor in atrule.descriptors) {
|
||||
descriptors[descriptor] = atrule.descriptors[descriptor].syntax;
|
||||
}
|
||||
}
|
||||
|
||||
result[atruleName.substr(1)] = {
|
||||
prelude: atrule.syntax.trim().replace(/\{(.|\s)+\}/, '').match(/^@\S+\s+([^;\{]*)/)[1].trim() || null,
|
||||
descriptors
|
||||
};
|
||||
for (const descriptor in atrule.descriptors) {
|
||||
descriptors[descriptor] = atrule.descriptors[descriptor].syntax;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
result[atruleName.substr(1)] = {
|
||||
prelude:
|
||||
atrule.syntax
|
||||
.trim()
|
||||
.replace(/\{(.|\s)+\}/, '')
|
||||
.match(/^@\S+\s+([^;\{]*)/)[1]
|
||||
.trim() || null,
|
||||
descriptors,
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function patchDictionary(dict, patchDict) {
|
||||
const result = {};
|
||||
const result = {};
|
||||
|
||||
// copy all syntaxes for an original dict
|
||||
for (const key in dict) {
|
||||
result[key] = dict[key].syntax || dict[key];
|
||||
// copy all syntaxes for an original dict
|
||||
for (const key in dict) {
|
||||
result[key] = dict[key].syntax || dict[key];
|
||||
}
|
||||
|
||||
// apply a patch
|
||||
for (const key in patchDict) {
|
||||
if (key in dict) {
|
||||
if (patchDict[key].syntax) {
|
||||
result[key] =
|
||||
extendSyntax.test(patchDict[key].syntax) ?
|
||||
result[key] + ' ' + patchDict[key].syntax.trim()
|
||||
: patchDict[key].syntax;
|
||||
} else {
|
||||
delete result[key];
|
||||
}
|
||||
} else {
|
||||
if (patchDict[key].syntax) {
|
||||
result[key] = patchDict[key].syntax.replace(extendSyntax, '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// apply a patch
|
||||
for (const key in patchDict) {
|
||||
if (key in dict) {
|
||||
if (patchDict[key].syntax) {
|
||||
result[key] = extendSyntax.test(patchDict[key].syntax)
|
||||
? result[key] + ' ' + patchDict[key].syntax.trim()
|
||||
: patchDict[key].syntax;
|
||||
} else {
|
||||
delete result[key];
|
||||
}
|
||||
} else {
|
||||
if (patchDict[key].syntax) {
|
||||
result[key] = patchDict[key].syntax.replace(extendSyntax, '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function patchAtrules(dict, patchDict) {
|
||||
const result = {};
|
||||
const result = {};
|
||||
|
||||
// copy all syntaxes for an original dict
|
||||
for (const key in dict) {
|
||||
const patchDescriptors = (patchDict[key] && patchDict[key].descriptors) || null;
|
||||
// copy all syntaxes for an original dict
|
||||
for (const key in dict) {
|
||||
const patchDescriptors =
|
||||
(patchDict[key] && patchDict[key].descriptors) || null;
|
||||
|
||||
result[key] = {
|
||||
prelude: key in patchDict && 'prelude' in patchDict[key]
|
||||
? patchDict[key].prelude
|
||||
: dict[key].prelude || null,
|
||||
descriptors: patchDictionary(dict[key].descriptors || {}, patchDescriptors || {})
|
||||
};
|
||||
result[key] = {
|
||||
prelude:
|
||||
key in patchDict && 'prelude' in patchDict[key] ?
|
||||
patchDict[key].prelude
|
||||
: dict[key].prelude || null,
|
||||
descriptors: patchDictionary(
|
||||
dict[key].descriptors || {},
|
||||
patchDescriptors || {}
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
// apply a patch
|
||||
for (const key in patchDict) {
|
||||
if (!hasOwnProperty.call(dict, key)) {
|
||||
result[key] = {
|
||||
prelude: patchDict[key].prelude || null,
|
||||
descriptors:
|
||||
patchDict[key].descriptors &&
|
||||
patchDictionary({}, patchDict[key].descriptors),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// apply a patch
|
||||
for (const key in patchDict) {
|
||||
if (!hasOwnProperty.call(dict, key)) {
|
||||
result[key] = {
|
||||
prelude: patchDict[key].prelude || null,
|
||||
descriptors: patchDict[key].descriptors && patchDictionary({}, patchDict[key].descriptors)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
export default {
|
||||
types: patchDictionary(mdnSyntaxes, patch.types),
|
||||
atrules: patchAtrules(preprocessAtrules(mdnAtrules), patch.atrules),
|
||||
properties: patchDictionary(mdnProperties, patch.properties)
|
||||
types: patchDictionary(mdnSyntaxes, patch.types),
|
||||
atrules: patchAtrules(preprocessAtrules(mdnAtrules), patch.atrules),
|
||||
properties: patchDictionary(mdnProperties, patch.properties),
|
||||
};
|
||||
|
24
node_modules/css-tree/lib/definition-syntax/SyntaxError.js
generated
vendored
24
node_modules/css-tree/lib/definition-syntax/SyntaxError.js
generated
vendored
@ -1,12 +1,18 @@
|
||||
import { createCustomError } from '../utils/create-custom-error.js';
|
||||
|
||||
export function SyntaxError(message, input, offset) {
|
||||
return Object.assign(createCustomError('SyntaxError', message), {
|
||||
input,
|
||||
offset,
|
||||
rawMessage: message,
|
||||
message: message + '\n' +
|
||||
' ' + input + '\n' +
|
||||
'--' + new Array((offset || input.length) + 1).join('-') + '^'
|
||||
});
|
||||
};
|
||||
return Object.assign(createCustomError('SyntaxError', message), {
|
||||
input,
|
||||
offset,
|
||||
rawMessage: message,
|
||||
message:
|
||||
message +
|
||||
'\n' +
|
||||
' ' +
|
||||
input +
|
||||
'\n' +
|
||||
'--' +
|
||||
new Array((offset || input.length) + 1).join('-') +
|
||||
'^',
|
||||
});
|
||||
}
|
||||
|
196
node_modules/css-tree/lib/definition-syntax/generate.js
generated
vendored
196
node_modules/css-tree/lib/definition-syntax/generate.js
generated
vendored
@ -1,131 +1,141 @@
|
||||
function noop(value) {
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
|
||||
function generateMultiplier(multiplier) {
|
||||
const { min, max, comma } = multiplier;
|
||||
const { min, max, comma } = multiplier;
|
||||
|
||||
if (min === 0 && max === 0) {
|
||||
return comma ? '#?' : '*';
|
||||
}
|
||||
if (min === 0 && max === 0) {
|
||||
return comma ? '#?' : '*';
|
||||
}
|
||||
|
||||
if (min === 0 && max === 1) {
|
||||
return '?';
|
||||
}
|
||||
if (min === 0 && max === 1) {
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (min === 1 && max === 0) {
|
||||
return comma ? '#' : '+';
|
||||
}
|
||||
if (min === 1 && max === 0) {
|
||||
return comma ? '#' : '+';
|
||||
}
|
||||
|
||||
if (min === 1 && max === 1) {
|
||||
return '';
|
||||
}
|
||||
if (min === 1 && max === 1) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return (
|
||||
(comma ? '#' : '') +
|
||||
(min === max
|
||||
? '{' + min + '}'
|
||||
: '{' + min + ',' + (max !== 0 ? max : '') + '}'
|
||||
)
|
||||
);
|
||||
return (
|
||||
(comma ? '#' : '') +
|
||||
(min === max ?
|
||||
'{' + min + '}'
|
||||
: '{' + min + ',' + (max !== 0 ? max : '') + '}')
|
||||
);
|
||||
}
|
||||
|
||||
function generateTypeOpts(node) {
|
||||
switch (node.type) {
|
||||
case 'Range':
|
||||
return (
|
||||
' [' +
|
||||
(node.min === null ? '-∞' : node.min) +
|
||||
',' +
|
||||
(node.max === null ? '∞' : node.max) +
|
||||
']'
|
||||
);
|
||||
switch (node.type) {
|
||||
case 'Range':
|
||||
return (
|
||||
' [' +
|
||||
(node.min === null ? '-∞' : node.min) +
|
||||
',' +
|
||||
(node.max === null ? '∞' : node.max) +
|
||||
']'
|
||||
);
|
||||
|
||||
default:
|
||||
throw new Error('Unknown node type `' + node.type + '`');
|
||||
}
|
||||
default:
|
||||
throw new Error('Unknown node type `' + node.type + '`');
|
||||
}
|
||||
}
|
||||
|
||||
function generateSequence(node, decorate, forceBraces, compact) {
|
||||
const combinator = node.combinator === ' ' || compact ? node.combinator : ' ' + node.combinator + ' ';
|
||||
const result = node.terms
|
||||
.map(term => internalGenerate(term, decorate, forceBraces, compact))
|
||||
.join(combinator);
|
||||
const combinator =
|
||||
node.combinator === ' ' || compact ?
|
||||
node.combinator
|
||||
: ' ' + node.combinator + ' ';
|
||||
const result = node.terms
|
||||
.map((term) => internalGenerate(term, decorate, forceBraces, compact))
|
||||
.join(combinator);
|
||||
|
||||
if (node.explicit || forceBraces) {
|
||||
return (compact || result[0] === ',' ? '[' : '[ ') + result + (compact ? ']' : ' ]');
|
||||
}
|
||||
if (node.explicit || forceBraces) {
|
||||
return (
|
||||
(compact || result[0] === ',' ? '[' : '[ ') +
|
||||
result +
|
||||
(compact ? ']' : ' ]')
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function internalGenerate(node, decorate, forceBraces, compact) {
|
||||
let result;
|
||||
let result;
|
||||
|
||||
switch (node.type) {
|
||||
case 'Group':
|
||||
result =
|
||||
generateSequence(node, decorate, forceBraces, compact) +
|
||||
(node.disallowEmpty ? '!' : '');
|
||||
break;
|
||||
switch (node.type) {
|
||||
case 'Group':
|
||||
result =
|
||||
generateSequence(node, decorate, forceBraces, compact) +
|
||||
(node.disallowEmpty ? '!' : '');
|
||||
break;
|
||||
|
||||
case 'Multiplier':
|
||||
// return since node is a composition
|
||||
return (
|
||||
internalGenerate(node.term, decorate, forceBraces, compact) +
|
||||
decorate(generateMultiplier(node), node)
|
||||
);
|
||||
case 'Multiplier':
|
||||
// return since node is a composition
|
||||
return (
|
||||
internalGenerate(node.term, decorate, forceBraces, compact) +
|
||||
decorate(generateMultiplier(node), node)
|
||||
);
|
||||
|
||||
case 'Type':
|
||||
result = '<' + node.name + (node.opts ? decorate(generateTypeOpts(node.opts), node.opts) : '') + '>';
|
||||
break;
|
||||
case 'Type':
|
||||
result =
|
||||
'<' +
|
||||
node.name +
|
||||
(node.opts ? decorate(generateTypeOpts(node.opts), node.opts) : '') +
|
||||
'>';
|
||||
break;
|
||||
|
||||
case 'Property':
|
||||
result = '<\'' + node.name + '\'>';
|
||||
break;
|
||||
case 'Property':
|
||||
result = "<'" + node.name + "'>";
|
||||
break;
|
||||
|
||||
case 'Keyword':
|
||||
result = node.name;
|
||||
break;
|
||||
case 'Keyword':
|
||||
result = node.name;
|
||||
break;
|
||||
|
||||
case 'AtKeyword':
|
||||
result = '@' + node.name;
|
||||
break;
|
||||
case 'AtKeyword':
|
||||
result = '@' + node.name;
|
||||
break;
|
||||
|
||||
case 'Function':
|
||||
result = node.name + '(';
|
||||
break;
|
||||
case 'Function':
|
||||
result = node.name + '(';
|
||||
break;
|
||||
|
||||
case 'String':
|
||||
case 'Token':
|
||||
result = node.value;
|
||||
break;
|
||||
case 'String':
|
||||
case 'Token':
|
||||
result = node.value;
|
||||
break;
|
||||
|
||||
case 'Comma':
|
||||
result = ',';
|
||||
break;
|
||||
case 'Comma':
|
||||
result = ',';
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error('Unknown node type `' + node.type + '`');
|
||||
}
|
||||
default:
|
||||
throw new Error('Unknown node type `' + node.type + '`');
|
||||
}
|
||||
|
||||
return decorate(result, node);
|
||||
return decorate(result, node);
|
||||
}
|
||||
|
||||
export function generate(node, options) {
|
||||
let decorate = noop;
|
||||
let forceBraces = false;
|
||||
let compact = false;
|
||||
let decorate = noop;
|
||||
let forceBraces = false;
|
||||
let compact = false;
|
||||
|
||||
if (typeof options === 'function') {
|
||||
decorate = options;
|
||||
} else if (options) {
|
||||
forceBraces = Boolean(options.forceBraces);
|
||||
compact = Boolean(options.compact);
|
||||
if (typeof options.decorate === 'function') {
|
||||
decorate = options.decorate;
|
||||
}
|
||||
if (typeof options === 'function') {
|
||||
decorate = options;
|
||||
} else if (options) {
|
||||
forceBraces = Boolean(options.forceBraces);
|
||||
compact = Boolean(options.compact);
|
||||
if (typeof options.decorate === 'function') {
|
||||
decorate = options.decorate;
|
||||
}
|
||||
}
|
||||
|
||||
return internalGenerate(node, decorate, forceBraces, compact);
|
||||
};
|
||||
return internalGenerate(node, decorate, forceBraces, compact);
|
||||
}
|
||||
|
836
node_modules/css-tree/lib/definition-syntax/parse.js
generated
vendored
836
node_modules/css-tree/lib/definition-syntax/parse.js
generated
vendored
@ -5,244 +5,244 @@ const N = 10;
|
||||
const F = 12;
|
||||
const R = 13;
|
||||
const SPACE = 32;
|
||||
const EXCLAMATIONMARK = 33; // !
|
||||
const NUMBERSIGN = 35; // #
|
||||
const AMPERSAND = 38; // &
|
||||
const APOSTROPHE = 39; // '
|
||||
const LEFTPARENTHESIS = 40; // (
|
||||
const RIGHTPARENTHESIS = 41; // )
|
||||
const ASTERISK = 42; // *
|
||||
const PLUSSIGN = 43; // +
|
||||
const COMMA = 44; // ,
|
||||
const HYPERMINUS = 45; // -
|
||||
const LESSTHANSIGN = 60; // <
|
||||
const GREATERTHANSIGN = 62; // >
|
||||
const QUESTIONMARK = 63; // ?
|
||||
const COMMERCIALAT = 64; // @
|
||||
const LEFTSQUAREBRACKET = 91; // [
|
||||
const EXCLAMATIONMARK = 33; // !
|
||||
const NUMBERSIGN = 35; // #
|
||||
const AMPERSAND = 38; // &
|
||||
const APOSTROPHE = 39; // '
|
||||
const LEFTPARENTHESIS = 40; // (
|
||||
const RIGHTPARENTHESIS = 41; // )
|
||||
const ASTERISK = 42; // *
|
||||
const PLUSSIGN = 43; // +
|
||||
const COMMA = 44; // ,
|
||||
const HYPERMINUS = 45; // -
|
||||
const LESSTHANSIGN = 60; // <
|
||||
const GREATERTHANSIGN = 62; // >
|
||||
const QUESTIONMARK = 63; // ?
|
||||
const COMMERCIALAT = 64; // @
|
||||
const LEFTSQUAREBRACKET = 91; // [
|
||||
const RIGHTSQUAREBRACKET = 93; // ]
|
||||
const LEFTCURLYBRACKET = 123; // {
|
||||
const VERTICALLINE = 124; // |
|
||||
const LEFTCURLYBRACKET = 123; // {
|
||||
const VERTICALLINE = 124; // |
|
||||
const RIGHTCURLYBRACKET = 125; // }
|
||||
const INFINITY = 8734; // ∞
|
||||
const INFINITY = 8734; // ∞
|
||||
const NAME_CHAR = new Uint8Array(128).map((_, idx) =>
|
||||
/[a-zA-Z0-9\-]/.test(String.fromCharCode(idx)) ? 1 : 0
|
||||
/[a-zA-Z0-9\-]/.test(String.fromCharCode(idx)) ? 1 : 0
|
||||
);
|
||||
const COMBINATOR_PRECEDENCE = {
|
||||
' ': 1,
|
||||
'&&': 2,
|
||||
'||': 3,
|
||||
'|': 4
|
||||
' ': 1,
|
||||
'&&': 2,
|
||||
'||': 3,
|
||||
'|': 4,
|
||||
};
|
||||
|
||||
function scanSpaces(tokenizer) {
|
||||
return tokenizer.substringToPos(
|
||||
tokenizer.findWsEnd(tokenizer.pos)
|
||||
);
|
||||
return tokenizer.substringToPos(tokenizer.findWsEnd(tokenizer.pos));
|
||||
}
|
||||
|
||||
function scanWord(tokenizer) {
|
||||
let end = tokenizer.pos;
|
||||
let end = tokenizer.pos;
|
||||
|
||||
for (; end < tokenizer.str.length; end++) {
|
||||
const code = tokenizer.str.charCodeAt(end);
|
||||
if (code >= 128 || NAME_CHAR[code] === 0) {
|
||||
break;
|
||||
}
|
||||
for (; end < tokenizer.str.length; end++) {
|
||||
const code = tokenizer.str.charCodeAt(end);
|
||||
if (code >= 128 || NAME_CHAR[code] === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tokenizer.pos === end) {
|
||||
tokenizer.error('Expect a keyword');
|
||||
}
|
||||
if (tokenizer.pos === end) {
|
||||
tokenizer.error('Expect a keyword');
|
||||
}
|
||||
|
||||
return tokenizer.substringToPos(end);
|
||||
return tokenizer.substringToPos(end);
|
||||
}
|
||||
|
||||
function scanNumber(tokenizer) {
|
||||
let end = tokenizer.pos;
|
||||
let end = tokenizer.pos;
|
||||
|
||||
for (; end < tokenizer.str.length; end++) {
|
||||
const code = tokenizer.str.charCodeAt(end);
|
||||
if (code < 48 || code > 57) {
|
||||
break;
|
||||
}
|
||||
for (; end < tokenizer.str.length; end++) {
|
||||
const code = tokenizer.str.charCodeAt(end);
|
||||
if (code < 48 || code > 57) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tokenizer.pos === end) {
|
||||
tokenizer.error('Expect a number');
|
||||
}
|
||||
if (tokenizer.pos === end) {
|
||||
tokenizer.error('Expect a number');
|
||||
}
|
||||
|
||||
return tokenizer.substringToPos(end);
|
||||
return tokenizer.substringToPos(end);
|
||||
}
|
||||
|
||||
function scanString(tokenizer) {
|
||||
const end = tokenizer.str.indexOf('\'', tokenizer.pos + 1);
|
||||
const end = tokenizer.str.indexOf("'", tokenizer.pos + 1);
|
||||
|
||||
if (end === -1) {
|
||||
tokenizer.pos = tokenizer.str.length;
|
||||
tokenizer.error('Expect an apostrophe');
|
||||
}
|
||||
if (end === -1) {
|
||||
tokenizer.pos = tokenizer.str.length;
|
||||
tokenizer.error('Expect an apostrophe');
|
||||
}
|
||||
|
||||
return tokenizer.substringToPos(end + 1);
|
||||
return tokenizer.substringToPos(end + 1);
|
||||
}
|
||||
|
||||
function readMultiplierRange(tokenizer) {
|
||||
let min = null;
|
||||
let max = null;
|
||||
let min = null;
|
||||
let max = null;
|
||||
|
||||
tokenizer.eat(LEFTCURLYBRACKET);
|
||||
tokenizer.eat(LEFTCURLYBRACKET);
|
||||
|
||||
min = scanNumber(tokenizer);
|
||||
min = scanNumber(tokenizer);
|
||||
|
||||
if (tokenizer.charCode() === COMMA) {
|
||||
tokenizer.pos++;
|
||||
if (tokenizer.charCode() !== RIGHTCURLYBRACKET) {
|
||||
max = scanNumber(tokenizer);
|
||||
}
|
||||
} else {
|
||||
max = min;
|
||||
if (tokenizer.charCode() === COMMA) {
|
||||
tokenizer.pos++;
|
||||
if (tokenizer.charCode() !== RIGHTCURLYBRACKET) {
|
||||
max = scanNumber(tokenizer);
|
||||
}
|
||||
} else {
|
||||
max = min;
|
||||
}
|
||||
|
||||
tokenizer.eat(RIGHTCURLYBRACKET);
|
||||
tokenizer.eat(RIGHTCURLYBRACKET);
|
||||
|
||||
return {
|
||||
min: Number(min),
|
||||
max: max ? Number(max) : 0
|
||||
};
|
||||
return {
|
||||
min: Number(min),
|
||||
max: max ? Number(max) : 0,
|
||||
};
|
||||
}
|
||||
|
||||
function readMultiplier(tokenizer) {
|
||||
let range = null;
|
||||
let comma = false;
|
||||
let range = null;
|
||||
let comma = false;
|
||||
|
||||
switch (tokenizer.charCode()) {
|
||||
case ASTERISK:
|
||||
tokenizer.pos++;
|
||||
switch (tokenizer.charCode()) {
|
||||
case ASTERISK:
|
||||
tokenizer.pos++;
|
||||
|
||||
range = {
|
||||
min: 0,
|
||||
max: 0
|
||||
};
|
||||
range = {
|
||||
min: 0,
|
||||
max: 0,
|
||||
};
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case PLUSSIGN:
|
||||
tokenizer.pos++;
|
||||
case PLUSSIGN:
|
||||
tokenizer.pos++;
|
||||
|
||||
range = {
|
||||
min: 1,
|
||||
max: 0
|
||||
};
|
||||
range = {
|
||||
min: 1,
|
||||
max: 0,
|
||||
};
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case QUESTIONMARK:
|
||||
tokenizer.pos++;
|
||||
case QUESTIONMARK:
|
||||
tokenizer.pos++;
|
||||
|
||||
range = {
|
||||
min: 0,
|
||||
max: 1
|
||||
};
|
||||
range = {
|
||||
min: 0,
|
||||
max: 1,
|
||||
};
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case NUMBERSIGN:
|
||||
tokenizer.pos++;
|
||||
case NUMBERSIGN:
|
||||
tokenizer.pos++;
|
||||
|
||||
comma = true;
|
||||
comma = true;
|
||||
|
||||
if (tokenizer.charCode() === LEFTCURLYBRACKET) {
|
||||
range = readMultiplierRange(tokenizer);
|
||||
} else if (tokenizer.charCode() === QUESTIONMARK) {
|
||||
// https://www.w3.org/TR/css-values-4/#component-multipliers
|
||||
// > the # and ? multipliers may be stacked as #?
|
||||
// In this case just treat "#?" as a single multiplier
|
||||
// { min: 0, max: 0, comma: true }
|
||||
tokenizer.pos++;
|
||||
range = {
|
||||
min: 0,
|
||||
max: 0
|
||||
};
|
||||
} else {
|
||||
range = {
|
||||
min: 1,
|
||||
max: 0
|
||||
};
|
||||
}
|
||||
if (tokenizer.charCode() === LEFTCURLYBRACKET) {
|
||||
range = readMultiplierRange(tokenizer);
|
||||
} else if (tokenizer.charCode() === QUESTIONMARK) {
|
||||
// https://www.w3.org/TR/css-values-4/#component-multipliers
|
||||
// > the # and ? multipliers may be stacked as #?
|
||||
// In this case just treat "#?" as a single multiplier
|
||||
// { min: 0, max: 0, comma: true }
|
||||
tokenizer.pos++;
|
||||
range = {
|
||||
min: 0,
|
||||
max: 0,
|
||||
};
|
||||
} else {
|
||||
range = {
|
||||
min: 1,
|
||||
max: 0,
|
||||
};
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case LEFTCURLYBRACKET:
|
||||
range = readMultiplierRange(tokenizer);
|
||||
break;
|
||||
case LEFTCURLYBRACKET:
|
||||
range = readMultiplierRange(tokenizer);
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Multiplier',
|
||||
comma,
|
||||
min: range.min,
|
||||
max: range.max,
|
||||
term: null
|
||||
};
|
||||
return {
|
||||
type: 'Multiplier',
|
||||
comma,
|
||||
min: range.min,
|
||||
max: range.max,
|
||||
term: null,
|
||||
};
|
||||
}
|
||||
|
||||
function maybeMultiplied(tokenizer, node) {
|
||||
const multiplier = readMultiplier(tokenizer);
|
||||
const multiplier = readMultiplier(tokenizer);
|
||||
|
||||
if (multiplier !== null) {
|
||||
multiplier.term = node;
|
||||
if (multiplier !== null) {
|
||||
multiplier.term = node;
|
||||
|
||||
// https://www.w3.org/TR/css-values-4/#component-multipliers
|
||||
// > The + and # multipliers may be stacked as +#;
|
||||
// Represent "+#" as nested multipliers:
|
||||
// { ...<multiplier #>,
|
||||
// term: {
|
||||
// ...<multipler +>,
|
||||
// term: node
|
||||
// }
|
||||
// }
|
||||
if (tokenizer.charCode() === NUMBERSIGN &&
|
||||
tokenizer.charCodeAt(tokenizer.pos - 1) === PLUSSIGN) {
|
||||
return maybeMultiplied(tokenizer, multiplier);
|
||||
}
|
||||
|
||||
return multiplier;
|
||||
// https://www.w3.org/TR/css-values-4/#component-multipliers
|
||||
// > The + and # multipliers may be stacked as +#;
|
||||
// Represent "+#" as nested multipliers:
|
||||
// { ...<multiplier #>,
|
||||
// term: {
|
||||
// ...<multipler +>,
|
||||
// term: node
|
||||
// }
|
||||
// }
|
||||
if (
|
||||
tokenizer.charCode() === NUMBERSIGN &&
|
||||
tokenizer.charCodeAt(tokenizer.pos - 1) === PLUSSIGN
|
||||
) {
|
||||
return maybeMultiplied(tokenizer, multiplier);
|
||||
}
|
||||
|
||||
return node;
|
||||
return multiplier;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function maybeToken(tokenizer) {
|
||||
const ch = tokenizer.peek();
|
||||
const ch = tokenizer.peek();
|
||||
|
||||
if (ch === '') {
|
||||
return null;
|
||||
}
|
||||
if (ch === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Token',
|
||||
value: ch
|
||||
};
|
||||
return {
|
||||
type: 'Token',
|
||||
value: ch,
|
||||
};
|
||||
}
|
||||
|
||||
function readProperty(tokenizer) {
|
||||
let name;
|
||||
let name;
|
||||
|
||||
tokenizer.eat(LESSTHANSIGN);
|
||||
tokenizer.eat(APOSTROPHE);
|
||||
tokenizer.eat(LESSTHANSIGN);
|
||||
tokenizer.eat(APOSTROPHE);
|
||||
|
||||
name = scanWord(tokenizer);
|
||||
name = scanWord(tokenizer);
|
||||
|
||||
tokenizer.eat(APOSTROPHE);
|
||||
tokenizer.eat(GREATERTHANSIGN);
|
||||
tokenizer.eat(APOSTROPHE);
|
||||
tokenizer.eat(GREATERTHANSIGN);
|
||||
|
||||
return maybeMultiplied(tokenizer, {
|
||||
type: 'Property',
|
||||
name
|
||||
});
|
||||
return maybeMultiplied(tokenizer, {
|
||||
type: 'Property',
|
||||
name,
|
||||
});
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-values-3/#numeric-ranges
|
||||
@ -253,332 +253,338 @@ function readProperty(tokenizer) {
|
||||
// indicating a closed range between (and including) min and max.
|
||||
// For example, <integer [0, 10]> indicates an integer between 0 and 10, inclusive.
|
||||
function readTypeRange(tokenizer) {
|
||||
// use null for Infinity to make AST format JSON serializable/deserializable
|
||||
let min = null; // -Infinity
|
||||
let max = null; // Infinity
|
||||
let sign = 1;
|
||||
// use null for Infinity to make AST format JSON serializable/deserializable
|
||||
let min = null; // -Infinity
|
||||
let max = null; // Infinity
|
||||
let sign = 1;
|
||||
|
||||
tokenizer.eat(LEFTSQUAREBRACKET);
|
||||
tokenizer.eat(LEFTSQUAREBRACKET);
|
||||
|
||||
if (tokenizer.charCode() === HYPERMINUS) {
|
||||
tokenizer.peek();
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
if (sign == -1 && tokenizer.charCode() === INFINITY) {
|
||||
tokenizer.peek();
|
||||
} else {
|
||||
min = sign * Number(scanNumber(tokenizer));
|
||||
|
||||
if (NAME_CHAR[tokenizer.charCode()] !== 0) {
|
||||
min += scanWord(tokenizer);
|
||||
}
|
||||
}
|
||||
|
||||
scanSpaces(tokenizer);
|
||||
tokenizer.eat(COMMA);
|
||||
scanSpaces(tokenizer);
|
||||
|
||||
if (tokenizer.charCode() === INFINITY) {
|
||||
tokenizer.peek();
|
||||
} else {
|
||||
sign = 1;
|
||||
|
||||
if (tokenizer.charCode() === HYPERMINUS) {
|
||||
tokenizer.peek();
|
||||
sign = -1;
|
||||
tokenizer.peek();
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
if (sign == -1 && tokenizer.charCode() === INFINITY) {
|
||||
tokenizer.peek();
|
||||
} else {
|
||||
min = sign * Number(scanNumber(tokenizer));
|
||||
max = sign * Number(scanNumber(tokenizer));
|
||||
|
||||
if (NAME_CHAR[tokenizer.charCode()] !== 0) {
|
||||
min += scanWord(tokenizer);
|
||||
}
|
||||
if (NAME_CHAR[tokenizer.charCode()] !== 0) {
|
||||
max += scanWord(tokenizer);
|
||||
}
|
||||
}
|
||||
|
||||
scanSpaces(tokenizer);
|
||||
tokenizer.eat(COMMA);
|
||||
scanSpaces(tokenizer);
|
||||
tokenizer.eat(RIGHTSQUAREBRACKET);
|
||||
|
||||
if (tokenizer.charCode() === INFINITY) {
|
||||
tokenizer.peek();
|
||||
} else {
|
||||
sign = 1;
|
||||
|
||||
if (tokenizer.charCode() === HYPERMINUS) {
|
||||
tokenizer.peek();
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
max = sign * Number(scanNumber(tokenizer));
|
||||
|
||||
if (NAME_CHAR[tokenizer.charCode()] !== 0) {
|
||||
max += scanWord(tokenizer);
|
||||
}
|
||||
}
|
||||
|
||||
tokenizer.eat(RIGHTSQUAREBRACKET);
|
||||
|
||||
return {
|
||||
type: 'Range',
|
||||
min,
|
||||
max
|
||||
};
|
||||
return {
|
||||
type: 'Range',
|
||||
min,
|
||||
max,
|
||||
};
|
||||
}
|
||||
|
||||
function readType(tokenizer) {
|
||||
let name;
|
||||
let opts = null;
|
||||
let name;
|
||||
let opts = null;
|
||||
|
||||
tokenizer.eat(LESSTHANSIGN);
|
||||
name = scanWord(tokenizer);
|
||||
tokenizer.eat(LESSTHANSIGN);
|
||||
name = scanWord(tokenizer);
|
||||
|
||||
if (tokenizer.charCode() === LEFTPARENTHESIS &&
|
||||
tokenizer.nextCharCode() === RIGHTPARENTHESIS) {
|
||||
tokenizer.pos += 2;
|
||||
name += '()';
|
||||
}
|
||||
if (
|
||||
tokenizer.charCode() === LEFTPARENTHESIS &&
|
||||
tokenizer.nextCharCode() === RIGHTPARENTHESIS
|
||||
) {
|
||||
tokenizer.pos += 2;
|
||||
name += '()';
|
||||
}
|
||||
|
||||
if (tokenizer.charCodeAt(tokenizer.findWsEnd(tokenizer.pos)) === LEFTSQUAREBRACKET) {
|
||||
scanSpaces(tokenizer);
|
||||
opts = readTypeRange(tokenizer);
|
||||
}
|
||||
if (
|
||||
tokenizer.charCodeAt(tokenizer.findWsEnd(tokenizer.pos)) ===
|
||||
LEFTSQUAREBRACKET
|
||||
) {
|
||||
scanSpaces(tokenizer);
|
||||
opts = readTypeRange(tokenizer);
|
||||
}
|
||||
|
||||
tokenizer.eat(GREATERTHANSIGN);
|
||||
tokenizer.eat(GREATERTHANSIGN);
|
||||
|
||||
return maybeMultiplied(tokenizer, {
|
||||
type: 'Type',
|
||||
name,
|
||||
opts
|
||||
});
|
||||
return maybeMultiplied(tokenizer, {
|
||||
type: 'Type',
|
||||
name,
|
||||
opts,
|
||||
});
|
||||
}
|
||||
|
||||
function readKeywordOrFunction(tokenizer) {
|
||||
const name = scanWord(tokenizer);
|
||||
const name = scanWord(tokenizer);
|
||||
|
||||
if (tokenizer.charCode() === LEFTPARENTHESIS) {
|
||||
tokenizer.pos++;
|
||||
if (tokenizer.charCode() === LEFTPARENTHESIS) {
|
||||
tokenizer.pos++;
|
||||
|
||||
return {
|
||||
type: 'Function',
|
||||
name
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: 'Function',
|
||||
name,
|
||||
};
|
||||
}
|
||||
|
||||
return maybeMultiplied(tokenizer, {
|
||||
type: 'Keyword',
|
||||
name
|
||||
});
|
||||
return maybeMultiplied(tokenizer, {
|
||||
type: 'Keyword',
|
||||
name,
|
||||
});
|
||||
}
|
||||
|
||||
function regroupTerms(terms, combinators) {
|
||||
function createGroup(terms, combinator) {
|
||||
return {
|
||||
type: 'Group',
|
||||
terms,
|
||||
combinator,
|
||||
disallowEmpty: false,
|
||||
explicit: false
|
||||
};
|
||||
}
|
||||
function createGroup(terms, combinator) {
|
||||
return {
|
||||
type: 'Group',
|
||||
terms,
|
||||
combinator,
|
||||
disallowEmpty: false,
|
||||
explicit: false,
|
||||
};
|
||||
}
|
||||
|
||||
let combinator;
|
||||
let combinator;
|
||||
|
||||
combinators = Object.keys(combinators)
|
||||
.sort((a, b) => COMBINATOR_PRECEDENCE[a] - COMBINATOR_PRECEDENCE[b]);
|
||||
combinators = Object.keys(combinators).sort(
|
||||
(a, b) => COMBINATOR_PRECEDENCE[a] - COMBINATOR_PRECEDENCE[b]
|
||||
);
|
||||
|
||||
while (combinators.length > 0) {
|
||||
combinator = combinators.shift();
|
||||
while (combinators.length > 0) {
|
||||
combinator = combinators.shift();
|
||||
|
||||
let i = 0;
|
||||
let subgroupStart = 0;
|
||||
let i = 0;
|
||||
let subgroupStart = 0;
|
||||
|
||||
for (; i < terms.length; i++) {
|
||||
const term = terms[i];
|
||||
for (; i < terms.length; i++) {
|
||||
const term = terms[i];
|
||||
|
||||
if (term.type === 'Combinator') {
|
||||
if (term.value === combinator) {
|
||||
if (subgroupStart === -1) {
|
||||
subgroupStart = i - 1;
|
||||
}
|
||||
terms.splice(i, 1);
|
||||
i--;
|
||||
} else {
|
||||
if (subgroupStart !== -1 && i - subgroupStart > 1) {
|
||||
terms.splice(
|
||||
subgroupStart,
|
||||
i - subgroupStart,
|
||||
createGroup(terms.slice(subgroupStart, i), combinator)
|
||||
);
|
||||
i = subgroupStart + 1;
|
||||
}
|
||||
subgroupStart = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (subgroupStart !== -1 && combinators.length) {
|
||||
if (term.type === 'Combinator') {
|
||||
if (term.value === combinator) {
|
||||
if (subgroupStart === -1) {
|
||||
subgroupStart = i - 1;
|
||||
}
|
||||
terms.splice(i, 1);
|
||||
i--;
|
||||
} else {
|
||||
if (subgroupStart !== -1 && i - subgroupStart > 1) {
|
||||
terms.splice(
|
||||
subgroupStart,
|
||||
i - subgroupStart,
|
||||
createGroup(terms.slice(subgroupStart, i), combinator)
|
||||
subgroupStart,
|
||||
i - subgroupStart,
|
||||
createGroup(terms.slice(subgroupStart, i), combinator)
|
||||
);
|
||||
i = subgroupStart + 1;
|
||||
}
|
||||
subgroupStart = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return combinator;
|
||||
if (subgroupStart !== -1 && combinators.length) {
|
||||
terms.splice(
|
||||
subgroupStart,
|
||||
i - subgroupStart,
|
||||
createGroup(terms.slice(subgroupStart, i), combinator)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return combinator;
|
||||
}
|
||||
|
||||
function readImplicitGroup(tokenizer) {
|
||||
const terms = [];
|
||||
const combinators = {};
|
||||
let token;
|
||||
let prevToken = null;
|
||||
let prevTokenPos = tokenizer.pos;
|
||||
const terms = [];
|
||||
const combinators = {};
|
||||
let token;
|
||||
let prevToken = null;
|
||||
let prevTokenPos = tokenizer.pos;
|
||||
|
||||
while (token = peek(tokenizer)) {
|
||||
if (token.type !== 'Spaces') {
|
||||
if (token.type === 'Combinator') {
|
||||
// check for combinator in group beginning and double combinator sequence
|
||||
if (prevToken === null || prevToken.type === 'Combinator') {
|
||||
tokenizer.pos = prevTokenPos;
|
||||
tokenizer.error('Unexpected combinator');
|
||||
}
|
||||
|
||||
combinators[token.value] = true;
|
||||
} else if (prevToken !== null && prevToken.type !== 'Combinator') {
|
||||
combinators[' '] = true; // a b
|
||||
terms.push({
|
||||
type: 'Combinator',
|
||||
value: ' '
|
||||
});
|
||||
}
|
||||
|
||||
terms.push(token);
|
||||
prevToken = token;
|
||||
prevTokenPos = tokenizer.pos;
|
||||
while ((token = peek(tokenizer))) {
|
||||
if (token.type !== 'Spaces') {
|
||||
if (token.type === 'Combinator') {
|
||||
// check for combinator in group beginning and double combinator sequence
|
||||
if (prevToken === null || prevToken.type === 'Combinator') {
|
||||
tokenizer.pos = prevTokenPos;
|
||||
tokenizer.error('Unexpected combinator');
|
||||
}
|
||||
}
|
||||
|
||||
// check for combinator in group ending
|
||||
if (prevToken !== null && prevToken.type === 'Combinator') {
|
||||
tokenizer.pos -= prevTokenPos;
|
||||
tokenizer.error('Unexpected combinator');
|
||||
}
|
||||
combinators[token.value] = true;
|
||||
} else if (prevToken !== null && prevToken.type !== 'Combinator') {
|
||||
combinators[' '] = true; // a b
|
||||
terms.push({
|
||||
type: 'Combinator',
|
||||
value: ' ',
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Group',
|
||||
terms,
|
||||
combinator: regroupTerms(terms, combinators) || ' ',
|
||||
disallowEmpty: false,
|
||||
explicit: false
|
||||
};
|
||||
terms.push(token);
|
||||
prevToken = token;
|
||||
prevTokenPos = tokenizer.pos;
|
||||
}
|
||||
}
|
||||
|
||||
// check for combinator in group ending
|
||||
if (prevToken !== null && prevToken.type === 'Combinator') {
|
||||
tokenizer.pos -= prevTokenPos;
|
||||
tokenizer.error('Unexpected combinator');
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Group',
|
||||
terms,
|
||||
combinator: regroupTerms(terms, combinators) || ' ',
|
||||
disallowEmpty: false,
|
||||
explicit: false,
|
||||
};
|
||||
}
|
||||
|
||||
function readGroup(tokenizer) {
|
||||
let result;
|
||||
let result;
|
||||
|
||||
tokenizer.eat(LEFTSQUAREBRACKET);
|
||||
result = readImplicitGroup(tokenizer);
|
||||
tokenizer.eat(RIGHTSQUAREBRACKET);
|
||||
tokenizer.eat(LEFTSQUAREBRACKET);
|
||||
result = readImplicitGroup(tokenizer);
|
||||
tokenizer.eat(RIGHTSQUAREBRACKET);
|
||||
|
||||
result.explicit = true;
|
||||
result.explicit = true;
|
||||
|
||||
if (tokenizer.charCode() === EXCLAMATIONMARK) {
|
||||
tokenizer.pos++;
|
||||
result.disallowEmpty = true;
|
||||
}
|
||||
if (tokenizer.charCode() === EXCLAMATIONMARK) {
|
||||
tokenizer.pos++;
|
||||
result.disallowEmpty = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function peek(tokenizer) {
|
||||
let code = tokenizer.charCode();
|
||||
let code = tokenizer.charCode();
|
||||
|
||||
if (code < 128 && NAME_CHAR[code] === 1) {
|
||||
return readKeywordOrFunction(tokenizer);
|
||||
}
|
||||
if (code < 128 && NAME_CHAR[code] === 1) {
|
||||
return readKeywordOrFunction(tokenizer);
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
case RIGHTSQUAREBRACKET:
|
||||
// don't eat, stop scan a group
|
||||
break;
|
||||
switch (code) {
|
||||
case RIGHTSQUAREBRACKET:
|
||||
// don't eat, stop scan a group
|
||||
break;
|
||||
|
||||
case LEFTSQUAREBRACKET:
|
||||
return maybeMultiplied(tokenizer, readGroup(tokenizer));
|
||||
case LEFTSQUAREBRACKET:
|
||||
return maybeMultiplied(tokenizer, readGroup(tokenizer));
|
||||
|
||||
case LESSTHANSIGN:
|
||||
return tokenizer.nextCharCode() === APOSTROPHE
|
||||
? readProperty(tokenizer)
|
||||
: readType(tokenizer);
|
||||
case LESSTHANSIGN:
|
||||
return tokenizer.nextCharCode() === APOSTROPHE ?
|
||||
readProperty(tokenizer)
|
||||
: readType(tokenizer);
|
||||
|
||||
case VERTICALLINE:
|
||||
return {
|
||||
type: 'Combinator',
|
||||
value: tokenizer.substringToPos(
|
||||
tokenizer.pos + (tokenizer.nextCharCode() === VERTICALLINE ? 2 : 1)
|
||||
)
|
||||
};
|
||||
case VERTICALLINE:
|
||||
return {
|
||||
type: 'Combinator',
|
||||
value: tokenizer.substringToPos(
|
||||
tokenizer.pos + (tokenizer.nextCharCode() === VERTICALLINE ? 2 : 1)
|
||||
),
|
||||
};
|
||||
|
||||
case AMPERSAND:
|
||||
tokenizer.pos++;
|
||||
tokenizer.eat(AMPERSAND);
|
||||
case AMPERSAND:
|
||||
tokenizer.pos++;
|
||||
tokenizer.eat(AMPERSAND);
|
||||
|
||||
return {
|
||||
type: 'Combinator',
|
||||
value: '&&'
|
||||
};
|
||||
return {
|
||||
type: 'Combinator',
|
||||
value: '&&',
|
||||
};
|
||||
|
||||
case COMMA:
|
||||
tokenizer.pos++;
|
||||
return {
|
||||
type: 'Comma'
|
||||
};
|
||||
case COMMA:
|
||||
tokenizer.pos++;
|
||||
return {
|
||||
type: 'Comma',
|
||||
};
|
||||
|
||||
case APOSTROPHE:
|
||||
return maybeMultiplied(tokenizer, {
|
||||
type: 'String',
|
||||
value: scanString(tokenizer)
|
||||
});
|
||||
case APOSTROPHE:
|
||||
return maybeMultiplied(tokenizer, {
|
||||
type: 'String',
|
||||
value: scanString(tokenizer),
|
||||
});
|
||||
|
||||
case SPACE:
|
||||
case TAB:
|
||||
case N:
|
||||
case R:
|
||||
case F:
|
||||
return {
|
||||
type: 'Spaces',
|
||||
value: scanSpaces(tokenizer)
|
||||
};
|
||||
case SPACE:
|
||||
case TAB:
|
||||
case N:
|
||||
case R:
|
||||
case F:
|
||||
return {
|
||||
type: 'Spaces',
|
||||
value: scanSpaces(tokenizer),
|
||||
};
|
||||
|
||||
case COMMERCIALAT:
|
||||
code = tokenizer.nextCharCode();
|
||||
case COMMERCIALAT:
|
||||
code = tokenizer.nextCharCode();
|
||||
|
||||
if (code < 128 && NAME_CHAR[code] === 1) {
|
||||
tokenizer.pos++;
|
||||
return {
|
||||
type: 'AtKeyword',
|
||||
name: scanWord(tokenizer)
|
||||
};
|
||||
}
|
||||
if (code < 128 && NAME_CHAR[code] === 1) {
|
||||
tokenizer.pos++;
|
||||
return {
|
||||
type: 'AtKeyword',
|
||||
name: scanWord(tokenizer),
|
||||
};
|
||||
}
|
||||
|
||||
return maybeToken(tokenizer);
|
||||
return maybeToken(tokenizer);
|
||||
|
||||
case ASTERISK:
|
||||
case PLUSSIGN:
|
||||
case QUESTIONMARK:
|
||||
case NUMBERSIGN:
|
||||
case EXCLAMATIONMARK:
|
||||
// prohibited tokens (used as a multiplier start)
|
||||
break;
|
||||
case ASTERISK:
|
||||
case PLUSSIGN:
|
||||
case QUESTIONMARK:
|
||||
case NUMBERSIGN:
|
||||
case EXCLAMATIONMARK:
|
||||
// prohibited tokens (used as a multiplier start)
|
||||
break;
|
||||
|
||||
case LEFTCURLYBRACKET:
|
||||
// LEFTCURLYBRACKET is allowed since mdn/data uses it w/o quoting
|
||||
// check next char isn't a number, because it's likely a disjoined multiplier
|
||||
code = tokenizer.nextCharCode();
|
||||
case LEFTCURLYBRACKET:
|
||||
// LEFTCURLYBRACKET is allowed since mdn/data uses it w/o quoting
|
||||
// check next char isn't a number, because it's likely a disjoined multiplier
|
||||
code = tokenizer.nextCharCode();
|
||||
|
||||
if (code < 48 || code > 57) {
|
||||
return maybeToken(tokenizer);
|
||||
}
|
||||
if (code < 48 || code > 57) {
|
||||
return maybeToken(tokenizer);
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
return maybeToken(tokenizer);
|
||||
}
|
||||
default:
|
||||
return maybeToken(tokenizer);
|
||||
}
|
||||
}
|
||||
|
||||
export function parse(source) {
|
||||
const tokenizer = new Tokenizer(source);
|
||||
const result = readImplicitGroup(tokenizer);
|
||||
const tokenizer = new Tokenizer(source);
|
||||
const result = readImplicitGroup(tokenizer);
|
||||
|
||||
if (tokenizer.pos !== source.length) {
|
||||
tokenizer.error('Unexpected input');
|
||||
}
|
||||
if (tokenizer.pos !== source.length) {
|
||||
tokenizer.error('Unexpected input');
|
||||
}
|
||||
|
||||
// reduce redundant groups with single group term
|
||||
if (result.terms.length === 1 && result.terms[0].type === 'Group') {
|
||||
return result.terms[0];
|
||||
}
|
||||
// reduce redundant groups with single group term
|
||||
if (result.terms.length === 1 && result.terms[0].type === 'Group') {
|
||||
return result.terms[0];
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
84
node_modules/css-tree/lib/definition-syntax/tokenizer.js
generated
vendored
84
node_modules/css-tree/lib/definition-syntax/tokenizer.js
generated
vendored
@ -7,46 +7,52 @@ const R = 13;
|
||||
const SPACE = 32;
|
||||
|
||||
export class Tokenizer {
|
||||
constructor(str) {
|
||||
this.str = str;
|
||||
this.pos = 0;
|
||||
constructor(str) {
|
||||
this.str = str;
|
||||
this.pos = 0;
|
||||
}
|
||||
charCodeAt(pos) {
|
||||
return pos < this.str.length ? this.str.charCodeAt(pos) : 0;
|
||||
}
|
||||
charCode() {
|
||||
return this.charCodeAt(this.pos);
|
||||
}
|
||||
nextCharCode() {
|
||||
return this.charCodeAt(this.pos + 1);
|
||||
}
|
||||
nextNonWsCode(pos) {
|
||||
return this.charCodeAt(this.findWsEnd(pos));
|
||||
}
|
||||
findWsEnd(pos) {
|
||||
for (; pos < this.str.length; pos++) {
|
||||
const code = this.str.charCodeAt(pos);
|
||||
if (
|
||||
code !== R &&
|
||||
code !== N &&
|
||||
code !== F &&
|
||||
code !== SPACE &&
|
||||
code !== TAB
|
||||
) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
charCodeAt(pos) {
|
||||
return pos < this.str.length ? this.str.charCodeAt(pos) : 0;
|
||||
}
|
||||
charCode() {
|
||||
return this.charCodeAt(this.pos);
|
||||
}
|
||||
nextCharCode() {
|
||||
return this.charCodeAt(this.pos + 1);
|
||||
}
|
||||
nextNonWsCode(pos) {
|
||||
return this.charCodeAt(this.findWsEnd(pos));
|
||||
}
|
||||
findWsEnd(pos) {
|
||||
for (; pos < this.str.length; pos++) {
|
||||
const code = this.str.charCodeAt(pos);
|
||||
if (code !== R && code !== N && code !== F && code !== SPACE && code !== TAB) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return pos;
|
||||
return pos;
|
||||
}
|
||||
substringToPos(end) {
|
||||
return this.str.substring(this.pos, (this.pos = end));
|
||||
}
|
||||
eat(code) {
|
||||
if (this.charCode() !== code) {
|
||||
this.error('Expect `' + String.fromCharCode(code) + '`');
|
||||
}
|
||||
substringToPos(end) {
|
||||
return this.str.substring(this.pos, this.pos = end);
|
||||
}
|
||||
eat(code) {
|
||||
if (this.charCode() !== code) {
|
||||
this.error('Expect `' + String.fromCharCode(code) + '`');
|
||||
}
|
||||
|
||||
this.pos++;
|
||||
}
|
||||
peek() {
|
||||
return this.pos < this.str.length ? this.str.charAt(this.pos++) : '';
|
||||
}
|
||||
error(message) {
|
||||
throw new SyntaxError(message, this.str, this.pos);
|
||||
}
|
||||
};
|
||||
this.pos++;
|
||||
}
|
||||
peek() {
|
||||
return this.pos < this.str.length ? this.str.charAt(this.pos++) : '';
|
||||
}
|
||||
error(message) {
|
||||
throw new SyntaxError(message, this.str, this.pos);
|
||||
}
|
||||
}
|
||||
|
78
node_modules/css-tree/lib/definition-syntax/walk.js
generated
vendored
78
node_modules/css-tree/lib/definition-syntax/walk.js
generated
vendored
@ -1,52 +1,54 @@
|
||||
const noop = function() {};
|
||||
const noop = function () {};
|
||||
|
||||
function ensureFunction(value) {
|
||||
return typeof value === 'function' ? value : noop;
|
||||
return typeof value === 'function' ? value : noop;
|
||||
}
|
||||
|
||||
export function walk(node, options, context) {
|
||||
function walk(node) {
|
||||
enter.call(context, node);
|
||||
function walk(node) {
|
||||
enter.call(context, node);
|
||||
|
||||
switch (node.type) {
|
||||
case 'Group':
|
||||
node.terms.forEach(walk);
|
||||
break;
|
||||
switch (node.type) {
|
||||
case 'Group':
|
||||
node.terms.forEach(walk);
|
||||
break;
|
||||
|
||||
case 'Multiplier':
|
||||
walk(node.term);
|
||||
break;
|
||||
case 'Multiplier':
|
||||
walk(node.term);
|
||||
break;
|
||||
|
||||
case 'Type':
|
||||
case 'Property':
|
||||
case 'Keyword':
|
||||
case 'AtKeyword':
|
||||
case 'Function':
|
||||
case 'String':
|
||||
case 'Token':
|
||||
case 'Comma':
|
||||
break;
|
||||
case 'Type':
|
||||
case 'Property':
|
||||
case 'Keyword':
|
||||
case 'AtKeyword':
|
||||
case 'Function':
|
||||
case 'String':
|
||||
case 'Token':
|
||||
case 'Comma':
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error('Unknown type: ' + node.type);
|
||||
}
|
||||
|
||||
leave.call(context, node);
|
||||
default:
|
||||
throw new Error('Unknown type: ' + node.type);
|
||||
}
|
||||
|
||||
let enter = noop;
|
||||
let leave = noop;
|
||||
leave.call(context, node);
|
||||
}
|
||||
|
||||
if (typeof options === 'function') {
|
||||
enter = options;
|
||||
} else if (options) {
|
||||
enter = ensureFunction(options.enter);
|
||||
leave = ensureFunction(options.leave);
|
||||
}
|
||||
let enter = noop;
|
||||
let leave = noop;
|
||||
|
||||
if (enter === noop && leave === noop) {
|
||||
throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
|
||||
}
|
||||
if (typeof options === 'function') {
|
||||
enter = options;
|
||||
} else if (options) {
|
||||
enter = ensureFunction(options.enter);
|
||||
leave = ensureFunction(options.leave);
|
||||
}
|
||||
|
||||
walk(node, context);
|
||||
};
|
||||
if (enter === noop && leave === noop) {
|
||||
throw new Error(
|
||||
"Neither `enter` nor `leave` walker handler is set or both aren't a function"
|
||||
);
|
||||
}
|
||||
|
||||
walk(node, context);
|
||||
}
|
||||
|
150
node_modules/css-tree/lib/generator/create.js
generated
vendored
150
node_modules/css-tree/lib/generator/create.js
generated
vendored
@ -5,94 +5,94 @@ import * as tokenBefore from './token-before.js';
|
||||
const REVERSESOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\)
|
||||
|
||||
function processChildren(node, delimeter) {
|
||||
if (typeof delimeter === 'function') {
|
||||
let prev = null;
|
||||
if (typeof delimeter === 'function') {
|
||||
let prev = null;
|
||||
|
||||
node.children.forEach(node => {
|
||||
if (prev !== null) {
|
||||
delimeter.call(this, prev);
|
||||
}
|
||||
node.children.forEach((node) => {
|
||||
if (prev !== null) {
|
||||
delimeter.call(this, prev);
|
||||
}
|
||||
|
||||
this.node(node);
|
||||
prev = node;
|
||||
});
|
||||
this.node(node);
|
||||
prev = node;
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
node.children.forEach(this.node, this);
|
||||
node.children.forEach(this.node, this);
|
||||
}
|
||||
|
||||
function processChunk(chunk) {
|
||||
tokenize(chunk, (type, start, end) => {
|
||||
this.token(type, chunk.slice(start, end));
|
||||
});
|
||||
tokenize(chunk, (type, start, end) => {
|
||||
this.token(type, chunk.slice(start, end));
|
||||
});
|
||||
}
|
||||
|
||||
export function createGenerator(config) {
|
||||
const types = new Map();
|
||||
const types = new Map();
|
||||
|
||||
for (let name in config.node) {
|
||||
const item = config.node[name];
|
||||
const fn = item.generate || item;
|
||||
for (let name in config.node) {
|
||||
const item = config.node[name];
|
||||
const fn = item.generate || item;
|
||||
|
||||
if (typeof fn === 'function') {
|
||||
types.set(name, item.generate || item);
|
||||
if (typeof fn === 'function') {
|
||||
types.set(name, item.generate || item);
|
||||
}
|
||||
}
|
||||
|
||||
return function (node, options) {
|
||||
let buffer = '';
|
||||
let prevCode = 0;
|
||||
let handlers = {
|
||||
node(node) {
|
||||
if (types.has(node.type)) {
|
||||
types.get(node.type).call(publicApi, node);
|
||||
} else {
|
||||
throw new Error('Unknown node type: ' + node.type);
|
||||
}
|
||||
},
|
||||
tokenBefore: tokenBefore.safe,
|
||||
token(type, value) {
|
||||
prevCode = this.tokenBefore(prevCode, type, value);
|
||||
|
||||
this.emit(value, type, false);
|
||||
|
||||
if (type === Delim && value.charCodeAt(0) === REVERSESOLIDUS) {
|
||||
this.emit('\n', WhiteSpace, true);
|
||||
}
|
||||
},
|
||||
emit(value) {
|
||||
buffer += value;
|
||||
},
|
||||
result() {
|
||||
return buffer;
|
||||
},
|
||||
};
|
||||
|
||||
if (options) {
|
||||
if (typeof options.decorator === 'function') {
|
||||
handlers = options.decorator(handlers);
|
||||
}
|
||||
|
||||
if (options.sourceMap) {
|
||||
handlers = generateSourceMap(handlers);
|
||||
}
|
||||
|
||||
if (options.mode in tokenBefore) {
|
||||
handlers.tokenBefore = tokenBefore[options.mode];
|
||||
}
|
||||
}
|
||||
|
||||
return function(node, options) {
|
||||
let buffer = '';
|
||||
let prevCode = 0;
|
||||
let handlers = {
|
||||
node(node) {
|
||||
if (types.has(node.type)) {
|
||||
types.get(node.type).call(publicApi, node);
|
||||
} else {
|
||||
throw new Error('Unknown node type: ' + node.type);
|
||||
}
|
||||
},
|
||||
tokenBefore: tokenBefore.safe,
|
||||
token(type, value) {
|
||||
prevCode = this.tokenBefore(prevCode, type, value);
|
||||
|
||||
this.emit(value, type, false);
|
||||
|
||||
if (type === Delim && value.charCodeAt(0) === REVERSESOLIDUS) {
|
||||
this.emit('\n', WhiteSpace, true);
|
||||
}
|
||||
},
|
||||
emit(value) {
|
||||
buffer += value;
|
||||
},
|
||||
result() {
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
if (options) {
|
||||
if (typeof options.decorator === 'function') {
|
||||
handlers = options.decorator(handlers);
|
||||
}
|
||||
|
||||
if (options.sourceMap) {
|
||||
handlers = generateSourceMap(handlers);
|
||||
}
|
||||
|
||||
if (options.mode in tokenBefore) {
|
||||
handlers.tokenBefore = tokenBefore[options.mode];
|
||||
}
|
||||
}
|
||||
|
||||
const publicApi = {
|
||||
node: (node) => handlers.node(node),
|
||||
children: processChildren,
|
||||
token: (type, value) => handlers.token(type, value),
|
||||
tokenize: processChunk
|
||||
};
|
||||
|
||||
handlers.node(node);
|
||||
|
||||
return handlers.result();
|
||||
const publicApi = {
|
||||
node: (node) => handlers.node(node),
|
||||
children: processChildren,
|
||||
token: (type, value) => handlers.token(type, value),
|
||||
tokenize: processChunk,
|
||||
};
|
||||
};
|
||||
|
||||
handlers.node(node);
|
||||
|
||||
return handlers.result();
|
||||
};
|
||||
}
|
||||
|
158
node_modules/css-tree/lib/generator/sourceMap.js
generated
vendored
158
node_modules/css-tree/lib/generator/sourceMap.js
generated
vendored
@ -3,90 +3,92 @@ import { SourceMapGenerator } from 'source-map-js/lib/source-map-generator.js';
|
||||
const trackNodes = new Set(['Atrule', 'Selector', 'Declaration']);
|
||||
|
||||
export function generateSourceMap(handlers) {
|
||||
const map = new SourceMapGenerator();
|
||||
const generated = {
|
||||
line: 1,
|
||||
column: 0
|
||||
};
|
||||
const original = {
|
||||
line: 0, // should be zero to add first mapping
|
||||
column: 0
|
||||
};
|
||||
const activatedGenerated = {
|
||||
line: 1,
|
||||
column: 0
|
||||
};
|
||||
const activatedMapping = {
|
||||
generated: activatedGenerated
|
||||
};
|
||||
let line = 1;
|
||||
let column = 0;
|
||||
let sourceMappingActive = false;
|
||||
const map = new SourceMapGenerator();
|
||||
const generated = {
|
||||
line: 1,
|
||||
column: 0,
|
||||
};
|
||||
const original = {
|
||||
line: 0, // should be zero to add first mapping
|
||||
column: 0,
|
||||
};
|
||||
const activatedGenerated = {
|
||||
line: 1,
|
||||
column: 0,
|
||||
};
|
||||
const activatedMapping = {
|
||||
generated: activatedGenerated,
|
||||
};
|
||||
let line = 1;
|
||||
let column = 0;
|
||||
let sourceMappingActive = false;
|
||||
|
||||
const origHandlersNode = handlers.node;
|
||||
handlers.node = function(node) {
|
||||
if (node.loc && node.loc.start && trackNodes.has(node.type)) {
|
||||
const nodeLine = node.loc.start.line;
|
||||
const nodeColumn = node.loc.start.column - 1;
|
||||
const origHandlersNode = handlers.node;
|
||||
handlers.node = function (node) {
|
||||
if (node.loc && node.loc.start && trackNodes.has(node.type)) {
|
||||
const nodeLine = node.loc.start.line;
|
||||
const nodeColumn = node.loc.start.column - 1;
|
||||
|
||||
if (original.line !== nodeLine ||
|
||||
original.column !== nodeColumn) {
|
||||
original.line = nodeLine;
|
||||
original.column = nodeColumn;
|
||||
if (original.line !== nodeLine || original.column !== nodeColumn) {
|
||||
original.line = nodeLine;
|
||||
original.column = nodeColumn;
|
||||
|
||||
generated.line = line;
|
||||
generated.column = column;
|
||||
generated.line = line;
|
||||
generated.column = column;
|
||||
|
||||
if (sourceMappingActive) {
|
||||
sourceMappingActive = false;
|
||||
if (generated.line !== activatedGenerated.line ||
|
||||
generated.column !== activatedGenerated.column) {
|
||||
map.addMapping(activatedMapping);
|
||||
}
|
||||
}
|
||||
|
||||
sourceMappingActive = true;
|
||||
map.addMapping({
|
||||
source: node.loc.source,
|
||||
original,
|
||||
generated
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
origHandlersNode.call(this, node);
|
||||
|
||||
if (sourceMappingActive && trackNodes.has(node.type)) {
|
||||
activatedGenerated.line = line;
|
||||
activatedGenerated.column = column;
|
||||
}
|
||||
};
|
||||
|
||||
const origHandlersEmit = handlers.emit;
|
||||
handlers.emit = function(value, type, auto) {
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
if (value.charCodeAt(i) === 10) { // \n
|
||||
line++;
|
||||
column = 0;
|
||||
} else {
|
||||
column++;
|
||||
}
|
||||
}
|
||||
|
||||
origHandlersEmit(value, type, auto);
|
||||
};
|
||||
|
||||
const origHandlersResult = handlers.result;
|
||||
handlers.result = function() {
|
||||
if (sourceMappingActive) {
|
||||
sourceMappingActive = false;
|
||||
if (
|
||||
generated.line !== activatedGenerated.line ||
|
||||
generated.column !== activatedGenerated.column
|
||||
) {
|
||||
map.addMapping(activatedMapping);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
css: origHandlersResult(),
|
||||
map
|
||||
};
|
||||
};
|
||||
sourceMappingActive = true;
|
||||
map.addMapping({
|
||||
source: node.loc.source,
|
||||
original,
|
||||
generated,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return handlers;
|
||||
};
|
||||
origHandlersNode.call(this, node);
|
||||
|
||||
if (sourceMappingActive && trackNodes.has(node.type)) {
|
||||
activatedGenerated.line = line;
|
||||
activatedGenerated.column = column;
|
||||
}
|
||||
};
|
||||
|
||||
const origHandlersEmit = handlers.emit;
|
||||
handlers.emit = function (value, type, auto) {
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
if (value.charCodeAt(i) === 10) {
|
||||
// \n
|
||||
line++;
|
||||
column = 0;
|
||||
} else {
|
||||
column++;
|
||||
}
|
||||
}
|
||||
|
||||
origHandlersEmit(value, type, auto);
|
||||
};
|
||||
|
||||
const origHandlersResult = handlers.result;
|
||||
handlers.result = function () {
|
||||
if (sourceMappingActive) {
|
||||
map.addMapping(activatedMapping);
|
||||
}
|
||||
|
||||
return {
|
||||
css: origHandlersResult(),
|
||||
map,
|
||||
};
|
||||
};
|
||||
|
||||
return handlers;
|
||||
}
|
||||
|
278
node_modules/css-tree/lib/generator/token-before.js
generated
vendored
278
node_modules/css-tree/lib/generator/token-before.js
generated
vendored
@ -1,36 +1,36 @@
|
||||
import {
|
||||
WhiteSpace,
|
||||
Delim,
|
||||
Ident,
|
||||
Function as FunctionToken,
|
||||
Url,
|
||||
BadUrl,
|
||||
AtKeyword,
|
||||
Hash,
|
||||
Percentage,
|
||||
Dimension,
|
||||
Number as NumberToken,
|
||||
String as StringToken,
|
||||
Colon,
|
||||
LeftParenthesis,
|
||||
RightParenthesis,
|
||||
CDC
|
||||
WhiteSpace,
|
||||
Delim,
|
||||
Ident,
|
||||
Function as FunctionToken,
|
||||
Url,
|
||||
BadUrl,
|
||||
AtKeyword,
|
||||
Hash,
|
||||
Percentage,
|
||||
Dimension,
|
||||
Number as NumberToken,
|
||||
String as StringToken,
|
||||
Colon,
|
||||
LeftParenthesis,
|
||||
RightParenthesis,
|
||||
CDC,
|
||||
} from '../tokenizer/index.js';
|
||||
|
||||
const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
|
||||
const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)
|
||||
const PLUSSIGN = 0x002b; // U+002B PLUS SIGN (+)
|
||||
const HYPHENMINUS = 0x002d; // U+002D HYPHEN-MINUS (-)
|
||||
|
||||
const code = (type, value) => {
|
||||
if (type === Delim) {
|
||||
type = value;
|
||||
}
|
||||
if (type === Delim) {
|
||||
type = value;
|
||||
}
|
||||
|
||||
if (typeof type === 'string') {
|
||||
const charCode = type.charCodeAt(0);
|
||||
return charCode > 0x7F ? 0x8000 : charCode << 8;
|
||||
}
|
||||
if (typeof type === 'string') {
|
||||
const charCode = type.charCodeAt(0);
|
||||
return charCode > 0x7f ? 0x8000 : charCode << 8;
|
||||
}
|
||||
|
||||
return type;
|
||||
return type;
|
||||
};
|
||||
|
||||
// https://www.w3.org/TR/css-syntax-3/#serialization
|
||||
@ -40,142 +40,144 @@ const code = (type, value) => {
|
||||
// which may be collapsed into a single token.
|
||||
|
||||
const specPairs = [
|
||||
[Ident, Ident],
|
||||
[Ident, FunctionToken],
|
||||
[Ident, Url],
|
||||
[Ident, BadUrl],
|
||||
[Ident, '-'],
|
||||
[Ident, NumberToken],
|
||||
[Ident, Percentage],
|
||||
[Ident, Dimension],
|
||||
[Ident, CDC],
|
||||
[Ident, LeftParenthesis],
|
||||
[Ident, Ident],
|
||||
[Ident, FunctionToken],
|
||||
[Ident, Url],
|
||||
[Ident, BadUrl],
|
||||
[Ident, '-'],
|
||||
[Ident, NumberToken],
|
||||
[Ident, Percentage],
|
||||
[Ident, Dimension],
|
||||
[Ident, CDC],
|
||||
[Ident, LeftParenthesis],
|
||||
|
||||
[AtKeyword, Ident],
|
||||
[AtKeyword, FunctionToken],
|
||||
[AtKeyword, Url],
|
||||
[AtKeyword, BadUrl],
|
||||
[AtKeyword, '-'],
|
||||
[AtKeyword, NumberToken],
|
||||
[AtKeyword, Percentage],
|
||||
[AtKeyword, Dimension],
|
||||
[AtKeyword, CDC],
|
||||
[AtKeyword, Ident],
|
||||
[AtKeyword, FunctionToken],
|
||||
[AtKeyword, Url],
|
||||
[AtKeyword, BadUrl],
|
||||
[AtKeyword, '-'],
|
||||
[AtKeyword, NumberToken],
|
||||
[AtKeyword, Percentage],
|
||||
[AtKeyword, Dimension],
|
||||
[AtKeyword, CDC],
|
||||
|
||||
[Hash, Ident],
|
||||
[Hash, FunctionToken],
|
||||
[Hash, Url],
|
||||
[Hash, BadUrl],
|
||||
[Hash, '-'],
|
||||
[Hash, NumberToken],
|
||||
[Hash, Percentage],
|
||||
[Hash, Dimension],
|
||||
[Hash, CDC],
|
||||
[Hash, Ident],
|
||||
[Hash, FunctionToken],
|
||||
[Hash, Url],
|
||||
[Hash, BadUrl],
|
||||
[Hash, '-'],
|
||||
[Hash, NumberToken],
|
||||
[Hash, Percentage],
|
||||
[Hash, Dimension],
|
||||
[Hash, CDC],
|
||||
|
||||
[Dimension, Ident],
|
||||
[Dimension, FunctionToken],
|
||||
[Dimension, Url],
|
||||
[Dimension, BadUrl],
|
||||
[Dimension, '-'],
|
||||
[Dimension, NumberToken],
|
||||
[Dimension, Percentage],
|
||||
[Dimension, Dimension],
|
||||
[Dimension, CDC],
|
||||
[Dimension, Ident],
|
||||
[Dimension, FunctionToken],
|
||||
[Dimension, Url],
|
||||
[Dimension, BadUrl],
|
||||
[Dimension, '-'],
|
||||
[Dimension, NumberToken],
|
||||
[Dimension, Percentage],
|
||||
[Dimension, Dimension],
|
||||
[Dimension, CDC],
|
||||
|
||||
['#', Ident],
|
||||
['#', FunctionToken],
|
||||
['#', Url],
|
||||
['#', BadUrl],
|
||||
['#', '-'],
|
||||
['#', NumberToken],
|
||||
['#', Percentage],
|
||||
['#', Dimension],
|
||||
['#', CDC], // https://github.com/w3c/csswg-drafts/pull/6874
|
||||
['#', Ident],
|
||||
['#', FunctionToken],
|
||||
['#', Url],
|
||||
['#', BadUrl],
|
||||
['#', '-'],
|
||||
['#', NumberToken],
|
||||
['#', Percentage],
|
||||
['#', Dimension],
|
||||
['#', CDC], // https://github.com/w3c/csswg-drafts/pull/6874
|
||||
|
||||
['-', Ident],
|
||||
['-', FunctionToken],
|
||||
['-', Url],
|
||||
['-', BadUrl],
|
||||
['-', '-'],
|
||||
['-', NumberToken],
|
||||
['-', Percentage],
|
||||
['-', Dimension],
|
||||
['-', CDC], // https://github.com/w3c/csswg-drafts/pull/6874
|
||||
['-', Ident],
|
||||
['-', FunctionToken],
|
||||
['-', Url],
|
||||
['-', BadUrl],
|
||||
['-', '-'],
|
||||
['-', NumberToken],
|
||||
['-', Percentage],
|
||||
['-', Dimension],
|
||||
['-', CDC], // https://github.com/w3c/csswg-drafts/pull/6874
|
||||
|
||||
[NumberToken, Ident],
|
||||
[NumberToken, FunctionToken],
|
||||
[NumberToken, Url],
|
||||
[NumberToken, BadUrl],
|
||||
[NumberToken, NumberToken],
|
||||
[NumberToken, Percentage],
|
||||
[NumberToken, Dimension],
|
||||
[NumberToken, '%'],
|
||||
[NumberToken, CDC], // https://github.com/w3c/csswg-drafts/pull/6874
|
||||
[NumberToken, Ident],
|
||||
[NumberToken, FunctionToken],
|
||||
[NumberToken, Url],
|
||||
[NumberToken, BadUrl],
|
||||
[NumberToken, NumberToken],
|
||||
[NumberToken, Percentage],
|
||||
[NumberToken, Dimension],
|
||||
[NumberToken, '%'],
|
||||
[NumberToken, CDC], // https://github.com/w3c/csswg-drafts/pull/6874
|
||||
|
||||
['@', Ident],
|
||||
['@', FunctionToken],
|
||||
['@', Url],
|
||||
['@', BadUrl],
|
||||
['@', '-'],
|
||||
['@', CDC], // https://github.com/w3c/csswg-drafts/pull/6874
|
||||
['@', Ident],
|
||||
['@', FunctionToken],
|
||||
['@', Url],
|
||||
['@', BadUrl],
|
||||
['@', '-'],
|
||||
['@', CDC], // https://github.com/w3c/csswg-drafts/pull/6874
|
||||
|
||||
['.', NumberToken],
|
||||
['.', Percentage],
|
||||
['.', Dimension],
|
||||
['.', NumberToken],
|
||||
['.', Percentage],
|
||||
['.', Dimension],
|
||||
|
||||
['+', NumberToken],
|
||||
['+', Percentage],
|
||||
['+', Dimension],
|
||||
['+', NumberToken],
|
||||
['+', Percentage],
|
||||
['+', Dimension],
|
||||
|
||||
['/', '*']
|
||||
['/', '*'],
|
||||
];
|
||||
// validate with scripts/generate-safe
|
||||
const safePairs = specPairs.concat([
|
||||
[Ident, Hash],
|
||||
[Ident, Hash],
|
||||
|
||||
[Dimension, Hash],
|
||||
[Dimension, Hash],
|
||||
|
||||
[Hash, Hash],
|
||||
[Hash, Hash],
|
||||
|
||||
[AtKeyword, LeftParenthesis],
|
||||
[AtKeyword, StringToken],
|
||||
[AtKeyword, Colon],
|
||||
[AtKeyword, LeftParenthesis],
|
||||
[AtKeyword, StringToken],
|
||||
[AtKeyword, Colon],
|
||||
|
||||
[Percentage, Percentage],
|
||||
[Percentage, Dimension],
|
||||
[Percentage, FunctionToken],
|
||||
[Percentage, '-'],
|
||||
[Percentage, Percentage],
|
||||
[Percentage, Dimension],
|
||||
[Percentage, FunctionToken],
|
||||
[Percentage, '-'],
|
||||
|
||||
[RightParenthesis, Ident],
|
||||
[RightParenthesis, FunctionToken],
|
||||
[RightParenthesis, Percentage],
|
||||
[RightParenthesis, Dimension],
|
||||
[RightParenthesis, Hash],
|
||||
[RightParenthesis, '-']
|
||||
[RightParenthesis, Ident],
|
||||
[RightParenthesis, FunctionToken],
|
||||
[RightParenthesis, Percentage],
|
||||
[RightParenthesis, Dimension],
|
||||
[RightParenthesis, Hash],
|
||||
[RightParenthesis, '-'],
|
||||
]);
|
||||
|
||||
function createMap(pairs) {
|
||||
const isWhiteSpaceRequired = new Set(
|
||||
pairs.map(([prev, next]) => (code(prev) << 16 | code(next)))
|
||||
);
|
||||
const isWhiteSpaceRequired = new Set(
|
||||
pairs.map(([prev, next]) => (code(prev) << 16) | code(next))
|
||||
);
|
||||
|
||||
return function(prevCode, type, value) {
|
||||
const nextCode = code(type, value);
|
||||
const nextCharCode = value.charCodeAt(0);
|
||||
const emitWs =
|
||||
(nextCharCode === HYPHENMINUS &&
|
||||
type !== Ident &&
|
||||
type !== FunctionToken &&
|
||||
type !== CDC) ||
|
||||
(nextCharCode === PLUSSIGN)
|
||||
? isWhiteSpaceRequired.has(prevCode << 16 | nextCharCode << 8)
|
||||
: isWhiteSpaceRequired.has(prevCode << 16 | nextCode);
|
||||
return function (prevCode, type, value) {
|
||||
const nextCode = code(type, value);
|
||||
const nextCharCode = value.charCodeAt(0);
|
||||
const emitWs =
|
||||
(
|
||||
(nextCharCode === HYPHENMINUS &&
|
||||
type !== Ident &&
|
||||
type !== FunctionToken &&
|
||||
type !== CDC) ||
|
||||
nextCharCode === PLUSSIGN
|
||||
) ?
|
||||
isWhiteSpaceRequired.has((prevCode << 16) | (nextCharCode << 8))
|
||||
: isWhiteSpaceRequired.has((prevCode << 16) | nextCode);
|
||||
|
||||
if (emitWs) {
|
||||
this.emit(' ', WhiteSpace, true);
|
||||
}
|
||||
if (emitWs) {
|
||||
this.emit(' ', WhiteSpace, true);
|
||||
}
|
||||
|
||||
return nextCode;
|
||||
};
|
||||
return nextCode;
|
||||
};
|
||||
}
|
||||
|
||||
export const spec = createMap(specPairs);
|
||||
|
24
node_modules/css-tree/lib/index.js
generated
vendored
24
node_modules/css-tree/lib/index.js
generated
vendored
@ -12,19 +12,19 @@ export * as ident from './utils/ident.js';
|
||||
export * as string from './utils/string.js';
|
||||
export * as url from './utils/url.js';
|
||||
export const {
|
||||
tokenize,
|
||||
parse,
|
||||
generate,
|
||||
lexer,
|
||||
createLexer,
|
||||
tokenize,
|
||||
parse,
|
||||
generate,
|
||||
lexer,
|
||||
createLexer,
|
||||
|
||||
walk,
|
||||
find,
|
||||
findLast,
|
||||
findAll,
|
||||
walk,
|
||||
find,
|
||||
findLast,
|
||||
findAll,
|
||||
|
||||
toPlainObject,
|
||||
fromPlainObject,
|
||||
toPlainObject,
|
||||
fromPlainObject,
|
||||
|
||||
fork
|
||||
fork,
|
||||
} = syntax;
|
||||
|
846
node_modules/css-tree/lib/lexer/Lexer.js
generated
vendored
846
node_modules/css-tree/lib/lexer/Lexer.js
generated
vendored
@ -13,441 +13,507 @@ import { getStructureFromConfig } from './structure.js';
|
||||
const cssWideKeywordsSyntax = buildMatchGraph(cssWideKeywords.join(' | '));
|
||||
|
||||
function dumpMapSyntax(map, compact, syntaxAsAst) {
|
||||
const result = {};
|
||||
const result = {};
|
||||
|
||||
for (const name in map) {
|
||||
if (map[name].syntax) {
|
||||
result[name] = syntaxAsAst
|
||||
? map[name].syntax
|
||||
: generate(map[name].syntax, { compact });
|
||||
}
|
||||
for (const name in map) {
|
||||
if (map[name].syntax) {
|
||||
result[name] =
|
||||
syntaxAsAst ?
|
||||
map[name].syntax
|
||||
: generate(map[name].syntax, { compact });
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function dumpAtruleMapSyntax(map, compact, syntaxAsAst) {
|
||||
const result = {};
|
||||
const result = {};
|
||||
|
||||
for (const [name, atrule] of Object.entries(map)) {
|
||||
result[name] = {
|
||||
prelude: atrule.prelude && (
|
||||
syntaxAsAst
|
||||
? atrule.prelude.syntax
|
||||
: generate(atrule.prelude.syntax, { compact })
|
||||
),
|
||||
descriptors: atrule.descriptors && dumpMapSyntax(atrule.descriptors, compact, syntaxAsAst)
|
||||
};
|
||||
}
|
||||
for (const [name, atrule] of Object.entries(map)) {
|
||||
result[name] = {
|
||||
prelude:
|
||||
atrule.prelude &&
|
||||
(syntaxAsAst ?
|
||||
atrule.prelude.syntax
|
||||
: generate(atrule.prelude.syntax, { compact })),
|
||||
descriptors:
|
||||
atrule.descriptors &&
|
||||
dumpMapSyntax(atrule.descriptors, compact, syntaxAsAst),
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function valueHasVar(tokens) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
if (tokens[i].value.toLowerCase() === 'var(') {
|
||||
return true;
|
||||
}
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
if (tokens[i].value.toLowerCase() === 'var(') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
function buildMatchResult(matched, error, iterations) {
|
||||
return {
|
||||
matched,
|
||||
iterations,
|
||||
error,
|
||||
...trace
|
||||
};
|
||||
return {
|
||||
matched,
|
||||
iterations,
|
||||
error,
|
||||
...trace,
|
||||
};
|
||||
}
|
||||
|
||||
function matchSyntax(lexer, syntax, value, useCssWideKeywords) {
|
||||
const tokens = prepareTokens(value, lexer.syntax);
|
||||
let result;
|
||||
const tokens = prepareTokens(value, lexer.syntax);
|
||||
let result;
|
||||
|
||||
if (valueHasVar(tokens)) {
|
||||
return buildMatchResult(null, new Error('Matching for a tree with var() is not supported'));
|
||||
if (valueHasVar(tokens)) {
|
||||
return buildMatchResult(
|
||||
null,
|
||||
new Error('Matching for a tree with var() is not supported')
|
||||
);
|
||||
}
|
||||
|
||||
if (useCssWideKeywords) {
|
||||
result = matchAsTree(tokens, lexer.cssWideKeywordsSyntax, lexer);
|
||||
}
|
||||
|
||||
if (!useCssWideKeywords || !result.match) {
|
||||
result = matchAsTree(tokens, syntax.match, lexer);
|
||||
if (!result.match) {
|
||||
return buildMatchResult(
|
||||
null,
|
||||
new SyntaxMatchError(result.reason, syntax.syntax, value, result),
|
||||
result.iterations
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (useCssWideKeywords) {
|
||||
result = matchAsTree(tokens, lexer.cssWideKeywordsSyntax, lexer);
|
||||
}
|
||||
|
||||
if (!useCssWideKeywords || !result.match) {
|
||||
result = matchAsTree(tokens, syntax.match, lexer);
|
||||
if (!result.match) {
|
||||
return buildMatchResult(
|
||||
null,
|
||||
new SyntaxMatchError(result.reason, syntax.syntax, value, result),
|
||||
result.iterations
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return buildMatchResult(result.match, null, result.iterations);
|
||||
return buildMatchResult(result.match, null, result.iterations);
|
||||
}
|
||||
|
||||
export class Lexer {
|
||||
constructor(config, syntax, structure) {
|
||||
this.cssWideKeywordsSyntax = cssWideKeywordsSyntax;
|
||||
this.syntax = syntax;
|
||||
this.generic = false;
|
||||
this.atrules = Object.create(null);
|
||||
this.properties = Object.create(null);
|
||||
this.types = Object.create(null);
|
||||
this.structure = structure || getStructureFromConfig(config);
|
||||
constructor(config, syntax, structure) {
|
||||
this.cssWideKeywordsSyntax = cssWideKeywordsSyntax;
|
||||
this.syntax = syntax;
|
||||
this.generic = false;
|
||||
this.atrules = Object.create(null);
|
||||
this.properties = Object.create(null);
|
||||
this.types = Object.create(null);
|
||||
this.structure = structure || getStructureFromConfig(config);
|
||||
|
||||
if (config) {
|
||||
if (config.types) {
|
||||
for (const name in config.types) {
|
||||
this.addType_(name, config.types[name]);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.generic) {
|
||||
this.generic = true;
|
||||
for (const name in generic) {
|
||||
this.addType_(name, generic[name]);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.atrules) {
|
||||
for (const name in config.atrules) {
|
||||
this.addAtrule_(name, config.atrules[name]);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.properties) {
|
||||
for (const name in config.properties) {
|
||||
this.addProperty_(name, config.properties[name]);
|
||||
}
|
||||
}
|
||||
if (config) {
|
||||
if (config.types) {
|
||||
for (const name in config.types) {
|
||||
this.addType_(name, config.types[name]);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.generic) {
|
||||
this.generic = true;
|
||||
for (const name in generic) {
|
||||
this.addType_(name, generic[name]);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.atrules) {
|
||||
for (const name in config.atrules) {
|
||||
this.addAtrule_(name, config.atrules[name]);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.properties) {
|
||||
for (const name in config.properties) {
|
||||
this.addProperty_(name, config.properties[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkStructure(ast) {
|
||||
function collectWarning(node, message) {
|
||||
warns.push({ node, message });
|
||||
}
|
||||
|
||||
checkStructure(ast) {
|
||||
function collectWarning(node, message) {
|
||||
warns.push({ node, message });
|
||||
}
|
||||
const structure = this.structure;
|
||||
const warns = [];
|
||||
|
||||
const structure = this.structure;
|
||||
const warns = [];
|
||||
this.syntax.walk(ast, function (node) {
|
||||
if (structure.hasOwnProperty(node.type)) {
|
||||
structure[node.type].check(node, collectWarning);
|
||||
} else {
|
||||
collectWarning(node, 'Unknown node type `' + node.type + '`');
|
||||
}
|
||||
});
|
||||
|
||||
this.syntax.walk(ast, function(node) {
|
||||
if (structure.hasOwnProperty(node.type)) {
|
||||
structure[node.type].check(node, collectWarning);
|
||||
} else {
|
||||
collectWarning(node, 'Unknown node type `' + node.type + '`');
|
||||
}
|
||||
});
|
||||
return warns.length ? warns : false;
|
||||
}
|
||||
|
||||
return warns.length ? warns : false;
|
||||
}
|
||||
createDescriptor(syntax, type, name, parent = null) {
|
||||
const ref = {
|
||||
type,
|
||||
name,
|
||||
};
|
||||
const descriptor = {
|
||||
type,
|
||||
name,
|
||||
parent,
|
||||
serializable:
|
||||
typeof syntax === 'string' ||
|
||||
(syntax && typeof syntax.type === 'string'),
|
||||
syntax: null,
|
||||
match: null,
|
||||
};
|
||||
|
||||
createDescriptor(syntax, type, name, parent = null) {
|
||||
const ref = {
|
||||
type,
|
||||
name
|
||||
};
|
||||
const descriptor = {
|
||||
type,
|
||||
name,
|
||||
parent,
|
||||
serializable: typeof syntax === 'string' || (syntax && typeof syntax.type === 'string'),
|
||||
syntax: null,
|
||||
match: null
|
||||
};
|
||||
|
||||
if (typeof syntax === 'function') {
|
||||
descriptor.match = buildMatchGraph(syntax, ref);
|
||||
} else {
|
||||
if (typeof syntax === 'string') {
|
||||
// lazy parsing on first access
|
||||
Object.defineProperty(descriptor, 'syntax', {
|
||||
get() {
|
||||
Object.defineProperty(descriptor, 'syntax', {
|
||||
value: parse(syntax)
|
||||
});
|
||||
|
||||
return descriptor.syntax;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
descriptor.syntax = syntax;
|
||||
}
|
||||
|
||||
// lazy graph build on first access
|
||||
Object.defineProperty(descriptor, 'match', {
|
||||
get() {
|
||||
Object.defineProperty(descriptor, 'match', {
|
||||
value: buildMatchGraph(descriptor.syntax, ref)
|
||||
});
|
||||
|
||||
return descriptor.match;
|
||||
}
|
||||
if (typeof syntax === 'function') {
|
||||
descriptor.match = buildMatchGraph(syntax, ref);
|
||||
} else {
|
||||
if (typeof syntax === 'string') {
|
||||
// lazy parsing on first access
|
||||
Object.defineProperty(descriptor, 'syntax', {
|
||||
get() {
|
||||
Object.defineProperty(descriptor, 'syntax', {
|
||||
value: parse(syntax),
|
||||
});
|
||||
}
|
||||
|
||||
return descriptor;
|
||||
}
|
||||
addAtrule_(name, syntax) {
|
||||
if (!syntax) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.atrules[name] = {
|
||||
type: 'Atrule',
|
||||
name: name,
|
||||
prelude: syntax.prelude ? this.createDescriptor(syntax.prelude, 'AtrulePrelude', name) : null,
|
||||
descriptors: syntax.descriptors
|
||||
? Object.keys(syntax.descriptors).reduce(
|
||||
(map, descName) => {
|
||||
map[descName] = this.createDescriptor(syntax.descriptors[descName], 'AtruleDescriptor', descName, name);
|
||||
return map;
|
||||
},
|
||||
Object.create(null)
|
||||
)
|
||||
: null
|
||||
};
|
||||
}
|
||||
addProperty_(name, syntax) {
|
||||
if (!syntax) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.properties[name] = this.createDescriptor(syntax, 'Property', name);
|
||||
}
|
||||
addType_(name, syntax) {
|
||||
if (!syntax) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.types[name] = this.createDescriptor(syntax, 'Type', name);
|
||||
}
|
||||
|
||||
checkAtruleName(atruleName) {
|
||||
if (!this.getAtrule(atruleName)) {
|
||||
return new SyntaxReferenceError('Unknown at-rule', '@' + atruleName);
|
||||
}
|
||||
}
|
||||
checkAtrulePrelude(atruleName, prelude) {
|
||||
const error = this.checkAtruleName(atruleName);
|
||||
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
const atrule = this.getAtrule(atruleName);
|
||||
|
||||
if (!atrule.prelude && prelude) {
|
||||
return new SyntaxError('At-rule `@' + atruleName + '` should not contain a prelude');
|
||||
}
|
||||
|
||||
if (atrule.prelude && !prelude) {
|
||||
if (!matchSyntax(this, atrule.prelude, '', false).matched) {
|
||||
return new SyntaxError('At-rule `@' + atruleName + '` should contain a prelude');
|
||||
}
|
||||
}
|
||||
}
|
||||
checkAtruleDescriptorName(atruleName, descriptorName) {
|
||||
const error = this.checkAtruleName(atruleName);
|
||||
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
const atrule = this.getAtrule(atruleName);
|
||||
const descriptor = names.keyword(descriptorName);
|
||||
|
||||
if (!atrule.descriptors) {
|
||||
return new SyntaxError('At-rule `@' + atruleName + '` has no known descriptors');
|
||||
}
|
||||
|
||||
if (!atrule.descriptors[descriptor.name] &&
|
||||
!atrule.descriptors[descriptor.basename]) {
|
||||
return new SyntaxReferenceError('Unknown at-rule descriptor', descriptorName);
|
||||
}
|
||||
}
|
||||
checkPropertyName(propertyName) {
|
||||
if (!this.getProperty(propertyName)) {
|
||||
return new SyntaxReferenceError('Unknown property', propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
matchAtrulePrelude(atruleName, prelude) {
|
||||
const error = this.checkAtrulePrelude(atruleName, prelude);
|
||||
|
||||
if (error) {
|
||||
return buildMatchResult(null, error);
|
||||
}
|
||||
|
||||
const atrule = this.getAtrule(atruleName);
|
||||
|
||||
if (!atrule.prelude) {
|
||||
return buildMatchResult(null, null);
|
||||
}
|
||||
|
||||
return matchSyntax(this, atrule.prelude, prelude || '', false);
|
||||
}
|
||||
matchAtruleDescriptor(atruleName, descriptorName, value) {
|
||||
const error = this.checkAtruleDescriptorName(atruleName, descriptorName);
|
||||
|
||||
if (error) {
|
||||
return buildMatchResult(null, error);
|
||||
}
|
||||
|
||||
const atrule = this.getAtrule(atruleName);
|
||||
const descriptor = names.keyword(descriptorName);
|
||||
|
||||
return matchSyntax(this, atrule.descriptors[descriptor.name] || atrule.descriptors[descriptor.basename], value, false);
|
||||
}
|
||||
matchDeclaration(node) {
|
||||
if (node.type !== 'Declaration') {
|
||||
return buildMatchResult(null, new Error('Not a Declaration node'));
|
||||
}
|
||||
|
||||
return this.matchProperty(node.property, node.value);
|
||||
}
|
||||
matchProperty(propertyName, value) {
|
||||
// don't match syntax for a custom property at the moment
|
||||
if (names.property(propertyName).custom) {
|
||||
return buildMatchResult(null, new Error('Lexer matching doesn\'t applicable for custom properties'));
|
||||
}
|
||||
|
||||
const error = this.checkPropertyName(propertyName);
|
||||
|
||||
if (error) {
|
||||
return buildMatchResult(null, error);
|
||||
}
|
||||
|
||||
return matchSyntax(this, this.getProperty(propertyName), value, true);
|
||||
}
|
||||
matchType(typeName, value) {
|
||||
const typeSyntax = this.getType(typeName);
|
||||
|
||||
if (!typeSyntax) {
|
||||
return buildMatchResult(null, new SyntaxReferenceError('Unknown type', typeName));
|
||||
}
|
||||
|
||||
return matchSyntax(this, typeSyntax, value, false);
|
||||
}
|
||||
match(syntax, value) {
|
||||
if (typeof syntax !== 'string' && (!syntax || !syntax.type)) {
|
||||
return buildMatchResult(null, new SyntaxReferenceError('Bad syntax'));
|
||||
}
|
||||
|
||||
if (typeof syntax === 'string' || !syntax.match) {
|
||||
syntax = this.createDescriptor(syntax, 'Type', 'anonymous');
|
||||
}
|
||||
|
||||
return matchSyntax(this, syntax, value, false);
|
||||
}
|
||||
|
||||
findValueFragments(propertyName, value, type, name) {
|
||||
return matchFragments(this, value, this.matchProperty(propertyName, value), type, name);
|
||||
}
|
||||
findDeclarationValueFragments(declaration, type, name) {
|
||||
return matchFragments(this, declaration.value, this.matchDeclaration(declaration), type, name);
|
||||
}
|
||||
findAllFragments(ast, type, name) {
|
||||
const result = [];
|
||||
|
||||
this.syntax.walk(ast, {
|
||||
visit: 'Declaration',
|
||||
enter: (declaration) => {
|
||||
result.push.apply(result, this.findDeclarationValueFragments(declaration, type, name));
|
||||
}
|
||||
return descriptor.syntax;
|
||||
},
|
||||
});
|
||||
} else {
|
||||
descriptor.syntax = syntax;
|
||||
}
|
||||
|
||||
return result;
|
||||
// lazy graph build on first access
|
||||
Object.defineProperty(descriptor, 'match', {
|
||||
get() {
|
||||
Object.defineProperty(descriptor, 'match', {
|
||||
value: buildMatchGraph(descriptor.syntax, ref),
|
||||
});
|
||||
|
||||
return descriptor.match;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
getAtrule(atruleName, fallbackBasename = true) {
|
||||
const atrule = names.keyword(atruleName);
|
||||
const atruleEntry = atrule.vendor && fallbackBasename
|
||||
? this.atrules[atrule.name] || this.atrules[atrule.basename]
|
||||
: this.atrules[atrule.name];
|
||||
|
||||
return atruleEntry || null;
|
||||
}
|
||||
getAtrulePrelude(atruleName, fallbackBasename = true) {
|
||||
const atrule = this.getAtrule(atruleName, fallbackBasename);
|
||||
|
||||
return atrule && atrule.prelude || null;
|
||||
}
|
||||
getAtruleDescriptor(atruleName, name) {
|
||||
return this.atrules.hasOwnProperty(atruleName) && this.atrules.declarators
|
||||
? this.atrules[atruleName].declarators[name] || null
|
||||
: null;
|
||||
}
|
||||
getProperty(propertyName, fallbackBasename = true) {
|
||||
const property = names.property(propertyName);
|
||||
const propertyEntry = property.vendor && fallbackBasename
|
||||
? this.properties[property.name] || this.properties[property.basename]
|
||||
: this.properties[property.name];
|
||||
|
||||
return propertyEntry || null;
|
||||
}
|
||||
getType(name) {
|
||||
return hasOwnProperty.call(this.types, name) ? this.types[name] : null;
|
||||
return descriptor;
|
||||
}
|
||||
addAtrule_(name, syntax) {
|
||||
if (!syntax) {
|
||||
return;
|
||||
}
|
||||
|
||||
validate() {
|
||||
function validate(syntax, name, broken, descriptor) {
|
||||
if (broken.has(name)) {
|
||||
return broken.get(name);
|
||||
this.atrules[name] = {
|
||||
type: 'Atrule',
|
||||
name: name,
|
||||
prelude:
|
||||
syntax.prelude ?
|
||||
this.createDescriptor(syntax.prelude, 'AtrulePrelude', name)
|
||||
: null,
|
||||
descriptors:
|
||||
syntax.descriptors ?
|
||||
Object.keys(syntax.descriptors).reduce((map, descName) => {
|
||||
map[descName] = this.createDescriptor(
|
||||
syntax.descriptors[descName],
|
||||
'AtruleDescriptor',
|
||||
descName,
|
||||
name
|
||||
);
|
||||
return map;
|
||||
}, Object.create(null))
|
||||
: null,
|
||||
};
|
||||
}
|
||||
addProperty_(name, syntax) {
|
||||
if (!syntax) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.properties[name] = this.createDescriptor(syntax, 'Property', name);
|
||||
}
|
||||
addType_(name, syntax) {
|
||||
if (!syntax) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.types[name] = this.createDescriptor(syntax, 'Type', name);
|
||||
}
|
||||
|
||||
checkAtruleName(atruleName) {
|
||||
if (!this.getAtrule(atruleName)) {
|
||||
return new SyntaxReferenceError('Unknown at-rule', '@' + atruleName);
|
||||
}
|
||||
}
|
||||
checkAtrulePrelude(atruleName, prelude) {
|
||||
const error = this.checkAtruleName(atruleName);
|
||||
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
const atrule = this.getAtrule(atruleName);
|
||||
|
||||
if (!atrule.prelude && prelude) {
|
||||
return new SyntaxError(
|
||||
'At-rule `@' + atruleName + '` should not contain a prelude'
|
||||
);
|
||||
}
|
||||
|
||||
if (atrule.prelude && !prelude) {
|
||||
if (!matchSyntax(this, atrule.prelude, '', false).matched) {
|
||||
return new SyntaxError(
|
||||
'At-rule `@' + atruleName + '` should contain a prelude'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
checkAtruleDescriptorName(atruleName, descriptorName) {
|
||||
const error = this.checkAtruleName(atruleName);
|
||||
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
const atrule = this.getAtrule(atruleName);
|
||||
const descriptor = names.keyword(descriptorName);
|
||||
|
||||
if (!atrule.descriptors) {
|
||||
return new SyntaxError(
|
||||
'At-rule `@' + atruleName + '` has no known descriptors'
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
!atrule.descriptors[descriptor.name] &&
|
||||
!atrule.descriptors[descriptor.basename]
|
||||
) {
|
||||
return new SyntaxReferenceError(
|
||||
'Unknown at-rule descriptor',
|
||||
descriptorName
|
||||
);
|
||||
}
|
||||
}
|
||||
checkPropertyName(propertyName) {
|
||||
if (!this.getProperty(propertyName)) {
|
||||
return new SyntaxReferenceError('Unknown property', propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
matchAtrulePrelude(atruleName, prelude) {
|
||||
const error = this.checkAtrulePrelude(atruleName, prelude);
|
||||
|
||||
if (error) {
|
||||
return buildMatchResult(null, error);
|
||||
}
|
||||
|
||||
const atrule = this.getAtrule(atruleName);
|
||||
|
||||
if (!atrule.prelude) {
|
||||
return buildMatchResult(null, null);
|
||||
}
|
||||
|
||||
return matchSyntax(this, atrule.prelude, prelude || '', false);
|
||||
}
|
||||
matchAtruleDescriptor(atruleName, descriptorName, value) {
|
||||
const error = this.checkAtruleDescriptorName(atruleName, descriptorName);
|
||||
|
||||
if (error) {
|
||||
return buildMatchResult(null, error);
|
||||
}
|
||||
|
||||
const atrule = this.getAtrule(atruleName);
|
||||
const descriptor = names.keyword(descriptorName);
|
||||
|
||||
return matchSyntax(
|
||||
this,
|
||||
atrule.descriptors[descriptor.name] ||
|
||||
atrule.descriptors[descriptor.basename],
|
||||
value,
|
||||
false
|
||||
);
|
||||
}
|
||||
matchDeclaration(node) {
|
||||
if (node.type !== 'Declaration') {
|
||||
return buildMatchResult(null, new Error('Not a Declaration node'));
|
||||
}
|
||||
|
||||
return this.matchProperty(node.property, node.value);
|
||||
}
|
||||
matchProperty(propertyName, value) {
|
||||
// don't match syntax for a custom property at the moment
|
||||
if (names.property(propertyName).custom) {
|
||||
return buildMatchResult(
|
||||
null,
|
||||
new Error("Lexer matching doesn't applicable for custom properties")
|
||||
);
|
||||
}
|
||||
|
||||
const error = this.checkPropertyName(propertyName);
|
||||
|
||||
if (error) {
|
||||
return buildMatchResult(null, error);
|
||||
}
|
||||
|
||||
return matchSyntax(this, this.getProperty(propertyName), value, true);
|
||||
}
|
||||
matchType(typeName, value) {
|
||||
const typeSyntax = this.getType(typeName);
|
||||
|
||||
if (!typeSyntax) {
|
||||
return buildMatchResult(
|
||||
null,
|
||||
new SyntaxReferenceError('Unknown type', typeName)
|
||||
);
|
||||
}
|
||||
|
||||
return matchSyntax(this, typeSyntax, value, false);
|
||||
}
|
||||
match(syntax, value) {
|
||||
if (typeof syntax !== 'string' && (!syntax || !syntax.type)) {
|
||||
return buildMatchResult(null, new SyntaxReferenceError('Bad syntax'));
|
||||
}
|
||||
|
||||
if (typeof syntax === 'string' || !syntax.match) {
|
||||
syntax = this.createDescriptor(syntax, 'Type', 'anonymous');
|
||||
}
|
||||
|
||||
return matchSyntax(this, syntax, value, false);
|
||||
}
|
||||
|
||||
findValueFragments(propertyName, value, type, name) {
|
||||
return matchFragments(
|
||||
this,
|
||||
value,
|
||||
this.matchProperty(propertyName, value),
|
||||
type,
|
||||
name
|
||||
);
|
||||
}
|
||||
findDeclarationValueFragments(declaration, type, name) {
|
||||
return matchFragments(
|
||||
this,
|
||||
declaration.value,
|
||||
this.matchDeclaration(declaration),
|
||||
type,
|
||||
name
|
||||
);
|
||||
}
|
||||
findAllFragments(ast, type, name) {
|
||||
const result = [];
|
||||
|
||||
this.syntax.walk(ast, {
|
||||
visit: 'Declaration',
|
||||
enter: (declaration) => {
|
||||
result.push.apply(
|
||||
result,
|
||||
this.findDeclarationValueFragments(declaration, type, name)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
getAtrule(atruleName, fallbackBasename = true) {
|
||||
const atrule = names.keyword(atruleName);
|
||||
const atruleEntry =
|
||||
atrule.vendor && fallbackBasename ?
|
||||
this.atrules[atrule.name] || this.atrules[atrule.basename]
|
||||
: this.atrules[atrule.name];
|
||||
|
||||
return atruleEntry || null;
|
||||
}
|
||||
getAtrulePrelude(atruleName, fallbackBasename = true) {
|
||||
const atrule = this.getAtrule(atruleName, fallbackBasename);
|
||||
|
||||
return (atrule && atrule.prelude) || null;
|
||||
}
|
||||
getAtruleDescriptor(atruleName, name) {
|
||||
return this.atrules.hasOwnProperty(atruleName) && this.atrules.declarators ?
|
||||
this.atrules[atruleName].declarators[name] || null
|
||||
: null;
|
||||
}
|
||||
getProperty(propertyName, fallbackBasename = true) {
|
||||
const property = names.property(propertyName);
|
||||
const propertyEntry =
|
||||
property.vendor && fallbackBasename ?
|
||||
this.properties[property.name] || this.properties[property.basename]
|
||||
: this.properties[property.name];
|
||||
|
||||
return propertyEntry || null;
|
||||
}
|
||||
getType(name) {
|
||||
return hasOwnProperty.call(this.types, name) ? this.types[name] : null;
|
||||
}
|
||||
|
||||
validate() {
|
||||
function validate(syntax, name, broken, descriptor) {
|
||||
if (broken.has(name)) {
|
||||
return broken.get(name);
|
||||
}
|
||||
|
||||
broken.set(name, false);
|
||||
if (descriptor.syntax !== null) {
|
||||
walk(
|
||||
descriptor.syntax,
|
||||
function (node) {
|
||||
if (node.type !== 'Type' && node.type !== 'Property') {
|
||||
return;
|
||||
}
|
||||
|
||||
broken.set(name, false);
|
||||
if (descriptor.syntax !== null) {
|
||||
walk(descriptor.syntax, function(node) {
|
||||
if (node.type !== 'Type' && node.type !== 'Property') {
|
||||
return;
|
||||
}
|
||||
const map = node.type === 'Type' ? syntax.types : syntax.properties;
|
||||
const brokenMap =
|
||||
node.type === 'Type' ? brokenTypes : brokenProperties;
|
||||
|
||||
const map = node.type === 'Type' ? syntax.types : syntax.properties;
|
||||
const brokenMap = node.type === 'Type' ? brokenTypes : brokenProperties;
|
||||
|
||||
if (!hasOwnProperty.call(map, node.name) || validate(syntax, node.name, brokenMap, map[node.name])) {
|
||||
broken.set(name, true);
|
||||
}
|
||||
}, this);
|
||||
if (
|
||||
!hasOwnProperty.call(map, node.name) ||
|
||||
validate(syntax, node.name, brokenMap, map[node.name])
|
||||
) {
|
||||
broken.set(name, true);
|
||||
}
|
||||
}
|
||||
|
||||
let brokenTypes = new Map();
|
||||
let brokenProperties = new Map();
|
||||
|
||||
for (const key in this.types) {
|
||||
validate(this, key, brokenTypes, this.types[key]);
|
||||
}
|
||||
|
||||
for (const key in this.properties) {
|
||||
validate(this, key, brokenProperties, this.properties[key]);
|
||||
}
|
||||
|
||||
brokenTypes = [...brokenTypes.keys()].filter(name => brokenTypes.get(name));
|
||||
brokenProperties = [...brokenProperties.keys()].filter(name => brokenProperties.get(name));
|
||||
|
||||
if (brokenTypes.length || brokenProperties.length) {
|
||||
return {
|
||||
types: brokenTypes,
|
||||
properties: brokenProperties
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
this
|
||||
);
|
||||
}
|
||||
}
|
||||
dump(syntaxAsAst, pretty) {
|
||||
return {
|
||||
generic: this.generic,
|
||||
types: dumpMapSyntax(this.types, !pretty, syntaxAsAst),
|
||||
properties: dumpMapSyntax(this.properties, !pretty, syntaxAsAst),
|
||||
atrules: dumpAtruleMapSyntax(this.atrules, !pretty, syntaxAsAst)
|
||||
};
|
||||
|
||||
let brokenTypes = new Map();
|
||||
let brokenProperties = new Map();
|
||||
|
||||
for (const key in this.types) {
|
||||
validate(this, key, brokenTypes, this.types[key]);
|
||||
}
|
||||
toString() {
|
||||
return JSON.stringify(this.dump());
|
||||
|
||||
for (const key in this.properties) {
|
||||
validate(this, key, brokenProperties, this.properties[key]);
|
||||
}
|
||||
};
|
||||
|
||||
brokenTypes = [...brokenTypes.keys()].filter((name) =>
|
||||
brokenTypes.get(name)
|
||||
);
|
||||
brokenProperties = [...brokenProperties.keys()].filter((name) =>
|
||||
brokenProperties.get(name)
|
||||
);
|
||||
|
||||
if (brokenTypes.length || brokenProperties.length) {
|
||||
return {
|
||||
types: brokenTypes,
|
||||
properties: brokenProperties,
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
dump(syntaxAsAst, pretty) {
|
||||
return {
|
||||
generic: this.generic,
|
||||
types: dumpMapSyntax(this.types, !pretty, syntaxAsAst),
|
||||
properties: dumpMapSyntax(this.properties, !pretty, syntaxAsAst),
|
||||
atrules: dumpAtruleMapSyntax(this.atrules, !pretty, syntaxAsAst),
|
||||
};
|
||||
}
|
||||
toString() {
|
||||
return JSON.stringify(this.dump());
|
||||
}
|
||||
}
|
||||
|
193
node_modules/css-tree/lib/lexer/error.js
generated
vendored
193
node_modules/css-tree/lib/lexer/error.js
generated
vendored
@ -4,120 +4,133 @@ import { generate } from '../definition-syntax/generate.js';
|
||||
const defaultLoc = { offset: 0, line: 1, column: 1 };
|
||||
|
||||
function locateMismatch(matchResult, node) {
|
||||
const tokens = matchResult.tokens;
|
||||
const longestMatch = matchResult.longestMatch;
|
||||
const mismatchNode = longestMatch < tokens.length ? tokens[longestMatch].node || null : null;
|
||||
const badNode = mismatchNode !== node ? mismatchNode : null;
|
||||
let mismatchOffset = 0;
|
||||
let mismatchLength = 0;
|
||||
let entries = 0;
|
||||
let css = '';
|
||||
let start;
|
||||
let end;
|
||||
const tokens = matchResult.tokens;
|
||||
const longestMatch = matchResult.longestMatch;
|
||||
const mismatchNode =
|
||||
longestMatch < tokens.length ? tokens[longestMatch].node || null : null;
|
||||
const badNode = mismatchNode !== node ? mismatchNode : null;
|
||||
let mismatchOffset = 0;
|
||||
let mismatchLength = 0;
|
||||
let entries = 0;
|
||||
let css = '';
|
||||
let start;
|
||||
let end;
|
||||
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i].value;
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i].value;
|
||||
|
||||
if (i === longestMatch) {
|
||||
mismatchLength = token.length;
|
||||
mismatchOffset = css.length;
|
||||
}
|
||||
|
||||
if (badNode !== null && tokens[i].node === badNode) {
|
||||
if (i <= longestMatch) {
|
||||
entries++;
|
||||
} else {
|
||||
entries = 0;
|
||||
}
|
||||
}
|
||||
|
||||
css += token;
|
||||
if (i === longestMatch) {
|
||||
mismatchLength = token.length;
|
||||
mismatchOffset = css.length;
|
||||
}
|
||||
|
||||
if (longestMatch === tokens.length || entries > 1) { // last
|
||||
start = fromLoc(badNode || node, 'end') || buildLoc(defaultLoc, css);
|
||||
end = buildLoc(start);
|
||||
} else {
|
||||
start = fromLoc(badNode, 'start') ||
|
||||
buildLoc(fromLoc(node, 'start') || defaultLoc, css.slice(0, mismatchOffset));
|
||||
end = fromLoc(badNode, 'end') ||
|
||||
buildLoc(start, css.substr(mismatchOffset, mismatchLength));
|
||||
if (badNode !== null && tokens[i].node === badNode) {
|
||||
if (i <= longestMatch) {
|
||||
entries++;
|
||||
} else {
|
||||
entries = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
css,
|
||||
mismatchOffset,
|
||||
mismatchLength,
|
||||
start,
|
||||
end
|
||||
};
|
||||
css += token;
|
||||
}
|
||||
|
||||
if (longestMatch === tokens.length || entries > 1) {
|
||||
// last
|
||||
start = fromLoc(badNode || node, 'end') || buildLoc(defaultLoc, css);
|
||||
end = buildLoc(start);
|
||||
} else {
|
||||
start =
|
||||
fromLoc(badNode, 'start') ||
|
||||
buildLoc(
|
||||
fromLoc(node, 'start') || defaultLoc,
|
||||
css.slice(0, mismatchOffset)
|
||||
);
|
||||
end =
|
||||
fromLoc(badNode, 'end') ||
|
||||
buildLoc(start, css.substr(mismatchOffset, mismatchLength));
|
||||
}
|
||||
|
||||
return {
|
||||
css,
|
||||
mismatchOffset,
|
||||
mismatchLength,
|
||||
start,
|
||||
end,
|
||||
};
|
||||
}
|
||||
|
||||
function fromLoc(node, point) {
|
||||
const value = node && node.loc && node.loc[point];
|
||||
const value = node && node.loc && node.loc[point];
|
||||
|
||||
if (value) {
|
||||
return 'line' in value ? buildLoc(value) : value;
|
||||
}
|
||||
if (value) {
|
||||
return 'line' in value ? buildLoc(value) : value;
|
||||
}
|
||||
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
function buildLoc({ offset, line, column }, extra) {
|
||||
const loc = {
|
||||
offset,
|
||||
line,
|
||||
column
|
||||
};
|
||||
const loc = {
|
||||
offset,
|
||||
line,
|
||||
column,
|
||||
};
|
||||
|
||||
if (extra) {
|
||||
const lines = extra.split(/\n|\r\n?|\f/);
|
||||
if (extra) {
|
||||
const lines = extra.split(/\n|\r\n?|\f/);
|
||||
|
||||
loc.offset += extra.length;
|
||||
loc.line += lines.length - 1;
|
||||
loc.column = lines.length === 1 ? loc.column + extra.length : lines.pop().length + 1;
|
||||
}
|
||||
loc.offset += extra.length;
|
||||
loc.line += lines.length - 1;
|
||||
loc.column =
|
||||
lines.length === 1 ? loc.column + extra.length : lines.pop().length + 1;
|
||||
}
|
||||
|
||||
return loc;
|
||||
return loc;
|
||||
}
|
||||
|
||||
export const SyntaxReferenceError = function(type, referenceName) {
|
||||
const error = createCustomError(
|
||||
'SyntaxReferenceError',
|
||||
type + (referenceName ? ' `' + referenceName + '`' : '')
|
||||
);
|
||||
export const SyntaxReferenceError = function (type, referenceName) {
|
||||
const error = createCustomError(
|
||||
'SyntaxReferenceError',
|
||||
type + (referenceName ? ' `' + referenceName + '`' : '')
|
||||
);
|
||||
|
||||
error.reference = referenceName;
|
||||
error.reference = referenceName;
|
||||
|
||||
return error;
|
||||
return error;
|
||||
};
|
||||
|
||||
export const SyntaxMatchError = function(message, syntax, node, matchResult) {
|
||||
const error = createCustomError('SyntaxMatchError', message);
|
||||
const {
|
||||
css,
|
||||
mismatchOffset,
|
||||
mismatchLength,
|
||||
start,
|
||||
end
|
||||
} = locateMismatch(matchResult, node);
|
||||
export const SyntaxMatchError = function (message, syntax, node, matchResult) {
|
||||
const error = createCustomError('SyntaxMatchError', message);
|
||||
const { css, mismatchOffset, mismatchLength, start, end } = locateMismatch(
|
||||
matchResult,
|
||||
node
|
||||
);
|
||||
|
||||
error.rawMessage = message;
|
||||
error.syntax = syntax ? generate(syntax) : '<generic>';
|
||||
error.css = css;
|
||||
error.mismatchOffset = mismatchOffset;
|
||||
error.mismatchLength = mismatchLength;
|
||||
error.message = message + '\n' +
|
||||
' syntax: ' + error.syntax + '\n' +
|
||||
' value: ' + (css || '<empty string>') + '\n' +
|
||||
' --------' + new Array(error.mismatchOffset + 1).join('-') + '^';
|
||||
error.rawMessage = message;
|
||||
error.syntax = syntax ? generate(syntax) : '<generic>';
|
||||
error.css = css;
|
||||
error.mismatchOffset = mismatchOffset;
|
||||
error.mismatchLength = mismatchLength;
|
||||
error.message =
|
||||
message +
|
||||
'\n' +
|
||||
' syntax: ' +
|
||||
error.syntax +
|
||||
'\n' +
|
||||
' value: ' +
|
||||
(css || '<empty string>') +
|
||||
'\n' +
|
||||
' --------' +
|
||||
new Array(error.mismatchOffset + 1).join('-') +
|
||||
'^';
|
||||
|
||||
Object.assign(error, start);
|
||||
error.loc = {
|
||||
source: (node && node.loc && node.loc.source) || '<unknown>',
|
||||
start,
|
||||
end
|
||||
};
|
||||
Object.assign(error, start);
|
||||
error.loc = {
|
||||
source: (node && node.loc && node.loc.source) || '<unknown>',
|
||||
start,
|
||||
end,
|
||||
};
|
||||
|
||||
return error;
|
||||
return error;
|
||||
};
|
||||
|
374
node_modules/css-tree/lib/lexer/generic-an-plus-b.js
generated
vendored
374
node_modules/css-tree/lib/lexer/generic-an-plus-b.js
generated
vendored
@ -1,238 +1,246 @@
|
||||
import {
|
||||
isDigit,
|
||||
cmpChar,
|
||||
Delim,
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
Ident,
|
||||
Number as NumberToken,
|
||||
Dimension
|
||||
isDigit,
|
||||
cmpChar,
|
||||
Delim,
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
Ident,
|
||||
Number as NumberToken,
|
||||
Dimension,
|
||||
} from '../tokenizer/index.js';
|
||||
|
||||
const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
|
||||
const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)
|
||||
const N = 0x006E; // U+006E LATIN SMALL LETTER N (n)
|
||||
const PLUSSIGN = 0x002b; // U+002B PLUS SIGN (+)
|
||||
const HYPHENMINUS = 0x002d; // U+002D HYPHEN-MINUS (-)
|
||||
const N = 0x006e; // U+006E LATIN SMALL LETTER N (n)
|
||||
const DISALLOW_SIGN = true;
|
||||
const ALLOW_SIGN = false;
|
||||
|
||||
function isDelim(token, code) {
|
||||
return token !== null && token.type === Delim && token.value.charCodeAt(0) === code;
|
||||
return (
|
||||
token !== null && token.type === Delim && token.value.charCodeAt(0) === code
|
||||
);
|
||||
}
|
||||
|
||||
function skipSC(token, offset, getNextToken) {
|
||||
while (token !== null && (token.type === WhiteSpace || token.type === Comment)) {
|
||||
token = getNextToken(++offset);
|
||||
}
|
||||
while (
|
||||
token !== null &&
|
||||
(token.type === WhiteSpace || token.type === Comment)
|
||||
) {
|
||||
token = getNextToken(++offset);
|
||||
}
|
||||
|
||||
return offset;
|
||||
return offset;
|
||||
}
|
||||
|
||||
function checkInteger(token, valueOffset, disallowSign, offset) {
|
||||
if (!token) {
|
||||
return 0;
|
||||
if (!token) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const code = token.value.charCodeAt(valueOffset);
|
||||
|
||||
if (code === PLUSSIGN || code === HYPHENMINUS) {
|
||||
if (disallowSign) {
|
||||
// Number sign is not allowed
|
||||
return 0;
|
||||
}
|
||||
valueOffset++;
|
||||
}
|
||||
|
||||
const code = token.value.charCodeAt(valueOffset);
|
||||
|
||||
if (code === PLUSSIGN || code === HYPHENMINUS) {
|
||||
if (disallowSign) {
|
||||
// Number sign is not allowed
|
||||
return 0;
|
||||
}
|
||||
valueOffset++;
|
||||
for (; valueOffset < token.value.length; valueOffset++) {
|
||||
if (!isDigit(token.value.charCodeAt(valueOffset))) {
|
||||
// Integer is expected
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (; valueOffset < token.value.length; valueOffset++) {
|
||||
if (!isDigit(token.value.charCodeAt(valueOffset))) {
|
||||
// Integer is expected
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return offset + 1;
|
||||
return offset + 1;
|
||||
}
|
||||
|
||||
// ... <signed-integer>
|
||||
// ... ['+' | '-'] <signless-integer>
|
||||
function consumeB(token, offset_, getNextToken) {
|
||||
let sign = false;
|
||||
let offset = skipSC(token, offset_, getNextToken);
|
||||
let sign = false;
|
||||
let offset = skipSC(token, offset_, getNextToken);
|
||||
|
||||
token = getNextToken(offset);
|
||||
token = getNextToken(offset);
|
||||
|
||||
if (token === null) {
|
||||
return offset_;
|
||||
if (token === null) {
|
||||
return offset_;
|
||||
}
|
||||
|
||||
if (token.type !== NumberToken) {
|
||||
if (isDelim(token, PLUSSIGN) || isDelim(token, HYPHENMINUS)) {
|
||||
sign = true;
|
||||
offset = skipSC(getNextToken(++offset), offset, getNextToken);
|
||||
token = getNextToken(offset);
|
||||
|
||||
if (token === null || token.type !== NumberToken) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return offset_;
|
||||
}
|
||||
}
|
||||
|
||||
if (token.type !== NumberToken) {
|
||||
if (isDelim(token, PLUSSIGN) || isDelim(token, HYPHENMINUS)) {
|
||||
sign = true;
|
||||
offset = skipSC(getNextToken(++offset), offset, getNextToken);
|
||||
token = getNextToken(offset);
|
||||
|
||||
if (token === null || token.type !== NumberToken) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return offset_;
|
||||
}
|
||||
if (!sign) {
|
||||
const code = token.value.charCodeAt(0);
|
||||
if (code !== PLUSSIGN && code !== HYPHENMINUS) {
|
||||
// Number sign is expected
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sign) {
|
||||
const code = token.value.charCodeAt(0);
|
||||
if (code !== PLUSSIGN && code !== HYPHENMINUS) {
|
||||
// Number sign is expected
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return checkInteger(token, sign ? 0 : 1, sign, offset);
|
||||
return checkInteger(token, sign ? 0 : 1, sign, offset);
|
||||
}
|
||||
|
||||
// An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
|
||||
export default function anPlusB(token, getNextToken) {
|
||||
/* eslint-disable brace-style*/
|
||||
let offset = 0;
|
||||
/* eslint-disable brace-style*/
|
||||
let offset = 0;
|
||||
|
||||
if (!token) {
|
||||
return 0;
|
||||
if (!token) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// <integer>
|
||||
if (token.type === NumberToken) {
|
||||
return checkInteger(token, 0, ALLOW_SIGN, offset); // b
|
||||
}
|
||||
|
||||
// -n
|
||||
// -n <signed-integer>
|
||||
// -n ['+' | '-'] <signless-integer>
|
||||
// -n- <signless-integer>
|
||||
// <dashndashdigit-ident>
|
||||
else if (token.type === Ident && token.value.charCodeAt(0) === HYPHENMINUS) {
|
||||
// expect 1st char is N
|
||||
if (!cmpChar(token.value, 1, N)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// <integer>
|
||||
if (token.type === NumberToken) {
|
||||
return checkInteger(token, 0, ALLOW_SIGN, offset); // b
|
||||
switch (token.value.length) {
|
||||
// -n
|
||||
// -n <signed-integer>
|
||||
// -n ['+' | '-'] <signless-integer>
|
||||
case 2:
|
||||
return consumeB(getNextToken(++offset), offset, getNextToken);
|
||||
|
||||
// -n- <signless-integer>
|
||||
case 3:
|
||||
if (token.value.charCodeAt(2) !== HYPHENMINUS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
offset = skipSC(getNextToken(++offset), offset, getNextToken);
|
||||
token = getNextToken(offset);
|
||||
|
||||
return checkInteger(token, 0, DISALLOW_SIGN, offset);
|
||||
|
||||
// <dashndashdigit-ident>
|
||||
default:
|
||||
if (token.value.charCodeAt(2) !== HYPHENMINUS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return checkInteger(token, 3, DISALLOW_SIGN, offset);
|
||||
}
|
||||
}
|
||||
|
||||
// '+'? n
|
||||
// '+'? n <signed-integer>
|
||||
// '+'? n ['+' | '-'] <signless-integer>
|
||||
// '+'? n- <signless-integer>
|
||||
// '+'? <ndashdigit-ident>
|
||||
else if (
|
||||
token.type === Ident ||
|
||||
(isDelim(token, PLUSSIGN) && getNextToken(offset + 1).type === Ident)
|
||||
) {
|
||||
// just ignore a plus
|
||||
if (token.type !== Ident) {
|
||||
token = getNextToken(++offset);
|
||||
}
|
||||
|
||||
// -n
|
||||
// -n <signed-integer>
|
||||
// -n ['+' | '-'] <signless-integer>
|
||||
// -n- <signless-integer>
|
||||
// <dashndashdigit-ident>
|
||||
else if (token.type === Ident && token.value.charCodeAt(0) === HYPHENMINUS) {
|
||||
// expect 1st char is N
|
||||
if (!cmpChar(token.value, 1, N)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (token.value.length) {
|
||||
// -n
|
||||
// -n <signed-integer>
|
||||
// -n ['+' | '-'] <signless-integer>
|
||||
case 2:
|
||||
return consumeB(getNextToken(++offset), offset, getNextToken);
|
||||
|
||||
// -n- <signless-integer>
|
||||
case 3:
|
||||
if (token.value.charCodeAt(2) !== HYPHENMINUS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
offset = skipSC(getNextToken(++offset), offset, getNextToken);
|
||||
token = getNextToken(offset);
|
||||
|
||||
return checkInteger(token, 0, DISALLOW_SIGN, offset);
|
||||
|
||||
// <dashndashdigit-ident>
|
||||
default:
|
||||
if (token.value.charCodeAt(2) !== HYPHENMINUS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return checkInteger(token, 3, DISALLOW_SIGN, offset);
|
||||
}
|
||||
if (token === null || !cmpChar(token.value, 0, N)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// '+'? n
|
||||
// '+'? n <signed-integer>
|
||||
// '+'? n ['+' | '-'] <signless-integer>
|
||||
// '+'? n- <signless-integer>
|
||||
// '+'? <ndashdigit-ident>
|
||||
else if (token.type === Ident || (isDelim(token, PLUSSIGN) && getNextToken(offset + 1).type === Ident)) {
|
||||
// just ignore a plus
|
||||
if (token.type !== Ident) {
|
||||
token = getNextToken(++offset);
|
||||
switch (token.value.length) {
|
||||
// '+'? n
|
||||
// '+'? n <signed-integer>
|
||||
// '+'? n ['+' | '-'] <signless-integer>
|
||||
case 1:
|
||||
return consumeB(getNextToken(++offset), offset, getNextToken);
|
||||
|
||||
// '+'? n- <signless-integer>
|
||||
case 2:
|
||||
if (token.value.charCodeAt(1) !== HYPHENMINUS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (token === null || !cmpChar(token.value, 0, N)) {
|
||||
return 0;
|
||||
offset = skipSC(getNextToken(++offset), offset, getNextToken);
|
||||
token = getNextToken(offset);
|
||||
|
||||
return checkInteger(token, 0, DISALLOW_SIGN, offset);
|
||||
|
||||
// '+'? <ndashdigit-ident>
|
||||
default:
|
||||
if (token.value.charCodeAt(1) !== HYPHENMINUS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (token.value.length) {
|
||||
// '+'? n
|
||||
// '+'? n <signed-integer>
|
||||
// '+'? n ['+' | '-'] <signless-integer>
|
||||
case 1:
|
||||
return consumeB(getNextToken(++offset), offset, getNextToken);
|
||||
return checkInteger(token, 2, DISALLOW_SIGN, offset);
|
||||
}
|
||||
}
|
||||
|
||||
// '+'? n- <signless-integer>
|
||||
case 2:
|
||||
if (token.value.charCodeAt(1) !== HYPHENMINUS) {
|
||||
return 0;
|
||||
}
|
||||
// <ndashdigit-dimension>
|
||||
// <ndash-dimension> <signless-integer>
|
||||
// <n-dimension>
|
||||
// <n-dimension> <signed-integer>
|
||||
// <n-dimension> ['+' | '-'] <signless-integer>
|
||||
else if (token.type === Dimension) {
|
||||
let code = token.value.charCodeAt(0);
|
||||
let sign = code === PLUSSIGN || code === HYPHENMINUS ? 1 : 0;
|
||||
let i = sign;
|
||||
|
||||
offset = skipSC(getNextToken(++offset), offset, getNextToken);
|
||||
token = getNextToken(offset);
|
||||
|
||||
return checkInteger(token, 0, DISALLOW_SIGN, offset);
|
||||
|
||||
// '+'? <ndashdigit-ident>
|
||||
default:
|
||||
if (token.value.charCodeAt(1) !== HYPHENMINUS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return checkInteger(token, 2, DISALLOW_SIGN, offset);
|
||||
}
|
||||
for (; i < token.value.length; i++) {
|
||||
if (!isDigit(token.value.charCodeAt(i))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i === sign) {
|
||||
// Integer is expected
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!cmpChar(token.value, i, N)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// <ndashdigit-dimension>
|
||||
// <ndash-dimension> <signless-integer>
|
||||
// <n-dimension>
|
||||
// <n-dimension> <signed-integer>
|
||||
// <n-dimension> ['+' | '-'] <signless-integer>
|
||||
else if (token.type === Dimension) {
|
||||
let code = token.value.charCodeAt(0);
|
||||
let sign = code === PLUSSIGN || code === HYPHENMINUS ? 1 : 0;
|
||||
let i = sign;
|
||||
if (i + 1 === token.value.length) {
|
||||
return consumeB(getNextToken(++offset), offset, getNextToken);
|
||||
} else {
|
||||
if (token.value.charCodeAt(i + 1) !== HYPHENMINUS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (; i < token.value.length; i++) {
|
||||
if (!isDigit(token.value.charCodeAt(i))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// <ndash-dimension> <signless-integer>
|
||||
if (i + 2 === token.value.length) {
|
||||
offset = skipSC(getNextToken(++offset), offset, getNextToken);
|
||||
token = getNextToken(offset);
|
||||
|
||||
if (i === sign) {
|
||||
// Integer is expected
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!cmpChar(token.value, i, N)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// <n-dimension>
|
||||
// <n-dimension> <signed-integer>
|
||||
// <n-dimension> ['+' | '-'] <signless-integer>
|
||||
if (i + 1 === token.value.length) {
|
||||
return consumeB(getNextToken(++offset), offset, getNextToken);
|
||||
} else {
|
||||
if (token.value.charCodeAt(i + 1) !== HYPHENMINUS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// <ndash-dimension> <signless-integer>
|
||||
if (i + 2 === token.value.length) {
|
||||
offset = skipSC(getNextToken(++offset), offset, getNextToken);
|
||||
token = getNextToken(offset);
|
||||
|
||||
return checkInteger(token, 0, DISALLOW_SIGN, offset);
|
||||
}
|
||||
// <ndashdigit-dimension>
|
||||
else {
|
||||
return checkInteger(token, i + 2, DISALLOW_SIGN, offset);
|
||||
}
|
||||
}
|
||||
return checkInteger(token, 0, DISALLOW_SIGN, offset);
|
||||
}
|
||||
// <ndashdigit-dimension>
|
||||
else {
|
||||
return checkInteger(token, i + 2, DISALLOW_SIGN, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
10
node_modules/css-tree/lib/lexer/generic-const.js
generated
vendored
10
node_modules/css-tree/lib/lexer/generic-const.js
generated
vendored
@ -1,8 +1,8 @@
|
||||
// https://drafts.csswg.org/css-cascade-5/
|
||||
export const cssWideKeywords = [
|
||||
'initial',
|
||||
'inherit',
|
||||
'unset',
|
||||
'revert',
|
||||
'revert-layer'
|
||||
'initial',
|
||||
'inherit',
|
||||
'unset',
|
||||
'revert',
|
||||
'revert-layer',
|
||||
];
|
||||
|
200
node_modules/css-tree/lib/lexer/generic-urange.js
generated
vendored
200
node_modules/css-tree/lib/lexer/generic-urange.js
generated
vendored
@ -1,62 +1,64 @@
|
||||
import {
|
||||
isHexDigit,
|
||||
cmpChar,
|
||||
Ident,
|
||||
Delim,
|
||||
Number as NumberToken,
|
||||
Dimension
|
||||
isHexDigit,
|
||||
cmpChar,
|
||||
Ident,
|
||||
Delim,
|
||||
Number as NumberToken,
|
||||
Dimension,
|
||||
} from '../tokenizer/index.js';
|
||||
|
||||
const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
|
||||
const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)
|
||||
const QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?)
|
||||
const U = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
|
||||
const PLUSSIGN = 0x002b; // U+002B PLUS SIGN (+)
|
||||
const HYPHENMINUS = 0x002d; // U+002D HYPHEN-MINUS (-)
|
||||
const QUESTIONMARK = 0x003f; // U+003F QUESTION MARK (?)
|
||||
const U = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
|
||||
|
||||
function isDelim(token, code) {
|
||||
return token !== null && token.type === Delim && token.value.charCodeAt(0) === code;
|
||||
return (
|
||||
token !== null && token.type === Delim && token.value.charCodeAt(0) === code
|
||||
);
|
||||
}
|
||||
|
||||
function startsWith(token, code) {
|
||||
return token.value.charCodeAt(0) === code;
|
||||
return token.value.charCodeAt(0) === code;
|
||||
}
|
||||
|
||||
function hexSequence(token, offset, allowDash) {
|
||||
let hexlen = 0;
|
||||
let hexlen = 0;
|
||||
|
||||
for (let pos = offset; pos < token.value.length; pos++) {
|
||||
const code = token.value.charCodeAt(pos);
|
||||
for (let pos = offset; pos < token.value.length; pos++) {
|
||||
const code = token.value.charCodeAt(pos);
|
||||
|
||||
if (code === HYPHENMINUS && allowDash && hexlen !== 0) {
|
||||
hexSequence(token, offset + hexlen + 1, false);
|
||||
return 6; // dissallow following question marks
|
||||
}
|
||||
|
||||
if (!isHexDigit(code)) {
|
||||
return 0; // not a hex digit
|
||||
}
|
||||
|
||||
if (++hexlen > 6) {
|
||||
return 0; // too many hex digits
|
||||
};
|
||||
if (code === HYPHENMINUS && allowDash && hexlen !== 0) {
|
||||
hexSequence(token, offset + hexlen + 1, false);
|
||||
return 6; // dissallow following question marks
|
||||
}
|
||||
|
||||
return hexlen;
|
||||
if (!isHexDigit(code)) {
|
||||
return 0; // not a hex digit
|
||||
}
|
||||
|
||||
if (++hexlen > 6) {
|
||||
return 0; // too many hex digits
|
||||
}
|
||||
}
|
||||
|
||||
return hexlen;
|
||||
}
|
||||
|
||||
function withQuestionMarkSequence(consumed, length, getNextToken) {
|
||||
if (!consumed) {
|
||||
return 0; // nothing consumed
|
||||
if (!consumed) {
|
||||
return 0; // nothing consumed
|
||||
}
|
||||
|
||||
while (isDelim(getNextToken(length), QUESTIONMARK)) {
|
||||
if (++consumed > 6) {
|
||||
return 0; // too many question marks
|
||||
}
|
||||
|
||||
while (isDelim(getNextToken(length), QUESTIONMARK)) {
|
||||
if (++consumed > 6) {
|
||||
return 0; // too many question marks
|
||||
}
|
||||
length++;
|
||||
}
|
||||
|
||||
length++;
|
||||
}
|
||||
|
||||
return length;
|
||||
return length;
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-syntax/#urange
|
||||
@ -79,73 +81,81 @@ function withQuestionMarkSequence(consumed, length, getNextToken) {
|
||||
// u <number-token> <number-token> |
|
||||
// u '+' '?'+
|
||||
export default function urange(token, getNextToken) {
|
||||
let length = 0;
|
||||
let length = 0;
|
||||
|
||||
// should start with `u` or `U`
|
||||
if (token === null || token.type !== Ident || !cmpChar(token.value, 0, U)) {
|
||||
return 0;
|
||||
// should start with `u` or `U`
|
||||
if (token === null || token.type !== Ident || !cmpChar(token.value, 0, U)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
token = getNextToken(++length);
|
||||
if (token === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// u '+' <ident-token> '?'*
|
||||
// u '+' '?'+
|
||||
if (isDelim(token, PLUSSIGN)) {
|
||||
token = getNextToken(++length);
|
||||
if (token === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (token.type === Ident) {
|
||||
// u '+' <ident-token> '?'*
|
||||
return withQuestionMarkSequence(
|
||||
hexSequence(token, 0, true),
|
||||
++length,
|
||||
getNextToken
|
||||
);
|
||||
}
|
||||
|
||||
if (isDelim(token, QUESTIONMARK)) {
|
||||
// u '+' '?'+
|
||||
return withQuestionMarkSequence(1, ++length, getNextToken);
|
||||
}
|
||||
|
||||
// Hex digit or question mark is expected
|
||||
return 0;
|
||||
}
|
||||
|
||||
// u <number-token> '?'*
|
||||
// u <number-token> <dimension-token>
|
||||
// u <number-token> <number-token>
|
||||
if (token.type === NumberToken) {
|
||||
const consumedHexLength = hexSequence(token, 1, true);
|
||||
if (consumedHexLength === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
token = getNextToken(++length);
|
||||
if (token === null) {
|
||||
return 0;
|
||||
// u <number-token> <eof>
|
||||
return length;
|
||||
}
|
||||
|
||||
// u '+' <ident-token> '?'*
|
||||
// u '+' '?'+
|
||||
if (isDelim(token, PLUSSIGN)) {
|
||||
token = getNextToken(++length);
|
||||
if (token === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (token.type === Ident) {
|
||||
// u '+' <ident-token> '?'*
|
||||
return withQuestionMarkSequence(hexSequence(token, 0, true), ++length, getNextToken);
|
||||
}
|
||||
|
||||
if (isDelim(token, QUESTIONMARK)) {
|
||||
// u '+' '?'+
|
||||
return withQuestionMarkSequence(1, ++length, getNextToken);
|
||||
}
|
||||
|
||||
// Hex digit or question mark is expected
|
||||
if (token.type === Dimension || token.type === NumberToken) {
|
||||
// u <number-token> <dimension-token>
|
||||
// u <number-token> <number-token>
|
||||
if (!startsWith(token, HYPHENMINUS) || !hexSequence(token, 1, false)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return length + 1;
|
||||
}
|
||||
|
||||
// u <number-token> '?'*
|
||||
// u <number-token> <dimension-token>
|
||||
// u <number-token> <number-token>
|
||||
if (token.type === NumberToken) {
|
||||
const consumedHexLength = hexSequence(token, 1, true);
|
||||
if (consumedHexLength === 0) {
|
||||
return 0;
|
||||
}
|
||||
return withQuestionMarkSequence(consumedHexLength, length, getNextToken);
|
||||
}
|
||||
|
||||
token = getNextToken(++length);
|
||||
if (token === null) {
|
||||
// u <number-token> <eof>
|
||||
return length;
|
||||
}
|
||||
// u <dimension-token> '?'*
|
||||
if (token.type === Dimension) {
|
||||
return withQuestionMarkSequence(
|
||||
hexSequence(token, 1, true),
|
||||
++length,
|
||||
getNextToken
|
||||
);
|
||||
}
|
||||
|
||||
if (token.type === Dimension || token.type === NumberToken) {
|
||||
// u <number-token> <dimension-token>
|
||||
// u <number-token> <number-token>
|
||||
if (!startsWith(token, HYPHENMINUS) || !hexSequence(token, 1, false)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return length + 1;
|
||||
}
|
||||
|
||||
// u <number-token> '?'*
|
||||
return withQuestionMarkSequence(consumedHexLength, length, getNextToken);
|
||||
}
|
||||
|
||||
// u <dimension-token> '?'*
|
||||
if (token.type === Dimension) {
|
||||
return withQuestionMarkSequence(hexSequence(token, 1, true), ++length, getNextToken);
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
874
node_modules/css-tree/lib/lexer/generic.js
generated
vendored
874
node_modules/css-tree/lib/lexer/generic.js
generated
vendored
File diff suppressed because it is too large
Load Diff
775
node_modules/css-tree/lib/lexer/match-graph.js
generated
vendored
775
node_modules/css-tree/lib/lexer/match-graph.js
generated
vendored
@ -4,453 +4,420 @@ export const MATCH = { type: 'Match' };
|
||||
export const MISMATCH = { type: 'Mismatch' };
|
||||
export const DISALLOW_EMPTY = { type: 'DisallowEmpty' };
|
||||
|
||||
const LEFTPARENTHESIS = 40; // (
|
||||
const LEFTPARENTHESIS = 40; // (
|
||||
const RIGHTPARENTHESIS = 41; // )
|
||||
|
||||
function createCondition(match, thenBranch, elseBranch) {
|
||||
// reduce node count
|
||||
if (thenBranch === MATCH && elseBranch === MISMATCH) {
|
||||
return match;
|
||||
}
|
||||
// reduce node count
|
||||
if (thenBranch === MATCH && elseBranch === MISMATCH) {
|
||||
return match;
|
||||
}
|
||||
|
||||
if (match === MATCH && thenBranch === MATCH && elseBranch === MATCH) {
|
||||
return match;
|
||||
}
|
||||
if (match === MATCH && thenBranch === MATCH && elseBranch === MATCH) {
|
||||
return match;
|
||||
}
|
||||
|
||||
if (match.type === 'If' && match.else === MISMATCH && thenBranch === MATCH) {
|
||||
thenBranch = match.then;
|
||||
match = match.match;
|
||||
}
|
||||
if (match.type === 'If' && match.else === MISMATCH && thenBranch === MATCH) {
|
||||
thenBranch = match.then;
|
||||
match = match.match;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'If',
|
||||
match,
|
||||
then: thenBranch,
|
||||
else: elseBranch
|
||||
};
|
||||
return {
|
||||
type: 'If',
|
||||
match,
|
||||
then: thenBranch,
|
||||
else: elseBranch,
|
||||
};
|
||||
}
|
||||
|
||||
function isFunctionType(name) {
|
||||
return (
|
||||
name.length > 2 &&
|
||||
name.charCodeAt(name.length - 2) === LEFTPARENTHESIS &&
|
||||
name.charCodeAt(name.length - 1) === RIGHTPARENTHESIS
|
||||
);
|
||||
return (
|
||||
name.length > 2 &&
|
||||
name.charCodeAt(name.length - 2) === LEFTPARENTHESIS &&
|
||||
name.charCodeAt(name.length - 1) === RIGHTPARENTHESIS
|
||||
);
|
||||
}
|
||||
|
||||
function isEnumCapatible(term) {
|
||||
return (
|
||||
term.type === 'Keyword' ||
|
||||
term.type === 'AtKeyword' ||
|
||||
term.type === 'Function' ||
|
||||
term.type === 'Type' && isFunctionType(term.name)
|
||||
);
|
||||
return (
|
||||
term.type === 'Keyword' ||
|
||||
term.type === 'AtKeyword' ||
|
||||
term.type === 'Function' ||
|
||||
(term.type === 'Type' && isFunctionType(term.name))
|
||||
);
|
||||
}
|
||||
|
||||
function buildGroupMatchGraph(combinator, terms, atLeastOneTermMatched) {
|
||||
switch (combinator) {
|
||||
case ' ': {
|
||||
// Juxtaposing components means that all of them must occur, in the given order.
|
||||
//
|
||||
// a b c
|
||||
// =
|
||||
// match a
|
||||
// then match b
|
||||
// then match c
|
||||
// then MATCH
|
||||
// else MISMATCH
|
||||
// else MISMATCH
|
||||
// else MISMATCH
|
||||
let result = MATCH;
|
||||
switch (combinator) {
|
||||
case ' ': {
|
||||
// Juxtaposing components means that all of them must occur, in the given order.
|
||||
//
|
||||
// a b c
|
||||
// =
|
||||
// match a
|
||||
// then match b
|
||||
// then match c
|
||||
// then MATCH
|
||||
// else MISMATCH
|
||||
// else MISMATCH
|
||||
// else MISMATCH
|
||||
let result = MATCH;
|
||||
|
||||
for (let i = terms.length - 1; i >= 0; i--) {
|
||||
const term = terms[i];
|
||||
for (let i = terms.length - 1; i >= 0; i--) {
|
||||
const term = terms[i];
|
||||
|
||||
result = createCondition(
|
||||
term,
|
||||
result,
|
||||
MISMATCH
|
||||
);
|
||||
};
|
||||
result = createCondition(term, result, MISMATCH);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
case '|': {
|
||||
// A bar (|) separates two or more alternatives: exactly one of them must occur.
|
||||
//
|
||||
// a | b | c
|
||||
// =
|
||||
// match a
|
||||
// then MATCH
|
||||
// else match b
|
||||
// then MATCH
|
||||
// else match c
|
||||
// then MATCH
|
||||
// else MISMATCH
|
||||
|
||||
let result = MISMATCH;
|
||||
let map = null;
|
||||
|
||||
for (let i = terms.length - 1; i >= 0; i--) {
|
||||
let term = terms[i];
|
||||
|
||||
// reduce sequence of keywords into a Enum
|
||||
if (isEnumCapatible(term)) {
|
||||
if (map === null && i > 0 && isEnumCapatible(terms[i - 1])) {
|
||||
map = Object.create(null);
|
||||
result = createCondition(
|
||||
{
|
||||
type: 'Enum',
|
||||
map
|
||||
},
|
||||
MATCH,
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
if (map !== null) {
|
||||
const key = (isFunctionType(term.name) ? term.name.slice(0, -1) : term.name).toLowerCase();
|
||||
if (key in map === false) {
|
||||
map[key] = term;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map = null;
|
||||
|
||||
// create a new conditonal node
|
||||
result = createCondition(
|
||||
term,
|
||||
MATCH,
|
||||
result
|
||||
);
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
case '&&': {
|
||||
// A double ampersand (&&) separates two or more components,
|
||||
// all of which must occur, in any order.
|
||||
|
||||
// Use MatchOnce for groups with a large number of terms,
|
||||
// since &&-groups produces at least N!-node trees
|
||||
if (terms.length > 5) {
|
||||
return {
|
||||
type: 'MatchOnce',
|
||||
terms,
|
||||
all: true
|
||||
};
|
||||
}
|
||||
|
||||
// Use a combination tree for groups with small number of terms
|
||||
//
|
||||
// a && b && c
|
||||
// =
|
||||
// match a
|
||||
// then [b && c]
|
||||
// else match b
|
||||
// then [a && c]
|
||||
// else match c
|
||||
// then [a && b]
|
||||
// else MISMATCH
|
||||
//
|
||||
// a && b
|
||||
// =
|
||||
// match a
|
||||
// then match b
|
||||
// then MATCH
|
||||
// else MISMATCH
|
||||
// else match b
|
||||
// then match a
|
||||
// then MATCH
|
||||
// else MISMATCH
|
||||
// else MISMATCH
|
||||
let result = MISMATCH;
|
||||
|
||||
for (let i = terms.length - 1; i >= 0; i--) {
|
||||
const term = terms[i];
|
||||
let thenClause;
|
||||
|
||||
if (terms.length > 1) {
|
||||
thenClause = buildGroupMatchGraph(
|
||||
combinator,
|
||||
terms.filter(function(newGroupTerm) {
|
||||
return newGroupTerm !== term;
|
||||
}),
|
||||
false
|
||||
);
|
||||
} else {
|
||||
thenClause = MATCH;
|
||||
}
|
||||
|
||||
result = createCondition(
|
||||
term,
|
||||
thenClause,
|
||||
result
|
||||
);
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
case '||': {
|
||||
// A double bar (||) separates two or more options:
|
||||
// one or more of them must occur, in any order.
|
||||
|
||||
// Use MatchOnce for groups with a large number of terms,
|
||||
// since ||-groups produces at least N!-node trees
|
||||
if (terms.length > 5) {
|
||||
return {
|
||||
type: 'MatchOnce',
|
||||
terms,
|
||||
all: false
|
||||
};
|
||||
}
|
||||
|
||||
// Use a combination tree for groups with small number of terms
|
||||
//
|
||||
// a || b || c
|
||||
// =
|
||||
// match a
|
||||
// then [b || c]
|
||||
// else match b
|
||||
// then [a || c]
|
||||
// else match c
|
||||
// then [a || b]
|
||||
// else MISMATCH
|
||||
//
|
||||
// a || b
|
||||
// =
|
||||
// match a
|
||||
// then match b
|
||||
// then MATCH
|
||||
// else MATCH
|
||||
// else match b
|
||||
// then match a
|
||||
// then MATCH
|
||||
// else MATCH
|
||||
// else MISMATCH
|
||||
let result = atLeastOneTermMatched ? MATCH : MISMATCH;
|
||||
|
||||
for (let i = terms.length - 1; i >= 0; i--) {
|
||||
const term = terms[i];
|
||||
let thenClause;
|
||||
|
||||
if (terms.length > 1) {
|
||||
thenClause = buildGroupMatchGraph(
|
||||
combinator,
|
||||
terms.filter(function(newGroupTerm) {
|
||||
return newGroupTerm !== term;
|
||||
}),
|
||||
true
|
||||
);
|
||||
} else {
|
||||
thenClause = MATCH;
|
||||
}
|
||||
|
||||
result = createCondition(
|
||||
term,
|
||||
thenClause,
|
||||
result
|
||||
);
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
case '|': {
|
||||
// A bar (|) separates two or more alternatives: exactly one of them must occur.
|
||||
//
|
||||
// a | b | c
|
||||
// =
|
||||
// match a
|
||||
// then MATCH
|
||||
// else match b
|
||||
// then MATCH
|
||||
// else match c
|
||||
// then MATCH
|
||||
// else MISMATCH
|
||||
|
||||
let result = MISMATCH;
|
||||
let map = null;
|
||||
|
||||
for (let i = terms.length - 1; i >= 0; i--) {
|
||||
let term = terms[i];
|
||||
|
||||
// reduce sequence of keywords into a Enum
|
||||
if (isEnumCapatible(term)) {
|
||||
if (map === null && i > 0 && isEnumCapatible(terms[i - 1])) {
|
||||
map = Object.create(null);
|
||||
result = createCondition(
|
||||
{
|
||||
type: 'Enum',
|
||||
map,
|
||||
},
|
||||
MATCH,
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
if (map !== null) {
|
||||
const key = (
|
||||
isFunctionType(term.name) ?
|
||||
term.name.slice(0, -1)
|
||||
: term.name).toLowerCase();
|
||||
if (key in map === false) {
|
||||
map[key] = term;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map = null;
|
||||
|
||||
// create a new conditonal node
|
||||
result = createCondition(term, MATCH, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
case '&&': {
|
||||
// A double ampersand (&&) separates two or more components,
|
||||
// all of which must occur, in any order.
|
||||
|
||||
// Use MatchOnce for groups with a large number of terms,
|
||||
// since &&-groups produces at least N!-node trees
|
||||
if (terms.length > 5) {
|
||||
return {
|
||||
type: 'MatchOnce',
|
||||
terms,
|
||||
all: true,
|
||||
};
|
||||
}
|
||||
|
||||
// Use a combination tree for groups with small number of terms
|
||||
//
|
||||
// a && b && c
|
||||
// =
|
||||
// match a
|
||||
// then [b && c]
|
||||
// else match b
|
||||
// then [a && c]
|
||||
// else match c
|
||||
// then [a && b]
|
||||
// else MISMATCH
|
||||
//
|
||||
// a && b
|
||||
// =
|
||||
// match a
|
||||
// then match b
|
||||
// then MATCH
|
||||
// else MISMATCH
|
||||
// else match b
|
||||
// then match a
|
||||
// then MATCH
|
||||
// else MISMATCH
|
||||
// else MISMATCH
|
||||
let result = MISMATCH;
|
||||
|
||||
for (let i = terms.length - 1; i >= 0; i--) {
|
||||
const term = terms[i];
|
||||
let thenClause;
|
||||
|
||||
if (terms.length > 1) {
|
||||
thenClause = buildGroupMatchGraph(
|
||||
combinator,
|
||||
terms.filter(function (newGroupTerm) {
|
||||
return newGroupTerm !== term;
|
||||
}),
|
||||
false
|
||||
);
|
||||
} else {
|
||||
thenClause = MATCH;
|
||||
}
|
||||
|
||||
result = createCondition(term, thenClause, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
case '||': {
|
||||
// A double bar (||) separates two or more options:
|
||||
// one or more of them must occur, in any order.
|
||||
|
||||
// Use MatchOnce for groups with a large number of terms,
|
||||
// since ||-groups produces at least N!-node trees
|
||||
if (terms.length > 5) {
|
||||
return {
|
||||
type: 'MatchOnce',
|
||||
terms,
|
||||
all: false,
|
||||
};
|
||||
}
|
||||
|
||||
// Use a combination tree for groups with small number of terms
|
||||
//
|
||||
// a || b || c
|
||||
// =
|
||||
// match a
|
||||
// then [b || c]
|
||||
// else match b
|
||||
// then [a || c]
|
||||
// else match c
|
||||
// then [a || b]
|
||||
// else MISMATCH
|
||||
//
|
||||
// a || b
|
||||
// =
|
||||
// match a
|
||||
// then match b
|
||||
// then MATCH
|
||||
// else MATCH
|
||||
// else match b
|
||||
// then match a
|
||||
// then MATCH
|
||||
// else MATCH
|
||||
// else MISMATCH
|
||||
let result = atLeastOneTermMatched ? MATCH : MISMATCH;
|
||||
|
||||
for (let i = terms.length - 1; i >= 0; i--) {
|
||||
const term = terms[i];
|
||||
let thenClause;
|
||||
|
||||
if (terms.length > 1) {
|
||||
thenClause = buildGroupMatchGraph(
|
||||
combinator,
|
||||
terms.filter(function (newGroupTerm) {
|
||||
return newGroupTerm !== term;
|
||||
}),
|
||||
true
|
||||
);
|
||||
} else {
|
||||
thenClause = MATCH;
|
||||
}
|
||||
|
||||
result = createCondition(term, thenClause, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function buildMultiplierMatchGraph(node) {
|
||||
let result = MATCH;
|
||||
let matchTerm = buildMatchGraphInternal(node.term);
|
||||
let result = MATCH;
|
||||
let matchTerm = buildMatchGraphInternal(node.term);
|
||||
|
||||
if (node.max === 0) {
|
||||
// disable repeating of empty match to prevent infinite loop
|
||||
matchTerm = createCondition(
|
||||
matchTerm,
|
||||
DISALLOW_EMPTY,
|
||||
MISMATCH
|
||||
);
|
||||
if (node.max === 0) {
|
||||
// disable repeating of empty match to prevent infinite loop
|
||||
matchTerm = createCondition(matchTerm, DISALLOW_EMPTY, MISMATCH);
|
||||
|
||||
// an occurrence count is not limited, make a cycle;
|
||||
// to collect more terms on each following matching mismatch
|
||||
result = createCondition(
|
||||
matchTerm,
|
||||
null, // will be a loop
|
||||
MISMATCH
|
||||
);
|
||||
// an occurrence count is not limited, make a cycle;
|
||||
// to collect more terms on each following matching mismatch
|
||||
result = createCondition(
|
||||
matchTerm,
|
||||
null, // will be a loop
|
||||
MISMATCH
|
||||
);
|
||||
|
||||
result.then = createCondition(
|
||||
MATCH,
|
||||
MATCH,
|
||||
result // make a loop
|
||||
);
|
||||
result.then = createCondition(
|
||||
MATCH,
|
||||
MATCH,
|
||||
result // make a loop
|
||||
);
|
||||
|
||||
if (node.comma) {
|
||||
result.then.else = createCondition(
|
||||
{ type: 'Comma', syntax: node },
|
||||
result,
|
||||
MISMATCH
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// create a match node chain for [min .. max] interval with optional matches
|
||||
for (let i = node.min || 1; i <= node.max; i++) {
|
||||
if (node.comma && result !== MATCH) {
|
||||
result = createCondition(
|
||||
{ type: 'Comma', syntax: node },
|
||||
result,
|
||||
MISMATCH
|
||||
);
|
||||
}
|
||||
|
||||
result = createCondition(
|
||||
matchTerm,
|
||||
createCondition(
|
||||
MATCH,
|
||||
MATCH,
|
||||
result
|
||||
),
|
||||
MISMATCH
|
||||
);
|
||||
}
|
||||
if (node.comma) {
|
||||
result.then.else = createCondition(
|
||||
{ type: 'Comma', syntax: node },
|
||||
result,
|
||||
MISMATCH
|
||||
);
|
||||
}
|
||||
|
||||
if (node.min === 0) {
|
||||
// allow zero match
|
||||
} else {
|
||||
// create a match node chain for [min .. max] interval with optional matches
|
||||
for (let i = node.min || 1; i <= node.max; i++) {
|
||||
if (node.comma && result !== MATCH) {
|
||||
result = createCondition(
|
||||
MATCH,
|
||||
MATCH,
|
||||
result
|
||||
{ type: 'Comma', syntax: node },
|
||||
result,
|
||||
MISMATCH
|
||||
);
|
||||
} else {
|
||||
// create a match node chain to collect [0 ... min - 1] required matches
|
||||
for (let i = 0; i < node.min - 1; i++) {
|
||||
if (node.comma && result !== MATCH) {
|
||||
result = createCondition(
|
||||
{ type: 'Comma', syntax: node },
|
||||
result,
|
||||
MISMATCH
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
result = createCondition(
|
||||
matchTerm,
|
||||
result,
|
||||
MISMATCH
|
||||
);
|
||||
}
|
||||
result = createCondition(
|
||||
matchTerm,
|
||||
createCondition(MATCH, MATCH, result),
|
||||
MISMATCH
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
if (node.min === 0) {
|
||||
// allow zero match
|
||||
result = createCondition(MATCH, MATCH, result);
|
||||
} else {
|
||||
// create a match node chain to collect [0 ... min - 1] required matches
|
||||
for (let i = 0; i < node.min - 1; i++) {
|
||||
if (node.comma && result !== MATCH) {
|
||||
result = createCondition(
|
||||
{ type: 'Comma', syntax: node },
|
||||
result,
|
||||
MISMATCH
|
||||
);
|
||||
}
|
||||
|
||||
result = createCondition(matchTerm, result, MISMATCH);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function buildMatchGraphInternal(node) {
|
||||
if (typeof node === 'function') {
|
||||
if (typeof node === 'function') {
|
||||
return {
|
||||
type: 'Generic',
|
||||
fn: node,
|
||||
};
|
||||
}
|
||||
|
||||
switch (node.type) {
|
||||
case 'Group': {
|
||||
let result = buildGroupMatchGraph(
|
||||
node.combinator,
|
||||
node.terms.map(buildMatchGraphInternal),
|
||||
false
|
||||
);
|
||||
|
||||
if (node.disallowEmpty) {
|
||||
result = createCondition(result, DISALLOW_EMPTY, MISMATCH);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
case 'Multiplier':
|
||||
return buildMultiplierMatchGraph(node);
|
||||
|
||||
case 'Type':
|
||||
case 'Property':
|
||||
return {
|
||||
type: node.type,
|
||||
name: node.name,
|
||||
syntax: node,
|
||||
};
|
||||
|
||||
case 'Keyword':
|
||||
return {
|
||||
type: node.type,
|
||||
name: node.name.toLowerCase(),
|
||||
syntax: node,
|
||||
};
|
||||
|
||||
case 'AtKeyword':
|
||||
return {
|
||||
type: node.type,
|
||||
name: '@' + node.name.toLowerCase(),
|
||||
syntax: node,
|
||||
};
|
||||
|
||||
case 'Function':
|
||||
return {
|
||||
type: node.type,
|
||||
name: node.name.toLowerCase() + '(',
|
||||
syntax: node,
|
||||
};
|
||||
|
||||
case 'String':
|
||||
// convert a one char length String to a Token
|
||||
if (node.value.length === 3) {
|
||||
return {
|
||||
type: 'Generic',
|
||||
fn: node
|
||||
type: 'Token',
|
||||
value: node.value.charAt(1),
|
||||
syntax: node,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
switch (node.type) {
|
||||
case 'Group': {
|
||||
let result = buildGroupMatchGraph(
|
||||
node.combinator,
|
||||
node.terms.map(buildMatchGraphInternal),
|
||||
false
|
||||
);
|
||||
// otherwise use it as is
|
||||
return {
|
||||
type: node.type,
|
||||
value: node.value.substr(1, node.value.length - 2).replace(/\\'/g, "'"),
|
||||
syntax: node,
|
||||
};
|
||||
|
||||
if (node.disallowEmpty) {
|
||||
result = createCondition(
|
||||
result,
|
||||
DISALLOW_EMPTY,
|
||||
MISMATCH
|
||||
);
|
||||
}
|
||||
case 'Token':
|
||||
return {
|
||||
type: node.type,
|
||||
value: node.value,
|
||||
syntax: node,
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
case 'Comma':
|
||||
return {
|
||||
type: node.type,
|
||||
syntax: node,
|
||||
};
|
||||
|
||||
case 'Multiplier':
|
||||
return buildMultiplierMatchGraph(node);
|
||||
|
||||
case 'Type':
|
||||
case 'Property':
|
||||
return {
|
||||
type: node.type,
|
||||
name: node.name,
|
||||
syntax: node
|
||||
};
|
||||
|
||||
case 'Keyword':
|
||||
return {
|
||||
type: node.type,
|
||||
name: node.name.toLowerCase(),
|
||||
syntax: node
|
||||
};
|
||||
|
||||
case 'AtKeyword':
|
||||
return {
|
||||
type: node.type,
|
||||
name: '@' + node.name.toLowerCase(),
|
||||
syntax: node
|
||||
};
|
||||
|
||||
case 'Function':
|
||||
return {
|
||||
type: node.type,
|
||||
name: node.name.toLowerCase() + '(',
|
||||
syntax: node
|
||||
};
|
||||
|
||||
case 'String':
|
||||
// convert a one char length String to a Token
|
||||
if (node.value.length === 3) {
|
||||
return {
|
||||
type: 'Token',
|
||||
value: node.value.charAt(1),
|
||||
syntax: node
|
||||
};
|
||||
}
|
||||
|
||||
// otherwise use it as is
|
||||
return {
|
||||
type: node.type,
|
||||
value: node.value.substr(1, node.value.length - 2).replace(/\\'/g, '\''),
|
||||
syntax: node
|
||||
};
|
||||
|
||||
case 'Token':
|
||||
return {
|
||||
type: node.type,
|
||||
value: node.value,
|
||||
syntax: node
|
||||
};
|
||||
|
||||
case 'Comma':
|
||||
return {
|
||||
type: node.type,
|
||||
syntax: node
|
||||
};
|
||||
|
||||
default:
|
||||
throw new Error('Unknown node type:', node.type);
|
||||
}
|
||||
default:
|
||||
throw new Error('Unknown node type:', node.type);
|
||||
}
|
||||
}
|
||||
|
||||
export function buildMatchGraph(syntaxTree, ref) {
|
||||
if (typeof syntaxTree === 'string') {
|
||||
syntaxTree = parse(syntaxTree);
|
||||
}
|
||||
if (typeof syntaxTree === 'string') {
|
||||
syntaxTree = parse(syntaxTree);
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'MatchGraph',
|
||||
match: buildMatchGraphInternal(syntaxTree),
|
||||
syntax: ref || null,
|
||||
source: syntaxTree
|
||||
};
|
||||
return {
|
||||
type: 'MatchGraph',
|
||||
match: buildMatchGraphInternal(syntaxTree),
|
||||
syntax: ref || null,
|
||||
source: syntaxTree,
|
||||
};
|
||||
}
|
||||
|
1147
node_modules/css-tree/lib/lexer/match.js
generated
vendored
1147
node_modules/css-tree/lib/lexer/match.js
generated
vendored
File diff suppressed because it is too large
Load Diff
76
node_modules/css-tree/lib/lexer/prepare-tokens.js
generated
vendored
76
node_modules/css-tree/lib/lexer/prepare-tokens.js
generated
vendored
@ -1,50 +1,50 @@
|
||||
import { tokenize } from '../tokenizer/index.js';
|
||||
|
||||
const astToTokens = {
|
||||
decorator(handlers) {
|
||||
const tokens = [];
|
||||
let curNode = null;
|
||||
decorator(handlers) {
|
||||
const tokens = [];
|
||||
let curNode = null;
|
||||
|
||||
return {
|
||||
...handlers,
|
||||
node(node) {
|
||||
const tmp = curNode;
|
||||
curNode = node;
|
||||
handlers.node.call(this, node);
|
||||
curNode = tmp;
|
||||
},
|
||||
emit(value, type, auto) {
|
||||
tokens.push({
|
||||
type,
|
||||
value,
|
||||
node: auto ? null : curNode
|
||||
});
|
||||
},
|
||||
result() {
|
||||
return tokens;
|
||||
}
|
||||
};
|
||||
}
|
||||
return {
|
||||
...handlers,
|
||||
node(node) {
|
||||
const tmp = curNode;
|
||||
curNode = node;
|
||||
handlers.node.call(this, node);
|
||||
curNode = tmp;
|
||||
},
|
||||
emit(value, type, auto) {
|
||||
tokens.push({
|
||||
type,
|
||||
value,
|
||||
node: auto ? null : curNode,
|
||||
});
|
||||
},
|
||||
result() {
|
||||
return tokens;
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
function stringToTokens(str) {
|
||||
const tokens = [];
|
||||
const tokens = [];
|
||||
|
||||
tokenize(str, (type, start, end) =>
|
||||
tokens.push({
|
||||
type,
|
||||
value: str.slice(start, end),
|
||||
node: null
|
||||
})
|
||||
);
|
||||
tokenize(str, (type, start, end) =>
|
||||
tokens.push({
|
||||
type,
|
||||
value: str.slice(start, end),
|
||||
node: null,
|
||||
})
|
||||
);
|
||||
|
||||
return tokens;
|
||||
return tokens;
|
||||
}
|
||||
|
||||
export default function(value, syntax) {
|
||||
if (typeof value === 'string') {
|
||||
return stringToTokens(value);
|
||||
}
|
||||
export default function (value, syntax) {
|
||||
if (typeof value === 'string') {
|
||||
return stringToTokens(value);
|
||||
}
|
||||
|
||||
return syntax.generate(value, astToTokens);
|
||||
};
|
||||
return syntax.generate(value, astToTokens);
|
||||
}
|
||||
|
80
node_modules/css-tree/lib/lexer/search.js
generated
vendored
80
node_modules/css-tree/lib/lexer/search.js
generated
vendored
@ -1,61 +1,63 @@
|
||||
import { List } from '../utils/List.js';
|
||||
|
||||
function getFirstMatchNode(matchNode) {
|
||||
if ('node' in matchNode) {
|
||||
return matchNode.node;
|
||||
}
|
||||
if ('node' in matchNode) {
|
||||
return matchNode.node;
|
||||
}
|
||||
|
||||
return getFirstMatchNode(matchNode.match[0]);
|
||||
return getFirstMatchNode(matchNode.match[0]);
|
||||
}
|
||||
|
||||
function getLastMatchNode(matchNode) {
|
||||
if ('node' in matchNode) {
|
||||
return matchNode.node;
|
||||
}
|
||||
if ('node' in matchNode) {
|
||||
return matchNode.node;
|
||||
}
|
||||
|
||||
return getLastMatchNode(matchNode.match[matchNode.match.length - 1]);
|
||||
return getLastMatchNode(matchNode.match[matchNode.match.length - 1]);
|
||||
}
|
||||
|
||||
export function matchFragments(lexer, ast, match, type, name) {
|
||||
function findFragments(matchNode) {
|
||||
if (matchNode.syntax !== null &&
|
||||
matchNode.syntax.type === type &&
|
||||
matchNode.syntax.name === name) {
|
||||
const start = getFirstMatchNode(matchNode);
|
||||
const end = getLastMatchNode(matchNode);
|
||||
function findFragments(matchNode) {
|
||||
if (
|
||||
matchNode.syntax !== null &&
|
||||
matchNode.syntax.type === type &&
|
||||
matchNode.syntax.name === name
|
||||
) {
|
||||
const start = getFirstMatchNode(matchNode);
|
||||
const end = getLastMatchNode(matchNode);
|
||||
|
||||
lexer.syntax.walk(ast, function(node, item, list) {
|
||||
if (node === start) {
|
||||
const nodes = new List();
|
||||
lexer.syntax.walk(ast, function (node, item, list) {
|
||||
if (node === start) {
|
||||
const nodes = new List();
|
||||
|
||||
do {
|
||||
nodes.appendData(item.data);
|
||||
do {
|
||||
nodes.appendData(item.data);
|
||||
|
||||
if (item.data === end) {
|
||||
break;
|
||||
}
|
||||
if (item.data === end) {
|
||||
break;
|
||||
}
|
||||
|
||||
item = item.next;
|
||||
} while (item !== null);
|
||||
item = item.next;
|
||||
} while (item !== null);
|
||||
|
||||
fragments.push({
|
||||
parent: list,
|
||||
nodes
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (Array.isArray(matchNode.match)) {
|
||||
matchNode.match.forEach(findFragments);
|
||||
fragments.push({
|
||||
parent: list,
|
||||
nodes,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const fragments = [];
|
||||
|
||||
if (match.matched !== null) {
|
||||
findFragments(match.matched);
|
||||
if (Array.isArray(matchNode.match)) {
|
||||
matchNode.match.forEach(findFragments);
|
||||
}
|
||||
}
|
||||
|
||||
return fragments;
|
||||
const fragments = [];
|
||||
|
||||
if (match.matched !== null) {
|
||||
findFragments(match.matched);
|
||||
}
|
||||
|
||||
return fragments;
|
||||
}
|
||||
|
276
node_modules/css-tree/lib/lexer/structure.js
generated
vendored
276
node_modules/css-tree/lib/lexer/structure.js
generated
vendored
@ -3,162 +3,178 @@ import { List } from '../utils/List.js';
|
||||
const { hasOwnProperty } = Object.prototype;
|
||||
|
||||
function isValidNumber(value) {
|
||||
// Number.isInteger(value) && value >= 0
|
||||
return (
|
||||
typeof value === 'number' &&
|
||||
isFinite(value) &&
|
||||
Math.floor(value) === value &&
|
||||
value >= 0
|
||||
);
|
||||
// Number.isInteger(value) && value >= 0
|
||||
return (
|
||||
typeof value === 'number' &&
|
||||
isFinite(value) &&
|
||||
Math.floor(value) === value &&
|
||||
value >= 0
|
||||
);
|
||||
}
|
||||
|
||||
function isValidLocation(loc) {
|
||||
return (
|
||||
Boolean(loc) &&
|
||||
isValidNumber(loc.offset) &&
|
||||
isValidNumber(loc.line) &&
|
||||
isValidNumber(loc.column)
|
||||
);
|
||||
return (
|
||||
Boolean(loc) &&
|
||||
isValidNumber(loc.offset) &&
|
||||
isValidNumber(loc.line) &&
|
||||
isValidNumber(loc.column)
|
||||
);
|
||||
}
|
||||
|
||||
function createNodeStructureChecker(type, fields) {
|
||||
return function checkNode(node, warn) {
|
||||
if (!node || node.constructor !== Object) {
|
||||
return warn(node, 'Type of node should be an Object');
|
||||
return function checkNode(node, warn) {
|
||||
if (!node || node.constructor !== Object) {
|
||||
return warn(node, 'Type of node should be an Object');
|
||||
}
|
||||
|
||||
for (let key in node) {
|
||||
let valid = true;
|
||||
|
||||
if (hasOwnProperty.call(node, key) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (key === 'type') {
|
||||
if (node.type !== type) {
|
||||
warn(
|
||||
node,
|
||||
'Wrong node type `' + node.type + '`, expected `' + type + '`'
|
||||
);
|
||||
}
|
||||
} else if (key === 'loc') {
|
||||
if (node.loc === null) {
|
||||
continue;
|
||||
} else if (node.loc && node.loc.constructor === Object) {
|
||||
if (typeof node.loc.source !== 'string') {
|
||||
key += '.source';
|
||||
} else if (!isValidLocation(node.loc.start)) {
|
||||
key += '.start';
|
||||
} else if (!isValidLocation(node.loc.end)) {
|
||||
key += '.end';
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (let key in node) {
|
||||
let valid = true;
|
||||
valid = false;
|
||||
} else if (fields.hasOwnProperty(key)) {
|
||||
valid = false;
|
||||
|
||||
if (hasOwnProperty.call(node, key) === false) {
|
||||
continue;
|
||||
}
|
||||
for (let i = 0; !valid && i < fields[key].length; i++) {
|
||||
const fieldType = fields[key][i];
|
||||
|
||||
if (key === 'type') {
|
||||
if (node.type !== type) {
|
||||
warn(node, 'Wrong node type `' + node.type + '`, expected `' + type + '`');
|
||||
}
|
||||
} else if (key === 'loc') {
|
||||
if (node.loc === null) {
|
||||
continue;
|
||||
} else if (node.loc && node.loc.constructor === Object) {
|
||||
if (typeof node.loc.source !== 'string') {
|
||||
key += '.source';
|
||||
} else if (!isValidLocation(node.loc.start)) {
|
||||
key += '.start';
|
||||
} else if (!isValidLocation(node.loc.end)) {
|
||||
key += '.end';
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
switch (fieldType) {
|
||||
case String:
|
||||
valid = typeof node[key] === 'string';
|
||||
break;
|
||||
|
||||
valid = false;
|
||||
} else if (fields.hasOwnProperty(key)) {
|
||||
valid = false;
|
||||
case Boolean:
|
||||
valid = typeof node[key] === 'boolean';
|
||||
break;
|
||||
|
||||
for (let i = 0; !valid && i < fields[key].length; i++) {
|
||||
const fieldType = fields[key][i];
|
||||
case null:
|
||||
valid = node[key] === null;
|
||||
break;
|
||||
|
||||
switch (fieldType) {
|
||||
case String:
|
||||
valid = typeof node[key] === 'string';
|
||||
break;
|
||||
|
||||
case Boolean:
|
||||
valid = typeof node[key] === 'boolean';
|
||||
break;
|
||||
|
||||
case null:
|
||||
valid = node[key] === null;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (typeof fieldType === 'string') {
|
||||
valid = node[key] && node[key].type === fieldType;
|
||||
} else if (Array.isArray(fieldType)) {
|
||||
valid = node[key] instanceof List;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn(node, 'Unknown field `' + key + '` for ' + type + ' node type');
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
warn(node, 'Bad value for `' + type + '.' + key + '`');
|
||||
}
|
||||
default:
|
||||
if (typeof fieldType === 'string') {
|
||||
valid = node[key] && node[key].type === fieldType;
|
||||
} else if (Array.isArray(fieldType)) {
|
||||
valid = node[key] instanceof List;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn(node, 'Unknown field `' + key + '` for ' + type + ' node type');
|
||||
}
|
||||
|
||||
for (const key in fields) {
|
||||
if (hasOwnProperty.call(fields, key) &&
|
||||
hasOwnProperty.call(node, key) === false) {
|
||||
warn(node, 'Field `' + type + '.' + key + '` is missed');
|
||||
}
|
||||
}
|
||||
};
|
||||
if (!valid) {
|
||||
warn(node, 'Bad value for `' + type + '.' + key + '`');
|
||||
}
|
||||
}
|
||||
|
||||
for (const key in fields) {
|
||||
if (
|
||||
hasOwnProperty.call(fields, key) &&
|
||||
hasOwnProperty.call(node, key) === false
|
||||
) {
|
||||
warn(node, 'Field `' + type + '.' + key + '` is missed');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function processStructure(name, nodeType) {
|
||||
const structure = nodeType.structure;
|
||||
const fields = {
|
||||
type: String,
|
||||
loc: true
|
||||
};
|
||||
const docs = {
|
||||
type: '"' + name + '"'
|
||||
};
|
||||
const structure = nodeType.structure;
|
||||
const fields = {
|
||||
type: String,
|
||||
loc: true,
|
||||
};
|
||||
const docs = {
|
||||
type: '"' + name + '"',
|
||||
};
|
||||
|
||||
for (const key in structure) {
|
||||
if (hasOwnProperty.call(structure, key) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const docsTypes = [];
|
||||
const fieldTypes = fields[key] = Array.isArray(structure[key])
|
||||
? structure[key].slice()
|
||||
: [structure[key]];
|
||||
|
||||
for (let i = 0; i < fieldTypes.length; i++) {
|
||||
const fieldType = fieldTypes[i];
|
||||
if (fieldType === String || fieldType === Boolean) {
|
||||
docsTypes.push(fieldType.name);
|
||||
} else if (fieldType === null) {
|
||||
docsTypes.push('null');
|
||||
} else if (typeof fieldType === 'string') {
|
||||
docsTypes.push('<' + fieldType + '>');
|
||||
} else if (Array.isArray(fieldType)) {
|
||||
docsTypes.push('List'); // TODO: use type enum
|
||||
} else {
|
||||
throw new Error('Wrong value `' + fieldType + '` in `' + name + '.' + key + '` structure definition');
|
||||
}
|
||||
}
|
||||
|
||||
docs[key] = docsTypes.join(' | ');
|
||||
for (const key in structure) {
|
||||
if (hasOwnProperty.call(structure, key) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return {
|
||||
docs,
|
||||
check: createNodeStructureChecker(name, fields)
|
||||
};
|
||||
const docsTypes = [];
|
||||
const fieldTypes = (fields[key] =
|
||||
Array.isArray(structure[key]) ?
|
||||
structure[key].slice()
|
||||
: [structure[key]]);
|
||||
|
||||
for (let i = 0; i < fieldTypes.length; i++) {
|
||||
const fieldType = fieldTypes[i];
|
||||
if (fieldType === String || fieldType === Boolean) {
|
||||
docsTypes.push(fieldType.name);
|
||||
} else if (fieldType === null) {
|
||||
docsTypes.push('null');
|
||||
} else if (typeof fieldType === 'string') {
|
||||
docsTypes.push('<' + fieldType + '>');
|
||||
} else if (Array.isArray(fieldType)) {
|
||||
docsTypes.push('List'); // TODO: use type enum
|
||||
} else {
|
||||
throw new Error(
|
||||
'Wrong value `' +
|
||||
fieldType +
|
||||
'` in `' +
|
||||
name +
|
||||
'.' +
|
||||
key +
|
||||
'` structure definition'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
docs[key] = docsTypes.join(' | ');
|
||||
}
|
||||
|
||||
return {
|
||||
docs,
|
||||
check: createNodeStructureChecker(name, fields),
|
||||
};
|
||||
}
|
||||
|
||||
export function getStructureFromConfig(config) {
|
||||
const structure = {};
|
||||
const structure = {};
|
||||
|
||||
if (config.node) {
|
||||
for (const name in config.node) {
|
||||
if (hasOwnProperty.call(config.node, name)) {
|
||||
const nodeType = config.node[name];
|
||||
if (config.node) {
|
||||
for (const name in config.node) {
|
||||
if (hasOwnProperty.call(config.node, name)) {
|
||||
const nodeType = config.node[name];
|
||||
|
||||
if (nodeType.structure) {
|
||||
structure[name] = processStructure(name, nodeType);
|
||||
} else {
|
||||
throw new Error('Missed `structure` field in `' + name + '` node type definition');
|
||||
}
|
||||
}
|
||||
if (nodeType.structure) {
|
||||
structure[name] = processStructure(name, nodeType);
|
||||
} else {
|
||||
throw new Error(
|
||||
'Missed `structure` field in `' + name + '` node type definition'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return structure;
|
||||
};
|
||||
return structure;
|
||||
}
|
||||
|
92
node_modules/css-tree/lib/lexer/trace.js
generated
vendored
92
node_modules/css-tree/lib/lexer/trace.js
generated
vendored
@ -1,66 +1,72 @@
|
||||
export function getTrace(node) {
|
||||
function shouldPutToTrace(syntax) {
|
||||
if (syntax === null) {
|
||||
return false;
|
||||
function shouldPutToTrace(syntax) {
|
||||
if (syntax === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
syntax.type === 'Type' ||
|
||||
syntax.type === 'Property' ||
|
||||
syntax.type === 'Keyword'
|
||||
);
|
||||
}
|
||||
|
||||
function hasMatch(matchNode) {
|
||||
if (Array.isArray(matchNode.match)) {
|
||||
// use for-loop for better perfomance
|
||||
for (let i = 0; i < matchNode.match.length; i++) {
|
||||
if (hasMatch(matchNode.match[i])) {
|
||||
if (shouldPutToTrace(matchNode.syntax)) {
|
||||
result.unshift(matchNode.syntax);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (matchNode.node === node) {
|
||||
result = shouldPutToTrace(matchNode.syntax) ? [matchNode.syntax] : [];
|
||||
|
||||
return (
|
||||
syntax.type === 'Type' ||
|
||||
syntax.type === 'Property' ||
|
||||
syntax.type === 'Keyword'
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
function hasMatch(matchNode) {
|
||||
if (Array.isArray(matchNode.match)) {
|
||||
// use for-loop for better perfomance
|
||||
for (let i = 0; i < matchNode.match.length; i++) {
|
||||
if (hasMatch(matchNode.match[i])) {
|
||||
if (shouldPutToTrace(matchNode.syntax)) {
|
||||
result.unshift(matchNode.syntax);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (matchNode.node === node) {
|
||||
result = shouldPutToTrace(matchNode.syntax)
|
||||
? [matchNode.syntax]
|
||||
: [];
|
||||
let result = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
if (this.matched !== null) {
|
||||
hasMatch(this.matched);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
let result = null;
|
||||
|
||||
if (this.matched !== null) {
|
||||
hasMatch(this.matched);
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
export function isType(node, type) {
|
||||
return testNode(this, node, match => match.type === 'Type' && match.name === type);
|
||||
return testNode(
|
||||
this,
|
||||
node,
|
||||
(match) => match.type === 'Type' && match.name === type
|
||||
);
|
||||
}
|
||||
|
||||
export function isProperty(node, property) {
|
||||
return testNode(this, node, match => match.type === 'Property' && match.name === property);
|
||||
return testNode(
|
||||
this,
|
||||
node,
|
||||
(match) => match.type === 'Property' && match.name === property
|
||||
);
|
||||
}
|
||||
|
||||
export function isKeyword(node) {
|
||||
return testNode(this, node, match => match.type === 'Keyword');
|
||||
return testNode(this, node, (match) => match.type === 'Keyword');
|
||||
}
|
||||
|
||||
function testNode(match, node, fn) {
|
||||
const trace = getTrace.call(match, node);
|
||||
const trace = getTrace.call(match, node);
|
||||
|
||||
if (trace === null) {
|
||||
return false;
|
||||
}
|
||||
if (trace === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return trace.some(fn);
|
||||
return trace.some(fn);
|
||||
}
|
||||
|
111
node_modules/css-tree/lib/parser/SyntaxError.js
generated
vendored
111
node_modules/css-tree/lib/parser/SyntaxError.js
generated
vendored
@ -5,61 +5,70 @@ const OFFSET_CORRECTION = 60;
|
||||
const TAB_REPLACEMENT = ' ';
|
||||
|
||||
function sourceFragment({ source, line, column }, extraLines) {
|
||||
function processLines(start, end) {
|
||||
return lines
|
||||
.slice(start, end)
|
||||
.map((line, idx) =>
|
||||
String(start + idx + 1).padStart(maxNumLength) + ' |' + line
|
||||
).join('\n');
|
||||
function processLines(start, end) {
|
||||
return lines
|
||||
.slice(start, end)
|
||||
.map(
|
||||
(line, idx) =>
|
||||
String(start + idx + 1).padStart(maxNumLength) + ' |' + line
|
||||
)
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
const lines = source.split(/\r\n?|\n|\f/);
|
||||
const startLine = Math.max(1, line - extraLines) - 1;
|
||||
const endLine = Math.min(line + extraLines, lines.length + 1);
|
||||
const maxNumLength = Math.max(4, String(endLine).length) + 1;
|
||||
let cutLeft = 0;
|
||||
|
||||
// column correction according to replaced tab before column
|
||||
column +=
|
||||
(TAB_REPLACEMENT.length - 1) *
|
||||
(lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length;
|
||||
|
||||
if (column > MAX_LINE_LENGTH) {
|
||||
cutLeft = column - OFFSET_CORRECTION + 3;
|
||||
column = OFFSET_CORRECTION - 2;
|
||||
}
|
||||
|
||||
for (let i = startLine; i <= endLine; i++) {
|
||||
if (i >= 0 && i < lines.length) {
|
||||
lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT);
|
||||
lines[i] =
|
||||
(cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') +
|
||||
lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +
|
||||
(lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : '');
|
||||
}
|
||||
}
|
||||
|
||||
const lines = source.split(/\r\n?|\n|\f/);
|
||||
const startLine = Math.max(1, line - extraLines) - 1;
|
||||
const endLine = Math.min(line + extraLines, lines.length + 1);
|
||||
const maxNumLength = Math.max(4, String(endLine).length) + 1;
|
||||
let cutLeft = 0;
|
||||
|
||||
// column correction according to replaced tab before column
|
||||
column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length;
|
||||
|
||||
if (column > MAX_LINE_LENGTH) {
|
||||
cutLeft = column - OFFSET_CORRECTION + 3;
|
||||
column = OFFSET_CORRECTION - 2;
|
||||
}
|
||||
|
||||
for (let i = startLine; i <= endLine; i++) {
|
||||
if (i >= 0 && i < lines.length) {
|
||||
lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT);
|
||||
lines[i] =
|
||||
(cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') +
|
||||
lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +
|
||||
(lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : '');
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
processLines(startLine, line),
|
||||
new Array(column + maxNumLength + 2).join('-') + '^',
|
||||
processLines(line, endLine)
|
||||
].filter(Boolean).join('\n');
|
||||
return [
|
||||
processLines(startLine, line),
|
||||
new Array(column + maxNumLength + 2).join('-') + '^',
|
||||
processLines(line, endLine),
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
export function SyntaxError(message, source, offset, line, column) {
|
||||
const error = Object.assign(createCustomError('SyntaxError', message), {
|
||||
source,
|
||||
offset,
|
||||
line,
|
||||
column,
|
||||
sourceFragment(extraLines) {
|
||||
return sourceFragment({ source, line, column }, isNaN(extraLines) ? 0 : extraLines);
|
||||
},
|
||||
get formattedMessage() {
|
||||
return (
|
||||
`Parse error: ${message}\n` +
|
||||
sourceFragment({ source, line, column }, 2)
|
||||
);
|
||||
}
|
||||
});
|
||||
const error = Object.assign(createCustomError('SyntaxError', message), {
|
||||
source,
|
||||
offset,
|
||||
line,
|
||||
column,
|
||||
sourceFragment(extraLines) {
|
||||
return sourceFragment(
|
||||
{ source, line, column },
|
||||
isNaN(extraLines) ? 0 : extraLines
|
||||
);
|
||||
},
|
||||
get formattedMessage() {
|
||||
return (
|
||||
`Parse error: ${message}\n` +
|
||||
sourceFragment({ source, line, column }, 2)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
return error;
|
||||
return error;
|
||||
}
|
||||
|
612
node_modules/css-tree/lib/parser/create.js
generated
vendored
612
node_modules/css-tree/lib/parser/create.js
generated
vendored
@ -1,346 +1,362 @@
|
||||
import { List } from '../utils/List.js';
|
||||
import { SyntaxError } from './SyntaxError.js';
|
||||
import {
|
||||
tokenize,
|
||||
OffsetToLocation,
|
||||
TokenStream,
|
||||
tokenNames,
|
||||
|
||||
consumeNumber,
|
||||
findWhiteSpaceStart,
|
||||
cmpChar,
|
||||
cmpStr,
|
||||
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
Ident,
|
||||
Function as FunctionToken,
|
||||
Url,
|
||||
Hash,
|
||||
Percentage,
|
||||
Number as NumberToken
|
||||
tokenize,
|
||||
OffsetToLocation,
|
||||
TokenStream,
|
||||
tokenNames,
|
||||
consumeNumber,
|
||||
findWhiteSpaceStart,
|
||||
cmpChar,
|
||||
cmpStr,
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
Ident,
|
||||
Function as FunctionToken,
|
||||
Url,
|
||||
Hash,
|
||||
Percentage,
|
||||
Number as NumberToken,
|
||||
} from '../tokenizer/index.js';
|
||||
import { readSequence } from './sequence.js';
|
||||
|
||||
const NOOP = () => {};
|
||||
const EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!)
|
||||
const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
|
||||
const SEMICOLON = 0x003B; // U+003B SEMICOLON (;)
|
||||
const LEFTCURLYBRACKET = 0x007B; // U+007B LEFT CURLY BRACKET ({)
|
||||
const EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!)
|
||||
const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
|
||||
const SEMICOLON = 0x003b; // U+003B SEMICOLON (;)
|
||||
const LEFTCURLYBRACKET = 0x007b; // U+007B LEFT CURLY BRACKET ({)
|
||||
const NULL = 0;
|
||||
|
||||
function createParseContext(name) {
|
||||
return function() {
|
||||
return this[name]();
|
||||
};
|
||||
return function () {
|
||||
return this[name]();
|
||||
};
|
||||
}
|
||||
|
||||
function fetchParseValues(dict) {
|
||||
const result = Object.create(null);
|
||||
const result = Object.create(null);
|
||||
|
||||
for (const name in dict) {
|
||||
const item = dict[name];
|
||||
const fn = item.parse || item;
|
||||
for (const name in dict) {
|
||||
const item = dict[name];
|
||||
const fn = item.parse || item;
|
||||
|
||||
if (fn) {
|
||||
result[name] = fn;
|
||||
}
|
||||
if (fn) {
|
||||
result[name] = fn;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function processConfig(config) {
|
||||
const parseConfig = {
|
||||
context: Object.create(null),
|
||||
scope: Object.assign(Object.create(null), config.scope),
|
||||
atrule: fetchParseValues(config.atrule),
|
||||
pseudo: fetchParseValues(config.pseudo),
|
||||
node: fetchParseValues(config.node)
|
||||
};
|
||||
const parseConfig = {
|
||||
context: Object.create(null),
|
||||
scope: Object.assign(Object.create(null), config.scope),
|
||||
atrule: fetchParseValues(config.atrule),
|
||||
pseudo: fetchParseValues(config.pseudo),
|
||||
node: fetchParseValues(config.node),
|
||||
};
|
||||
|
||||
for (const name in config.parseContext) {
|
||||
switch (typeof config.parseContext[name]) {
|
||||
case 'function':
|
||||
parseConfig.context[name] = config.parseContext[name];
|
||||
break;
|
||||
for (const name in config.parseContext) {
|
||||
switch (typeof config.parseContext[name]) {
|
||||
case 'function':
|
||||
parseConfig.context[name] = config.parseContext[name];
|
||||
break;
|
||||
|
||||
case 'string':
|
||||
parseConfig.context[name] = createParseContext(config.parseContext[name]);
|
||||
break;
|
||||
}
|
||||
case 'string':
|
||||
parseConfig.context[name] = createParseContext(
|
||||
config.parseContext[name]
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
config: parseConfig,
|
||||
...parseConfig,
|
||||
...parseConfig.node
|
||||
};
|
||||
return {
|
||||
config: parseConfig,
|
||||
...parseConfig,
|
||||
...parseConfig.node,
|
||||
};
|
||||
}
|
||||
|
||||
export function createParser(config) {
|
||||
let source = '';
|
||||
let filename = '<unknown>';
|
||||
let needPositions = false;
|
||||
let onParseError = NOOP;
|
||||
let onParseErrorThrow = false;
|
||||
let source = '';
|
||||
let filename = '<unknown>';
|
||||
let needPositions = false;
|
||||
let onParseError = NOOP;
|
||||
let onParseErrorThrow = false;
|
||||
|
||||
const locationMap = new OffsetToLocation();
|
||||
const parser = Object.assign(new TokenStream(), processConfig(config || {}), {
|
||||
parseAtrulePrelude: true,
|
||||
parseRulePrelude: true,
|
||||
parseValue: true,
|
||||
parseCustomProperty: false,
|
||||
const locationMap = new OffsetToLocation();
|
||||
const parser = Object.assign(new TokenStream(), processConfig(config || {}), {
|
||||
parseAtrulePrelude: true,
|
||||
parseRulePrelude: true,
|
||||
parseValue: true,
|
||||
parseCustomProperty: false,
|
||||
|
||||
readSequence,
|
||||
readSequence,
|
||||
|
||||
consumeUntilBalanceEnd: () => 0,
|
||||
consumeUntilLeftCurlyBracket(code) {
|
||||
return code === LEFTCURLYBRACKET ? 1 : 0;
|
||||
},
|
||||
consumeUntilLeftCurlyBracketOrSemicolon(code) {
|
||||
return code === LEFTCURLYBRACKET || code === SEMICOLON ? 1 : 0;
|
||||
},
|
||||
consumeUntilExclamationMarkOrSemicolon(code) {
|
||||
return code === EXCLAMATIONMARK || code === SEMICOLON ? 1 : 0;
|
||||
},
|
||||
consumeUntilSemicolonIncluded(code) {
|
||||
return code === SEMICOLON ? 2 : 0;
|
||||
},
|
||||
consumeUntilBalanceEnd: () => 0,
|
||||
consumeUntilLeftCurlyBracket(code) {
|
||||
return code === LEFTCURLYBRACKET ? 1 : 0;
|
||||
},
|
||||
consumeUntilLeftCurlyBracketOrSemicolon(code) {
|
||||
return code === LEFTCURLYBRACKET || code === SEMICOLON ? 1 : 0;
|
||||
},
|
||||
consumeUntilExclamationMarkOrSemicolon(code) {
|
||||
return code === EXCLAMATIONMARK || code === SEMICOLON ? 1 : 0;
|
||||
},
|
||||
consumeUntilSemicolonIncluded(code) {
|
||||
return code === SEMICOLON ? 2 : 0;
|
||||
},
|
||||
|
||||
createList() {
|
||||
return new List();
|
||||
},
|
||||
createSingleNodeList(node) {
|
||||
return new List().appendData(node);
|
||||
},
|
||||
getFirstListNode(list) {
|
||||
return list && list.first;
|
||||
},
|
||||
getLastListNode(list) {
|
||||
return list && list.last;
|
||||
},
|
||||
createList() {
|
||||
return new List();
|
||||
},
|
||||
createSingleNodeList(node) {
|
||||
return new List().appendData(node);
|
||||
},
|
||||
getFirstListNode(list) {
|
||||
return list && list.first;
|
||||
},
|
||||
getLastListNode(list) {
|
||||
return list && list.last;
|
||||
},
|
||||
|
||||
parseWithFallback(consumer, fallback) {
|
||||
const startToken = this.tokenIndex;
|
||||
parseWithFallback(consumer, fallback) {
|
||||
const startToken = this.tokenIndex;
|
||||
|
||||
try {
|
||||
return consumer.call(this);
|
||||
} catch (e) {
|
||||
if (onParseErrorThrow) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
const fallbackNode = fallback.call(this, startToken);
|
||||
|
||||
onParseErrorThrow = true;
|
||||
onParseError(e, fallbackNode);
|
||||
onParseErrorThrow = false;
|
||||
|
||||
return fallbackNode;
|
||||
}
|
||||
},
|
||||
|
||||
lookupNonWSType(offset) {
|
||||
let type;
|
||||
|
||||
do {
|
||||
type = this.lookupType(offset++);
|
||||
if (type !== WhiteSpace) {
|
||||
return type;
|
||||
}
|
||||
} while (type !== NULL);
|
||||
|
||||
return NULL;
|
||||
},
|
||||
|
||||
charCodeAt(offset) {
|
||||
return offset >= 0 && offset < source.length ? source.charCodeAt(offset) : 0;
|
||||
},
|
||||
substring(offsetStart, offsetEnd) {
|
||||
return source.substring(offsetStart, offsetEnd);
|
||||
},
|
||||
substrToCursor(start) {
|
||||
return this.source.substring(start, this.tokenStart);
|
||||
},
|
||||
|
||||
cmpChar(offset, charCode) {
|
||||
return cmpChar(source, offset, charCode);
|
||||
},
|
||||
cmpStr(offsetStart, offsetEnd, str) {
|
||||
return cmpStr(source, offsetStart, offsetEnd, str);
|
||||
},
|
||||
|
||||
consume(tokenType) {
|
||||
const start = this.tokenStart;
|
||||
|
||||
this.eat(tokenType);
|
||||
|
||||
return this.substrToCursor(start);
|
||||
},
|
||||
consumeFunctionName() {
|
||||
const name = source.substring(this.tokenStart, this.tokenEnd - 1);
|
||||
|
||||
this.eat(FunctionToken);
|
||||
|
||||
return name;
|
||||
},
|
||||
consumeNumber(type) {
|
||||
const number = source.substring(this.tokenStart, consumeNumber(source, this.tokenStart));
|
||||
|
||||
this.eat(type);
|
||||
|
||||
return number;
|
||||
},
|
||||
|
||||
eat(tokenType) {
|
||||
if (this.tokenType !== tokenType) {
|
||||
const tokenName = tokenNames[tokenType].slice(0, -6).replace(/-/g, ' ').replace(/^./, m => m.toUpperCase());
|
||||
let message = `${/[[\](){}]/.test(tokenName) ? `"${tokenName}"` : tokenName} is expected`;
|
||||
let offset = this.tokenStart;
|
||||
|
||||
// tweak message and offset
|
||||
switch (tokenType) {
|
||||
case Ident:
|
||||
// when identifier is expected but there is a function or url
|
||||
if (this.tokenType === FunctionToken || this.tokenType === Url) {
|
||||
offset = this.tokenEnd - 1;
|
||||
message = 'Identifier is expected but function found';
|
||||
} else {
|
||||
message = 'Identifier is expected';
|
||||
}
|
||||
break;
|
||||
|
||||
case Hash:
|
||||
if (this.isDelim(NUMBERSIGN)) {
|
||||
this.next();
|
||||
offset++;
|
||||
message = 'Name is expected';
|
||||
}
|
||||
break;
|
||||
|
||||
case Percentage:
|
||||
if (this.tokenType === NumberToken) {
|
||||
offset = this.tokenEnd;
|
||||
message = 'Percent sign is expected';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this.error(message, offset);
|
||||
}
|
||||
|
||||
this.next();
|
||||
},
|
||||
eatIdent(name) {
|
||||
if (this.tokenType !== Ident || this.lookupValue(0, name) === false) {
|
||||
this.error(`Identifier "${name}" is expected`);
|
||||
}
|
||||
|
||||
this.next();
|
||||
},
|
||||
eatDelim(code) {
|
||||
if (!this.isDelim(code)) {
|
||||
this.error(`Delim "${String.fromCharCode(code)}" is expected`);
|
||||
}
|
||||
|
||||
this.next();
|
||||
},
|
||||
|
||||
getLocation(start, end) {
|
||||
if (needPositions) {
|
||||
return locationMap.getLocationRange(
|
||||
start,
|
||||
end,
|
||||
filename
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
getLocationFromList(list) {
|
||||
if (needPositions) {
|
||||
const head = this.getFirstListNode(list);
|
||||
const tail = this.getLastListNode(list);
|
||||
return locationMap.getLocationRange(
|
||||
head !== null ? head.loc.start.offset - locationMap.startOffset : this.tokenStart,
|
||||
tail !== null ? tail.loc.end.offset - locationMap.startOffset : this.tokenStart,
|
||||
filename
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
error(message, offset) {
|
||||
const location = typeof offset !== 'undefined' && offset < source.length
|
||||
? locationMap.getLocation(offset)
|
||||
: this.eof
|
||||
? locationMap.getLocation(findWhiteSpaceStart(source, source.length - 1))
|
||||
: locationMap.getLocation(this.tokenStart);
|
||||
|
||||
throw new SyntaxError(
|
||||
message || 'Unexpected input',
|
||||
source,
|
||||
location.offset,
|
||||
location.line,
|
||||
location.column
|
||||
);
|
||||
try {
|
||||
return consumer.call(this);
|
||||
} catch (e) {
|
||||
if (onParseErrorThrow) {
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
const parse = function(source_, options) {
|
||||
source = source_;
|
||||
options = options || {};
|
||||
const fallbackNode = fallback.call(this, startToken);
|
||||
|
||||
parser.setSource(source, tokenize);
|
||||
locationMap.setSource(
|
||||
source,
|
||||
options.offset,
|
||||
options.line,
|
||||
options.column
|
||||
);
|
||||
|
||||
filename = options.filename || '<unknown>';
|
||||
needPositions = Boolean(options.positions);
|
||||
onParseError = typeof options.onParseError === 'function' ? options.onParseError : NOOP;
|
||||
onParseErrorThrow = true;
|
||||
onParseError(e, fallbackNode);
|
||||
onParseErrorThrow = false;
|
||||
|
||||
parser.parseAtrulePrelude = 'parseAtrulePrelude' in options ? Boolean(options.parseAtrulePrelude) : true;
|
||||
parser.parseRulePrelude = 'parseRulePrelude' in options ? Boolean(options.parseRulePrelude) : true;
|
||||
parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true;
|
||||
parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false;
|
||||
return fallbackNode;
|
||||
}
|
||||
},
|
||||
|
||||
const { context = 'default', onComment } = options;
|
||||
lookupNonWSType(offset) {
|
||||
let type;
|
||||
|
||||
if (context in parser.context === false) {
|
||||
throw new Error('Unknown context `' + context + '`');
|
||||
do {
|
||||
type = this.lookupType(offset++);
|
||||
if (type !== WhiteSpace) {
|
||||
return type;
|
||||
}
|
||||
} while (type !== NULL);
|
||||
|
||||
return NULL;
|
||||
},
|
||||
|
||||
charCodeAt(offset) {
|
||||
return offset >= 0 && offset < source.length ?
|
||||
source.charCodeAt(offset)
|
||||
: 0;
|
||||
},
|
||||
substring(offsetStart, offsetEnd) {
|
||||
return source.substring(offsetStart, offsetEnd);
|
||||
},
|
||||
substrToCursor(start) {
|
||||
return this.source.substring(start, this.tokenStart);
|
||||
},
|
||||
|
||||
cmpChar(offset, charCode) {
|
||||
return cmpChar(source, offset, charCode);
|
||||
},
|
||||
cmpStr(offsetStart, offsetEnd, str) {
|
||||
return cmpStr(source, offsetStart, offsetEnd, str);
|
||||
},
|
||||
|
||||
consume(tokenType) {
|
||||
const start = this.tokenStart;
|
||||
|
||||
this.eat(tokenType);
|
||||
|
||||
return this.substrToCursor(start);
|
||||
},
|
||||
consumeFunctionName() {
|
||||
const name = source.substring(this.tokenStart, this.tokenEnd - 1);
|
||||
|
||||
this.eat(FunctionToken);
|
||||
|
||||
return name;
|
||||
},
|
||||
consumeNumber(type) {
|
||||
const number = source.substring(
|
||||
this.tokenStart,
|
||||
consumeNumber(source, this.tokenStart)
|
||||
);
|
||||
|
||||
this.eat(type);
|
||||
|
||||
return number;
|
||||
},
|
||||
|
||||
eat(tokenType) {
|
||||
if (this.tokenType !== tokenType) {
|
||||
const tokenName = tokenNames[tokenType]
|
||||
.slice(0, -6)
|
||||
.replace(/-/g, ' ')
|
||||
.replace(/^./, (m) => m.toUpperCase());
|
||||
let message = `${/[[\](){}]/.test(tokenName) ? `"${tokenName}"` : tokenName} is expected`;
|
||||
let offset = this.tokenStart;
|
||||
|
||||
// tweak message and offset
|
||||
switch (tokenType) {
|
||||
case Ident:
|
||||
// when identifier is expected but there is a function or url
|
||||
if (this.tokenType === FunctionToken || this.tokenType === Url) {
|
||||
offset = this.tokenEnd - 1;
|
||||
message = 'Identifier is expected but function found';
|
||||
} else {
|
||||
message = 'Identifier is expected';
|
||||
}
|
||||
break;
|
||||
|
||||
case Hash:
|
||||
if (this.isDelim(NUMBERSIGN)) {
|
||||
this.next();
|
||||
offset++;
|
||||
message = 'Name is expected';
|
||||
}
|
||||
break;
|
||||
|
||||
case Percentage:
|
||||
if (this.tokenType === NumberToken) {
|
||||
offset = this.tokenEnd;
|
||||
message = 'Percent sign is expected';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (typeof onComment === 'function') {
|
||||
parser.forEachToken((type, start, end) => {
|
||||
if (type === Comment) {
|
||||
const loc = parser.getLocation(start, end);
|
||||
const value = cmpStr(source, end - 2, end, '*/')
|
||||
? source.slice(start + 2, end - 2)
|
||||
: source.slice(start + 2, end);
|
||||
this.error(message, offset);
|
||||
}
|
||||
|
||||
onComment(value, loc);
|
||||
}
|
||||
});
|
||||
this.next();
|
||||
},
|
||||
eatIdent(name) {
|
||||
if (this.tokenType !== Ident || this.lookupValue(0, name) === false) {
|
||||
this.error(`Identifier "${name}" is expected`);
|
||||
}
|
||||
|
||||
this.next();
|
||||
},
|
||||
eatDelim(code) {
|
||||
if (!this.isDelim(code)) {
|
||||
this.error(`Delim "${String.fromCharCode(code)}" is expected`);
|
||||
}
|
||||
|
||||
this.next();
|
||||
},
|
||||
|
||||
getLocation(start, end) {
|
||||
if (needPositions) {
|
||||
return locationMap.getLocationRange(start, end, filename);
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
getLocationFromList(list) {
|
||||
if (needPositions) {
|
||||
const head = this.getFirstListNode(list);
|
||||
const tail = this.getLastListNode(list);
|
||||
return locationMap.getLocationRange(
|
||||
head !== null ?
|
||||
head.loc.start.offset - locationMap.startOffset
|
||||
: this.tokenStart,
|
||||
tail !== null ?
|
||||
tail.loc.end.offset - locationMap.startOffset
|
||||
: this.tokenStart,
|
||||
filename
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
error(message, offset) {
|
||||
const location =
|
||||
typeof offset !== 'undefined' && offset < source.length ?
|
||||
locationMap.getLocation(offset)
|
||||
: this.eof ?
|
||||
locationMap.getLocation(
|
||||
findWhiteSpaceStart(source, source.length - 1)
|
||||
)
|
||||
: locationMap.getLocation(this.tokenStart);
|
||||
|
||||
throw new SyntaxError(
|
||||
message || 'Unexpected input',
|
||||
source,
|
||||
location.offset,
|
||||
location.line,
|
||||
location.column
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const parse = function (source_, options) {
|
||||
source = source_;
|
||||
options = options || {};
|
||||
|
||||
parser.setSource(source, tokenize);
|
||||
locationMap.setSource(source, options.offset, options.line, options.column);
|
||||
|
||||
filename = options.filename || '<unknown>';
|
||||
needPositions = Boolean(options.positions);
|
||||
onParseError =
|
||||
typeof options.onParseError === 'function' ? options.onParseError : NOOP;
|
||||
onParseErrorThrow = false;
|
||||
|
||||
parser.parseAtrulePrelude =
|
||||
'parseAtrulePrelude' in options ?
|
||||
Boolean(options.parseAtrulePrelude)
|
||||
: true;
|
||||
parser.parseRulePrelude =
|
||||
'parseRulePrelude' in options ? Boolean(options.parseRulePrelude) : true;
|
||||
parser.parseValue =
|
||||
'parseValue' in options ? Boolean(options.parseValue) : true;
|
||||
parser.parseCustomProperty =
|
||||
'parseCustomProperty' in options ?
|
||||
Boolean(options.parseCustomProperty)
|
||||
: false;
|
||||
|
||||
const { context = 'default', onComment } = options;
|
||||
|
||||
if (context in parser.context === false) {
|
||||
throw new Error('Unknown context `' + context + '`');
|
||||
}
|
||||
|
||||
if (typeof onComment === 'function') {
|
||||
parser.forEachToken((type, start, end) => {
|
||||
if (type === Comment) {
|
||||
const loc = parser.getLocation(start, end);
|
||||
const value =
|
||||
cmpStr(source, end - 2, end, '*/') ?
|
||||
source.slice(start + 2, end - 2)
|
||||
: source.slice(start + 2, end);
|
||||
|
||||
onComment(value, loc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const ast = parser.context[context].call(parser, options);
|
||||
const ast = parser.context[context].call(parser, options);
|
||||
|
||||
if (!parser.eof) {
|
||||
parser.error();
|
||||
}
|
||||
if (!parser.eof) {
|
||||
parser.error();
|
||||
}
|
||||
|
||||
return ast;
|
||||
};
|
||||
return ast;
|
||||
};
|
||||
|
||||
return Object.assign(parse, {
|
||||
SyntaxError,
|
||||
config: parser.config
|
||||
});
|
||||
};
|
||||
return Object.assign(parse, {
|
||||
SyntaxError,
|
||||
config: parser.config,
|
||||
});
|
||||
}
|
||||
|
68
node_modules/css-tree/lib/parser/sequence.js
generated
vendored
68
node_modules/css-tree/lib/parser/sequence.js
generated
vendored
@ -1,43 +1,43 @@
|
||||
import { WhiteSpace, Comment } from '../tokenizer/index.js';
|
||||
|
||||
export function readSequence(recognizer) {
|
||||
const children = this.createList();
|
||||
let space = false;
|
||||
const context = {
|
||||
recognizer
|
||||
};
|
||||
const children = this.createList();
|
||||
let space = false;
|
||||
const context = {
|
||||
recognizer,
|
||||
};
|
||||
|
||||
while (!this.eof) {
|
||||
switch (this.tokenType) {
|
||||
case Comment:
|
||||
this.next();
|
||||
continue;
|
||||
while (!this.eof) {
|
||||
switch (this.tokenType) {
|
||||
case Comment:
|
||||
this.next();
|
||||
continue;
|
||||
|
||||
case WhiteSpace:
|
||||
space = true;
|
||||
this.next();
|
||||
continue;
|
||||
}
|
||||
|
||||
let child = recognizer.getNode.call(this, context);
|
||||
|
||||
if (child === undefined) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (space) {
|
||||
if (recognizer.onWhiteSpace) {
|
||||
recognizer.onWhiteSpace.call(this, child, children, context);
|
||||
}
|
||||
space = false;
|
||||
}
|
||||
|
||||
children.push(child);
|
||||
case WhiteSpace:
|
||||
space = true;
|
||||
this.next();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (space && recognizer.onWhiteSpace) {
|
||||
recognizer.onWhiteSpace.call(this, null, children, context);
|
||||
let child = recognizer.getNode.call(this, context);
|
||||
|
||||
if (child === undefined) {
|
||||
break;
|
||||
}
|
||||
|
||||
return children;
|
||||
};
|
||||
if (space) {
|
||||
if (recognizer.onWhiteSpace) {
|
||||
recognizer.onWhiteSpace.call(this, child, children, context);
|
||||
}
|
||||
space = false;
|
||||
}
|
||||
|
||||
children.push(child);
|
||||
}
|
||||
|
||||
if (space && recognizer.onWhiteSpace) {
|
||||
recognizer.onWhiteSpace.call(this, null, children, context);
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
12
node_modules/css-tree/lib/syntax/atrule/font-face.js
generated
vendored
12
node_modules/css-tree/lib/syntax/atrule/font-face.js
generated
vendored
@ -1,8 +1,8 @@
|
||||
export default {
|
||||
parse: {
|
||||
prelude: null,
|
||||
block() {
|
||||
return this.Block(true);
|
||||
}
|
||||
}
|
||||
parse: {
|
||||
prelude: null,
|
||||
block() {
|
||||
return this.Block(true);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
58
node_modules/css-tree/lib/syntax/atrule/import.js
generated
vendored
58
node_modules/css-tree/lib/syntax/atrule/import.js
generated
vendored
@ -1,39 +1,41 @@
|
||||
import {
|
||||
String as StringToken,
|
||||
Ident,
|
||||
Url,
|
||||
Function as FunctionToken,
|
||||
LeftParenthesis
|
||||
String as StringToken,
|
||||
Ident,
|
||||
Url,
|
||||
Function as FunctionToken,
|
||||
LeftParenthesis,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
export default {
|
||||
parse: {
|
||||
prelude() {
|
||||
const children = this.createList();
|
||||
parse: {
|
||||
prelude() {
|
||||
const children = this.createList();
|
||||
|
||||
this.skipSC();
|
||||
this.skipSC();
|
||||
|
||||
switch (this.tokenType) {
|
||||
case StringToken:
|
||||
children.push(this.String());
|
||||
break;
|
||||
switch (this.tokenType) {
|
||||
case StringToken:
|
||||
children.push(this.String());
|
||||
break;
|
||||
|
||||
case Url:
|
||||
case FunctionToken:
|
||||
children.push(this.Url());
|
||||
break;
|
||||
case Url:
|
||||
case FunctionToken:
|
||||
children.push(this.Url());
|
||||
break;
|
||||
|
||||
default:
|
||||
this.error('String or url() is expected');
|
||||
}
|
||||
default:
|
||||
this.error('String or url() is expected');
|
||||
}
|
||||
|
||||
if (this.lookupNonWSType(0) === Ident ||
|
||||
this.lookupNonWSType(0) === LeftParenthesis) {
|
||||
children.push(this.MediaQueryList());
|
||||
}
|
||||
if (
|
||||
this.lookupNonWSType(0) === Ident ||
|
||||
this.lookupNonWSType(0) === LeftParenthesis
|
||||
) {
|
||||
children.push(this.MediaQueryList());
|
||||
}
|
||||
|
||||
return children;
|
||||
},
|
||||
block: null
|
||||
}
|
||||
return children;
|
||||
},
|
||||
block: null,
|
||||
},
|
||||
};
|
||||
|
10
node_modules/css-tree/lib/syntax/atrule/index.js
generated
vendored
10
node_modules/css-tree/lib/syntax/atrule/index.js
generated
vendored
@ -5,9 +5,9 @@ import page from './page.js';
|
||||
import supports from './supports.js';
|
||||
|
||||
export default {
|
||||
'font-face': fontFace,
|
||||
'import': importAtrule,
|
||||
media,
|
||||
page,
|
||||
supports
|
||||
'font-face': fontFace,
|
||||
import: importAtrule,
|
||||
media,
|
||||
page,
|
||||
supports,
|
||||
};
|
||||
|
18
node_modules/css-tree/lib/syntax/atrule/media.js
generated
vendored
18
node_modules/css-tree/lib/syntax/atrule/media.js
generated
vendored
@ -1,12 +1,10 @@
|
||||
export default {
|
||||
parse: {
|
||||
prelude() {
|
||||
return this.createSingleNodeList(
|
||||
this.MediaQueryList()
|
||||
);
|
||||
},
|
||||
block() {
|
||||
return this.Block(false);
|
||||
}
|
||||
}
|
||||
parse: {
|
||||
prelude() {
|
||||
return this.createSingleNodeList(this.MediaQueryList());
|
||||
},
|
||||
block() {
|
||||
return this.Block(false);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
18
node_modules/css-tree/lib/syntax/atrule/page.js
generated
vendored
18
node_modules/css-tree/lib/syntax/atrule/page.js
generated
vendored
@ -1,12 +1,10 @@
|
||||
export default {
|
||||
parse: {
|
||||
prelude() {
|
||||
return this.createSingleNodeList(
|
||||
this.SelectorList()
|
||||
);
|
||||
},
|
||||
block() {
|
||||
return this.Block(true);
|
||||
}
|
||||
}
|
||||
parse: {
|
||||
prelude() {
|
||||
return this.createSingleNodeList(this.SelectorList());
|
||||
},
|
||||
block() {
|
||||
return this.Block(true);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
102
node_modules/css-tree/lib/syntax/atrule/supports.js
generated
vendored
102
node_modules/css-tree/lib/syntax/atrule/supports.js
generated
vendored
@ -1,80 +1,74 @@
|
||||
import {
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
Ident,
|
||||
Function,
|
||||
Colon,
|
||||
LeftParenthesis
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
Ident,
|
||||
Function,
|
||||
Colon,
|
||||
LeftParenthesis,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
function consumeRaw() {
|
||||
return this.createSingleNodeList(
|
||||
this.Raw(this.tokenIndex, null, false)
|
||||
);
|
||||
return this.createSingleNodeList(this.Raw(this.tokenIndex, null, false));
|
||||
}
|
||||
|
||||
function parentheses() {
|
||||
this.skipSC();
|
||||
this.skipSC();
|
||||
|
||||
if (this.tokenType === Ident &&
|
||||
this.lookupNonWSType(1) === Colon) {
|
||||
return this.createSingleNodeList(
|
||||
this.Declaration()
|
||||
);
|
||||
}
|
||||
if (this.tokenType === Ident && this.lookupNonWSType(1) === Colon) {
|
||||
return this.createSingleNodeList(this.Declaration());
|
||||
}
|
||||
|
||||
return readSequence.call(this);
|
||||
return readSequence.call(this);
|
||||
}
|
||||
|
||||
function readSequence() {
|
||||
const children = this.createList();
|
||||
let child;
|
||||
const children = this.createList();
|
||||
let child;
|
||||
|
||||
this.skipSC();
|
||||
this.skipSC();
|
||||
|
||||
scan:
|
||||
while (!this.eof) {
|
||||
switch (this.tokenType) {
|
||||
case Comment:
|
||||
case WhiteSpace:
|
||||
this.next();
|
||||
continue;
|
||||
scan: while (!this.eof) {
|
||||
switch (this.tokenType) {
|
||||
case Comment:
|
||||
case WhiteSpace:
|
||||
this.next();
|
||||
continue;
|
||||
|
||||
case Function:
|
||||
child = this.Function(consumeRaw, this.scope.AtrulePrelude);
|
||||
break;
|
||||
case Function:
|
||||
child = this.Function(consumeRaw, this.scope.AtrulePrelude);
|
||||
break;
|
||||
|
||||
case Ident:
|
||||
child = this.Identifier();
|
||||
break;
|
||||
case Ident:
|
||||
child = this.Identifier();
|
||||
break;
|
||||
|
||||
case LeftParenthesis:
|
||||
child = this.Parentheses(parentheses, this.scope.AtrulePrelude);
|
||||
break;
|
||||
case LeftParenthesis:
|
||||
child = this.Parentheses(parentheses, this.scope.AtrulePrelude);
|
||||
break;
|
||||
|
||||
default:
|
||||
break scan;
|
||||
}
|
||||
|
||||
children.push(child);
|
||||
default:
|
||||
break scan;
|
||||
}
|
||||
|
||||
return children;
|
||||
children.push(child);
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
export default {
|
||||
parse: {
|
||||
prelude() {
|
||||
const children = readSequence.call(this);
|
||||
parse: {
|
||||
prelude() {
|
||||
const children = readSequence.call(this);
|
||||
|
||||
if (this.getFirstListNode(children) === null) {
|
||||
this.error('Condition is expected');
|
||||
}
|
||||
if (this.getFirstListNode(children) === null) {
|
||||
this.error('Condition is expected');
|
||||
}
|
||||
|
||||
return children;
|
||||
},
|
||||
block() {
|
||||
return this.Block(false);
|
||||
}
|
||||
}
|
||||
return children;
|
||||
},
|
||||
block() {
|
||||
return this.Block(false);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
2
node_modules/css-tree/lib/syntax/config/generator.js
generated
vendored
2
node_modules/css-tree/lib/syntax/config/generator.js
generated
vendored
@ -1,5 +1,5 @@
|
||||
import * as node from '../node/index-generate.js';
|
||||
|
||||
export default {
|
||||
node
|
||||
node,
|
||||
};
|
||||
|
6
node_modules/css-tree/lib/syntax/config/lexer.js
generated
vendored
6
node_modules/css-tree/lib/syntax/config/lexer.js
generated
vendored
@ -2,7 +2,7 @@ import definitions from '../../data.js';
|
||||
import * as node from '../node/index.js';
|
||||
|
||||
export default {
|
||||
generic: true,
|
||||
...definitions,
|
||||
node
|
||||
generic: true,
|
||||
...definitions,
|
||||
node,
|
||||
};
|
||||
|
199
node_modules/css-tree/lib/syntax/config/mix.js
generated
vendored
199
node_modules/css-tree/lib/syntax/config/mix.js
generated
vendored
@ -1,138 +1,135 @@
|
||||
const { hasOwnProperty } = Object.prototype;
|
||||
const shape = {
|
||||
generic: true,
|
||||
types: appendOrAssign,
|
||||
atrules: {
|
||||
prelude: appendOrAssignOrNull,
|
||||
descriptors: appendOrAssignOrNull
|
||||
},
|
||||
properties: appendOrAssign,
|
||||
parseContext: assign,
|
||||
scope: deepAssign,
|
||||
atrule: ['parse'],
|
||||
pseudo: ['parse'],
|
||||
node: ['name', 'structure', 'parse', 'generate', 'walkContext']
|
||||
generic: true,
|
||||
types: appendOrAssign,
|
||||
atrules: {
|
||||
prelude: appendOrAssignOrNull,
|
||||
descriptors: appendOrAssignOrNull,
|
||||
},
|
||||
properties: appendOrAssign,
|
||||
parseContext: assign,
|
||||
scope: deepAssign,
|
||||
atrule: ['parse'],
|
||||
pseudo: ['parse'],
|
||||
node: ['name', 'structure', 'parse', 'generate', 'walkContext'],
|
||||
};
|
||||
|
||||
function isObject(value) {
|
||||
return value && value.constructor === Object;
|
||||
return value && value.constructor === Object;
|
||||
}
|
||||
|
||||
function copy(value) {
|
||||
return isObject(value)
|
||||
? { ...value }
|
||||
: value;
|
||||
return isObject(value) ? { ...value } : value;
|
||||
}
|
||||
|
||||
function assign(dest, src) {
|
||||
return Object.assign(dest, src);
|
||||
return Object.assign(dest, src);
|
||||
}
|
||||
|
||||
function deepAssign(dest, src) {
|
||||
for (const key in src) {
|
||||
if (hasOwnProperty.call(src, key)) {
|
||||
if (isObject(dest[key])) {
|
||||
deepAssign(dest[key], src[key]);
|
||||
} else {
|
||||
dest[key] = copy(src[key]);
|
||||
}
|
||||
}
|
||||
for (const key in src) {
|
||||
if (hasOwnProperty.call(src, key)) {
|
||||
if (isObject(dest[key])) {
|
||||
deepAssign(dest[key], src[key]);
|
||||
} else {
|
||||
dest[key] = copy(src[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dest;
|
||||
return dest;
|
||||
}
|
||||
|
||||
function append(a, b) {
|
||||
if (typeof b === 'string' && /^\s*\|/.test(b)) {
|
||||
return typeof a === 'string'
|
||||
? a + b
|
||||
: b.replace(/^\s*\|\s*/, '');
|
||||
}
|
||||
if (typeof b === 'string' && /^\s*\|/.test(b)) {
|
||||
return typeof a === 'string' ? a + b : b.replace(/^\s*\|\s*/, '');
|
||||
}
|
||||
|
||||
return b || null;
|
||||
return b || null;
|
||||
}
|
||||
|
||||
function appendOrAssign(a, b) {
|
||||
if (typeof b === 'string') {
|
||||
return append(a, b);
|
||||
}
|
||||
if (typeof b === 'string') {
|
||||
return append(a, b);
|
||||
}
|
||||
|
||||
const result = { ...a };
|
||||
for (let key in b) {
|
||||
if (hasOwnProperty.call(b, key)) {
|
||||
result[key] = append(hasOwnProperty.call(a, key) ? a[key] : undefined, b[key]);
|
||||
}
|
||||
const result = { ...a };
|
||||
for (let key in b) {
|
||||
if (hasOwnProperty.call(b, key)) {
|
||||
result[key] = append(
|
||||
hasOwnProperty.call(a, key) ? a[key] : undefined,
|
||||
b[key]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function appendOrAssignOrNull(a, b) {
|
||||
const result = appendOrAssign(a, b);
|
||||
const result = appendOrAssign(a, b);
|
||||
|
||||
return !isObject(result) || Object.keys(result).length
|
||||
? result
|
||||
: null;
|
||||
return !isObject(result) || Object.keys(result).length ? result : null;
|
||||
}
|
||||
|
||||
function mix(dest, src, shape) {
|
||||
for (const key in shape) {
|
||||
if (hasOwnProperty.call(shape, key) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (shape[key] === true) {
|
||||
if (hasOwnProperty.call(src, key)) {
|
||||
dest[key] = copy(src[key]);
|
||||
}
|
||||
} else if (shape[key]) {
|
||||
if (typeof shape[key] === 'function') {
|
||||
const fn = shape[key];
|
||||
dest[key] = fn({}, dest[key]);
|
||||
dest[key] = fn(dest[key] || {}, src[key]);
|
||||
} else if (isObject(shape[key])) {
|
||||
const result = {};
|
||||
|
||||
for (let name in dest[key]) {
|
||||
result[name] = mix({}, dest[key][name], shape[key]);
|
||||
}
|
||||
|
||||
for (let name in src[key]) {
|
||||
result[name] = mix(result[name] || {}, src[key][name], shape[key]);
|
||||
}
|
||||
|
||||
dest[key] = result;
|
||||
} else if (Array.isArray(shape[key])) {
|
||||
const res = {};
|
||||
const innerShape = shape[key].reduce(function(s, k) {
|
||||
s[k] = true;
|
||||
return s;
|
||||
}, {});
|
||||
|
||||
for (const [name, value] of Object.entries(dest[key] || {})) {
|
||||
res[name] = {};
|
||||
if (value) {
|
||||
mix(res[name], value, innerShape);
|
||||
}
|
||||
}
|
||||
|
||||
for (const name in src[key]) {
|
||||
if (hasOwnProperty.call(src[key], name)) {
|
||||
if (!res[name]) {
|
||||
res[name] = {};
|
||||
}
|
||||
|
||||
if (src[key] && src[key][name]) {
|
||||
mix(res[name], src[key][name], innerShape);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dest[key] = res;
|
||||
}
|
||||
}
|
||||
for (const key in shape) {
|
||||
if (hasOwnProperty.call(shape, key) === false) {
|
||||
continue;
|
||||
}
|
||||
return dest;
|
||||
|
||||
if (shape[key] === true) {
|
||||
if (hasOwnProperty.call(src, key)) {
|
||||
dest[key] = copy(src[key]);
|
||||
}
|
||||
} else if (shape[key]) {
|
||||
if (typeof shape[key] === 'function') {
|
||||
const fn = shape[key];
|
||||
dest[key] = fn({}, dest[key]);
|
||||
dest[key] = fn(dest[key] || {}, src[key]);
|
||||
} else if (isObject(shape[key])) {
|
||||
const result = {};
|
||||
|
||||
for (let name in dest[key]) {
|
||||
result[name] = mix({}, dest[key][name], shape[key]);
|
||||
}
|
||||
|
||||
for (let name in src[key]) {
|
||||
result[name] = mix(result[name] || {}, src[key][name], shape[key]);
|
||||
}
|
||||
|
||||
dest[key] = result;
|
||||
} else if (Array.isArray(shape[key])) {
|
||||
const res = {};
|
||||
const innerShape = shape[key].reduce(function (s, k) {
|
||||
s[k] = true;
|
||||
return s;
|
||||
}, {});
|
||||
|
||||
for (const [name, value] of Object.entries(dest[key] || {})) {
|
||||
res[name] = {};
|
||||
if (value) {
|
||||
mix(res[name], value, innerShape);
|
||||
}
|
||||
}
|
||||
|
||||
for (const name in src[key]) {
|
||||
if (hasOwnProperty.call(src[key], name)) {
|
||||
if (!res[name]) {
|
||||
res[name] = {};
|
||||
}
|
||||
|
||||
if (src[key] && src[key][name]) {
|
||||
mix(res[name], src[key][name], innerShape);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dest[key] = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
export default (dest, src) => mix(dest, src, shape);
|
||||
|
18
node_modules/css-tree/lib/syntax/config/parser-selector.js
generated
vendored
18
node_modules/css-tree/lib/syntax/config/parser-selector.js
generated
vendored
@ -3,13 +3,13 @@ import pseudo from '../pseudo/index.js';
|
||||
import * as node from '../node/index-parse-selector.js';
|
||||
|
||||
export default {
|
||||
parseContext: {
|
||||
default: 'SelectorList',
|
||||
selectorList: 'SelectorList',
|
||||
selector: 'Selector'
|
||||
},
|
||||
scope: { Selector },
|
||||
atrule: {},
|
||||
pseudo,
|
||||
node
|
||||
parseContext: {
|
||||
default: 'SelectorList',
|
||||
selectorList: 'SelectorList',
|
||||
selector: 'Selector',
|
||||
},
|
||||
scope: { Selector },
|
||||
atrule: {},
|
||||
pseudo,
|
||||
node,
|
||||
};
|
||||
|
44
node_modules/css-tree/lib/syntax/config/parser.js
generated
vendored
44
node_modules/css-tree/lib/syntax/config/parser.js
generated
vendored
@ -4,27 +4,27 @@ import pseudo from '../pseudo/index.js';
|
||||
import * as node from '../node/index-parse.js';
|
||||
|
||||
export default {
|
||||
parseContext: {
|
||||
default: 'StyleSheet',
|
||||
stylesheet: 'StyleSheet',
|
||||
atrule: 'Atrule',
|
||||
atrulePrelude(options) {
|
||||
return this.AtrulePrelude(options.atrule ? String(options.atrule) : null);
|
||||
},
|
||||
mediaQueryList: 'MediaQueryList',
|
||||
mediaQuery: 'MediaQuery',
|
||||
rule: 'Rule',
|
||||
selectorList: 'SelectorList',
|
||||
selector: 'Selector',
|
||||
block() {
|
||||
return this.Block(true);
|
||||
},
|
||||
declarationList: 'DeclarationList',
|
||||
declaration: 'Declaration',
|
||||
value: 'Value'
|
||||
parseContext: {
|
||||
default: 'StyleSheet',
|
||||
stylesheet: 'StyleSheet',
|
||||
atrule: 'Atrule',
|
||||
atrulePrelude(options) {
|
||||
return this.AtrulePrelude(options.atrule ? String(options.atrule) : null);
|
||||
},
|
||||
scope,
|
||||
atrule,
|
||||
pseudo,
|
||||
node
|
||||
mediaQueryList: 'MediaQueryList',
|
||||
mediaQuery: 'MediaQuery',
|
||||
rule: 'Rule',
|
||||
selectorList: 'SelectorList',
|
||||
selector: 'Selector',
|
||||
block() {
|
||||
return this.Block(true);
|
||||
},
|
||||
declarationList: 'DeclarationList',
|
||||
declaration: 'Declaration',
|
||||
value: 'Value',
|
||||
},
|
||||
scope,
|
||||
atrule,
|
||||
pseudo,
|
||||
node,
|
||||
};
|
||||
|
2
node_modules/css-tree/lib/syntax/config/walker.js
generated
vendored
2
node_modules/css-tree/lib/syntax/config/walker.js
generated
vendored
@ -1,5 +1,5 @@
|
||||
import * as node from '../node/index.js';
|
||||
|
||||
export default {
|
||||
node
|
||||
node,
|
||||
};
|
||||
|
73
node_modules/css-tree/lib/syntax/create.js
generated
vendored
73
node_modules/css-tree/lib/syntax/create.js
generated
vendored
@ -7,47 +7,50 @@ import { Lexer } from '../lexer/Lexer.js';
|
||||
import mix from './config/mix.js';
|
||||
|
||||
function createSyntax(config) {
|
||||
const parse = createParser(config);
|
||||
const walk = createWalker(config);
|
||||
const generate = createGenerator(config);
|
||||
const { fromPlainObject, toPlainObject } = createConvertor(walk);
|
||||
const parse = createParser(config);
|
||||
const walk = createWalker(config);
|
||||
const generate = createGenerator(config);
|
||||
const { fromPlainObject, toPlainObject } = createConvertor(walk);
|
||||
|
||||
const syntax = {
|
||||
lexer: null,
|
||||
createLexer: config => new Lexer(config, syntax, syntax.lexer.structure),
|
||||
const syntax = {
|
||||
lexer: null,
|
||||
createLexer: (config) => new Lexer(config, syntax, syntax.lexer.structure),
|
||||
|
||||
tokenize,
|
||||
parse,
|
||||
generate,
|
||||
tokenize,
|
||||
parse,
|
||||
generate,
|
||||
|
||||
walk,
|
||||
find: walk.find,
|
||||
findLast: walk.findLast,
|
||||
findAll: walk.findAll,
|
||||
walk,
|
||||
find: walk.find,
|
||||
findLast: walk.findLast,
|
||||
findAll: walk.findAll,
|
||||
|
||||
fromPlainObject,
|
||||
toPlainObject,
|
||||
fromPlainObject,
|
||||
toPlainObject,
|
||||
|
||||
fork(extension) {
|
||||
const base = mix({}, config); // copy of config
|
||||
fork(extension) {
|
||||
const base = mix({}, config); // copy of config
|
||||
|
||||
return createSyntax(
|
||||
typeof extension === 'function'
|
||||
? extension(base, Object.assign)
|
||||
: mix(base, extension)
|
||||
);
|
||||
}
|
||||
};
|
||||
return createSyntax(
|
||||
typeof extension === 'function' ?
|
||||
extension(base, Object.assign)
|
||||
: mix(base, extension)
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
syntax.lexer = new Lexer({
|
||||
generic: true,
|
||||
types: config.types,
|
||||
atrules: config.atrules,
|
||||
properties: config.properties,
|
||||
node: config.node
|
||||
}, syntax);
|
||||
syntax.lexer = new Lexer(
|
||||
{
|
||||
generic: true,
|
||||
types: config.types,
|
||||
atrules: config.atrules,
|
||||
properties: config.properties,
|
||||
node: config.node,
|
||||
},
|
||||
syntax
|
||||
);
|
||||
|
||||
return syntax;
|
||||
};
|
||||
return syntax;
|
||||
}
|
||||
|
||||
export default config => createSyntax(mix({}, config));
|
||||
export default (config) => createSyntax(mix({}, config));
|
||||
|
6
node_modules/css-tree/lib/syntax/function/expression.js
generated
vendored
6
node_modules/css-tree/lib/syntax/function/expression.js
generated
vendored
@ -1,7 +1,5 @@
|
||||
// legacy IE function
|
||||
// expression( <any-value> )
|
||||
export default function() {
|
||||
return this.createSingleNodeList(
|
||||
this.Raw(this.tokenIndex, null, false)
|
||||
);
|
||||
export default function () {
|
||||
return this.createSingleNodeList(this.Raw(this.tokenIndex, null, false));
|
||||
}
|
||||
|
59
node_modules/css-tree/lib/syntax/function/var.js
generated
vendored
59
node_modules/css-tree/lib/syntax/function/var.js
generated
vendored
@ -1,39 +1,44 @@
|
||||
import { Comma, WhiteSpace } from '../../tokenizer/index.js';
|
||||
|
||||
// var( <ident> , <value>? )
|
||||
export default function() {
|
||||
const children = this.createList();
|
||||
export default function () {
|
||||
const children = this.createList();
|
||||
|
||||
this.skipSC();
|
||||
this.skipSC();
|
||||
|
||||
// NOTE: Don't check more than a first argument is an ident, rest checks are for lexer
|
||||
children.push(this.Identifier());
|
||||
// NOTE: Don't check more than a first argument is an ident, rest checks are for lexer
|
||||
children.push(this.Identifier());
|
||||
|
||||
this.skipSC();
|
||||
this.skipSC();
|
||||
|
||||
if (this.tokenType === Comma) {
|
||||
children.push(this.Operator());
|
||||
if (this.tokenType === Comma) {
|
||||
children.push(this.Operator());
|
||||
|
||||
const startIndex = this.tokenIndex;
|
||||
const value = this.parseCustomProperty
|
||||
? this.Value(null)
|
||||
: this.Raw(this.tokenIndex, this.consumeUntilExclamationMarkOrSemicolon, false);
|
||||
const startIndex = this.tokenIndex;
|
||||
const value =
|
||||
this.parseCustomProperty ?
|
||||
this.Value(null)
|
||||
: this.Raw(
|
||||
this.tokenIndex,
|
||||
this.consumeUntilExclamationMarkOrSemicolon,
|
||||
false
|
||||
);
|
||||
|
||||
if (value.type === 'Value' && value.children.isEmpty) {
|
||||
for (let offset = startIndex - this.tokenIndex; offset <= 0; offset++) {
|
||||
if (this.lookupType(offset) === WhiteSpace) {
|
||||
value.children.appendData({
|
||||
type: 'WhiteSpace',
|
||||
loc: null,
|
||||
value: ' '
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (value.type === 'Value' && value.children.isEmpty) {
|
||||
for (let offset = startIndex - this.tokenIndex; offset <= 0; offset++) {
|
||||
if (this.lookupType(offset) === WhiteSpace) {
|
||||
value.children.appendData({
|
||||
type: 'WhiteSpace',
|
||||
loc: null,
|
||||
value: ' ',
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
children.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
return children;
|
||||
};
|
||||
children.push(value);
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
6
node_modules/css-tree/lib/syntax/index.js
generated
vendored
6
node_modules/css-tree/lib/syntax/index.js
generated
vendored
@ -4,7 +4,7 @@ import parserConfig from './config/parser.js';
|
||||
import walkerConfig from './config/walker.js';
|
||||
|
||||
export default createSyntax({
|
||||
...lexerConfig,
|
||||
...parserConfig,
|
||||
...walkerConfig
|
||||
...lexerConfig,
|
||||
...parserConfig,
|
||||
...walkerConfig,
|
||||
});
|
||||
|
449
node_modules/css-tree/lib/syntax/node/AnPlusB.js
generated
vendored
449
node_modules/css-tree/lib/syntax/node/AnPlusB.js
generated
vendored
@ -1,292 +1,297 @@
|
||||
import {
|
||||
isDigit,
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
Ident,
|
||||
Number,
|
||||
Dimension
|
||||
isDigit,
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
Ident,
|
||||
Number,
|
||||
Dimension,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
|
||||
const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)
|
||||
const N = 0x006E; // U+006E LATIN SMALL LETTER N (n)
|
||||
const PLUSSIGN = 0x002b; // U+002B PLUS SIGN (+)
|
||||
const HYPHENMINUS = 0x002d; // U+002D HYPHEN-MINUS (-)
|
||||
const N = 0x006e; // U+006E LATIN SMALL LETTER N (n)
|
||||
const DISALLOW_SIGN = true;
|
||||
const ALLOW_SIGN = false;
|
||||
|
||||
function checkInteger(offset, disallowSign) {
|
||||
let pos = this.tokenStart + offset;
|
||||
const code = this.charCodeAt(pos);
|
||||
let pos = this.tokenStart + offset;
|
||||
const code = this.charCodeAt(pos);
|
||||
|
||||
if (code === PLUSSIGN || code === HYPHENMINUS) {
|
||||
if (disallowSign) {
|
||||
this.error('Number sign is not allowed');
|
||||
}
|
||||
pos++;
|
||||
if (code === PLUSSIGN || code === HYPHENMINUS) {
|
||||
if (disallowSign) {
|
||||
this.error('Number sign is not allowed');
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
||||
for (; pos < this.tokenEnd; pos++) {
|
||||
if (!isDigit(this.charCodeAt(pos))) {
|
||||
this.error('Integer is expected', pos);
|
||||
}
|
||||
for (; pos < this.tokenEnd; pos++) {
|
||||
if (!isDigit(this.charCodeAt(pos))) {
|
||||
this.error('Integer is expected', pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkTokenIsInteger(disallowSign) {
|
||||
return checkInteger.call(this, 0, disallowSign);
|
||||
return checkInteger.call(this, 0, disallowSign);
|
||||
}
|
||||
|
||||
function expectCharCode(offset, code) {
|
||||
if (!this.cmpChar(this.tokenStart + offset, code)) {
|
||||
let msg = '';
|
||||
if (!this.cmpChar(this.tokenStart + offset, code)) {
|
||||
let msg = '';
|
||||
|
||||
switch (code) {
|
||||
case N:
|
||||
msg = 'N is expected';
|
||||
break;
|
||||
case HYPHENMINUS:
|
||||
msg = 'HyphenMinus is expected';
|
||||
break;
|
||||
}
|
||||
|
||||
this.error(msg, this.tokenStart + offset);
|
||||
switch (code) {
|
||||
case N:
|
||||
msg = 'N is expected';
|
||||
break;
|
||||
case HYPHENMINUS:
|
||||
msg = 'HyphenMinus is expected';
|
||||
break;
|
||||
}
|
||||
|
||||
this.error(msg, this.tokenStart + offset);
|
||||
}
|
||||
}
|
||||
|
||||
// ... <signed-integer>
|
||||
// ... ['+' | '-'] <signless-integer>
|
||||
function consumeB() {
|
||||
let offset = 0;
|
||||
let sign = 0;
|
||||
let type = this.tokenType;
|
||||
let offset = 0;
|
||||
let sign = 0;
|
||||
let type = this.tokenType;
|
||||
|
||||
while (type === WhiteSpace || type === Comment) {
|
||||
while (type === WhiteSpace || type === Comment) {
|
||||
type = this.lookupType(++offset);
|
||||
}
|
||||
|
||||
if (type !== Number) {
|
||||
if (this.isDelim(PLUSSIGN, offset) || this.isDelim(HYPHENMINUS, offset)) {
|
||||
sign = this.isDelim(PLUSSIGN, offset) ? PLUSSIGN : HYPHENMINUS;
|
||||
|
||||
do {
|
||||
type = this.lookupType(++offset);
|
||||
}
|
||||
} while (type === WhiteSpace || type === Comment);
|
||||
|
||||
if (type !== Number) {
|
||||
if (this.isDelim(PLUSSIGN, offset) ||
|
||||
this.isDelim(HYPHENMINUS, offset)) {
|
||||
sign = this.isDelim(PLUSSIGN, offset) ? PLUSSIGN : HYPHENMINUS;
|
||||
|
||||
do {
|
||||
type = this.lookupType(++offset);
|
||||
} while (type === WhiteSpace || type === Comment);
|
||||
|
||||
if (type !== Number) {
|
||||
this.skip(offset);
|
||||
checkTokenIsInteger.call(this, DISALLOW_SIGN);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (offset > 0) {
|
||||
if (type !== Number) {
|
||||
this.skip(offset);
|
||||
checkTokenIsInteger.call(this, DISALLOW_SIGN);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (sign === 0) {
|
||||
type = this.charCodeAt(this.tokenStart);
|
||||
if (type !== PLUSSIGN && type !== HYPHENMINUS) {
|
||||
this.error('Number sign is expected');
|
||||
}
|
||||
if (offset > 0) {
|
||||
this.skip(offset);
|
||||
}
|
||||
|
||||
if (sign === 0) {
|
||||
type = this.charCodeAt(this.tokenStart);
|
||||
if (type !== PLUSSIGN && type !== HYPHENMINUS) {
|
||||
this.error('Number sign is expected');
|
||||
}
|
||||
}
|
||||
|
||||
checkTokenIsInteger.call(this, sign !== 0);
|
||||
return sign === HYPHENMINUS ? '-' + this.consume(Number) : this.consume(Number);
|
||||
checkTokenIsInteger.call(this, sign !== 0);
|
||||
return sign === HYPHENMINUS ?
|
||||
'-' + this.consume(Number)
|
||||
: this.consume(Number);
|
||||
}
|
||||
|
||||
// An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
|
||||
export const name = 'AnPlusB';
|
||||
export const structure = {
|
||||
a: [String, null],
|
||||
b: [String, null]
|
||||
a: [String, null],
|
||||
b: [String, null],
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
/* eslint-disable brace-style*/
|
||||
const start = this.tokenStart;
|
||||
let a = null;
|
||||
let b = null;
|
||||
/* eslint-disable brace-style*/
|
||||
const start = this.tokenStart;
|
||||
let a = null;
|
||||
let b = null;
|
||||
|
||||
// <integer>
|
||||
if (this.tokenType === Number) {
|
||||
checkTokenIsInteger.call(this, ALLOW_SIGN);
|
||||
b = this.consume(Number);
|
||||
// <integer>
|
||||
if (this.tokenType === Number) {
|
||||
checkTokenIsInteger.call(this, ALLOW_SIGN);
|
||||
b = this.consume(Number);
|
||||
}
|
||||
|
||||
// -n
|
||||
// -n <signed-integer>
|
||||
// -n ['+' | '-'] <signless-integer>
|
||||
// -n- <signless-integer>
|
||||
// <dashndashdigit-ident>
|
||||
else if (
|
||||
this.tokenType === Ident &&
|
||||
this.cmpChar(this.tokenStart, HYPHENMINUS)
|
||||
) {
|
||||
a = '-1';
|
||||
|
||||
expectCharCode.call(this, 1, N);
|
||||
|
||||
switch (this.tokenEnd - this.tokenStart) {
|
||||
// -n
|
||||
// -n <signed-integer>
|
||||
// -n ['+' | '-'] <signless-integer>
|
||||
case 2:
|
||||
this.next();
|
||||
b = consumeB.call(this);
|
||||
break;
|
||||
|
||||
// -n- <signless-integer>
|
||||
case 3:
|
||||
expectCharCode.call(this, 2, HYPHENMINUS);
|
||||
|
||||
this.next();
|
||||
this.skipSC();
|
||||
|
||||
checkTokenIsInteger.call(this, DISALLOW_SIGN);
|
||||
|
||||
b = '-' + this.consume(Number);
|
||||
break;
|
||||
|
||||
// <dashndashdigit-ident>
|
||||
default:
|
||||
expectCharCode.call(this, 2, HYPHENMINUS);
|
||||
checkInteger.call(this, 3, DISALLOW_SIGN);
|
||||
this.next();
|
||||
|
||||
b = this.substrToCursor(start + 2);
|
||||
}
|
||||
}
|
||||
|
||||
// '+'? n
|
||||
// '+'? n <signed-integer>
|
||||
// '+'? n ['+' | '-'] <signless-integer>
|
||||
// '+'? n- <signless-integer>
|
||||
// '+'? <ndashdigit-ident>
|
||||
else if (
|
||||
this.tokenType === Ident ||
|
||||
(this.isDelim(PLUSSIGN) && this.lookupType(1) === Ident)
|
||||
) {
|
||||
let sign = 0;
|
||||
a = '1';
|
||||
|
||||
// just ignore a plus
|
||||
if (this.isDelim(PLUSSIGN)) {
|
||||
sign = 1;
|
||||
this.next();
|
||||
}
|
||||
|
||||
// -n
|
||||
// -n <signed-integer>
|
||||
// -n ['+' | '-'] <signless-integer>
|
||||
// -n- <signless-integer>
|
||||
// <dashndashdigit-ident>
|
||||
else if (this.tokenType === Ident && this.cmpChar(this.tokenStart, HYPHENMINUS)) {
|
||||
a = '-1';
|
||||
expectCharCode.call(this, 0, N);
|
||||
|
||||
expectCharCode.call(this, 1, N);
|
||||
switch (this.tokenEnd - this.tokenStart) {
|
||||
// '+'? n
|
||||
// '+'? n <signed-integer>
|
||||
// '+'? n ['+' | '-'] <signless-integer>
|
||||
case 1:
|
||||
this.next();
|
||||
b = consumeB.call(this);
|
||||
break;
|
||||
|
||||
switch (this.tokenEnd - this.tokenStart) {
|
||||
// -n
|
||||
// -n <signed-integer>
|
||||
// -n ['+' | '-'] <signless-integer>
|
||||
case 2:
|
||||
this.next();
|
||||
b = consumeB.call(this);
|
||||
break;
|
||||
// '+'? n- <signless-integer>
|
||||
case 2:
|
||||
expectCharCode.call(this, 1, HYPHENMINUS);
|
||||
|
||||
// -n- <signless-integer>
|
||||
case 3:
|
||||
expectCharCode.call(this, 2, HYPHENMINUS);
|
||||
this.next();
|
||||
this.skipSC();
|
||||
|
||||
this.next();
|
||||
this.skipSC();
|
||||
checkTokenIsInteger.call(this, DISALLOW_SIGN);
|
||||
|
||||
checkTokenIsInteger.call(this, DISALLOW_SIGN);
|
||||
b = '-' + this.consume(Number);
|
||||
break;
|
||||
|
||||
b = '-' + this.consume(Number);
|
||||
break;
|
||||
// '+'? <ndashdigit-ident>
|
||||
default:
|
||||
expectCharCode.call(this, 1, HYPHENMINUS);
|
||||
checkInteger.call(this, 2, DISALLOW_SIGN);
|
||||
this.next();
|
||||
|
||||
// <dashndashdigit-ident>
|
||||
default:
|
||||
expectCharCode.call(this, 2, HYPHENMINUS);
|
||||
checkInteger.call(this, 3, DISALLOW_SIGN);
|
||||
this.next();
|
||||
b = this.substrToCursor(start + sign + 1);
|
||||
}
|
||||
}
|
||||
|
||||
b = this.substrToCursor(start + 2);
|
||||
}
|
||||
// <ndashdigit-dimension>
|
||||
// <ndash-dimension> <signless-integer>
|
||||
// <n-dimension>
|
||||
// <n-dimension> <signed-integer>
|
||||
// <n-dimension> ['+' | '-'] <signless-integer>
|
||||
else if (this.tokenType === Dimension) {
|
||||
const code = this.charCodeAt(this.tokenStart);
|
||||
const sign = code === PLUSSIGN || code === HYPHENMINUS;
|
||||
let i = this.tokenStart + sign;
|
||||
|
||||
for (; i < this.tokenEnd; i++) {
|
||||
if (!isDigit(this.charCodeAt(i))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// '+'? n
|
||||
// '+'? n <signed-integer>
|
||||
// '+'? n ['+' | '-'] <signless-integer>
|
||||
// '+'? n- <signless-integer>
|
||||
// '+'? <ndashdigit-ident>
|
||||
else if (this.tokenType === Ident || (this.isDelim(PLUSSIGN) && this.lookupType(1) === Ident)) {
|
||||
let sign = 0;
|
||||
a = '1';
|
||||
|
||||
// just ignore a plus
|
||||
if (this.isDelim(PLUSSIGN)) {
|
||||
sign = 1;
|
||||
this.next();
|
||||
}
|
||||
|
||||
expectCharCode.call(this, 0, N);
|
||||
|
||||
switch (this.tokenEnd - this.tokenStart) {
|
||||
// '+'? n
|
||||
// '+'? n <signed-integer>
|
||||
// '+'? n ['+' | '-'] <signless-integer>
|
||||
case 1:
|
||||
this.next();
|
||||
b = consumeB.call(this);
|
||||
break;
|
||||
|
||||
// '+'? n- <signless-integer>
|
||||
case 2:
|
||||
expectCharCode.call(this, 1, HYPHENMINUS);
|
||||
|
||||
this.next();
|
||||
this.skipSC();
|
||||
|
||||
checkTokenIsInteger.call(this, DISALLOW_SIGN);
|
||||
|
||||
b = '-' + this.consume(Number);
|
||||
break;
|
||||
|
||||
// '+'? <ndashdigit-ident>
|
||||
default:
|
||||
expectCharCode.call(this, 1, HYPHENMINUS);
|
||||
checkInteger.call(this, 2, DISALLOW_SIGN);
|
||||
this.next();
|
||||
|
||||
b = this.substrToCursor(start + sign + 1);
|
||||
}
|
||||
if (i === this.tokenStart + sign) {
|
||||
this.error('Integer is expected', this.tokenStart + sign);
|
||||
}
|
||||
|
||||
// <ndashdigit-dimension>
|
||||
// <ndash-dimension> <signless-integer>
|
||||
expectCharCode.call(this, i - this.tokenStart, N);
|
||||
a = this.substring(start, i);
|
||||
|
||||
// <n-dimension>
|
||||
// <n-dimension> <signed-integer>
|
||||
// <n-dimension> ['+' | '-'] <signless-integer>
|
||||
else if (this.tokenType === Dimension) {
|
||||
const code = this.charCodeAt(this.tokenStart);
|
||||
const sign = code === PLUSSIGN || code === HYPHENMINUS;
|
||||
let i = this.tokenStart + sign;
|
||||
|
||||
for (; i < this.tokenEnd; i++) {
|
||||
if (!isDigit(this.charCodeAt(i))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i === this.tokenStart + sign) {
|
||||
this.error('Integer is expected', this.tokenStart + sign);
|
||||
}
|
||||
|
||||
expectCharCode.call(this, i - this.tokenStart, N);
|
||||
a = this.substring(start, i);
|
||||
|
||||
// <n-dimension>
|
||||
// <n-dimension> <signed-integer>
|
||||
// <n-dimension> ['+' | '-'] <signless-integer>
|
||||
if (i + 1 === this.tokenEnd) {
|
||||
this.next();
|
||||
b = consumeB.call(this);
|
||||
} else {
|
||||
expectCharCode.call(this, i - this.tokenStart + 1, HYPHENMINUS);
|
||||
|
||||
// <ndash-dimension> <signless-integer>
|
||||
if (i + 2 === this.tokenEnd) {
|
||||
this.next();
|
||||
this.skipSC();
|
||||
checkTokenIsInteger.call(this, DISALLOW_SIGN);
|
||||
b = '-' + this.consume(Number);
|
||||
}
|
||||
// <ndashdigit-dimension>
|
||||
else {
|
||||
checkInteger.call(this, i - this.tokenStart + 2, DISALLOW_SIGN);
|
||||
this.next();
|
||||
b = this.substrToCursor(i + 1);
|
||||
}
|
||||
}
|
||||
if (i + 1 === this.tokenEnd) {
|
||||
this.next();
|
||||
b = consumeB.call(this);
|
||||
} else {
|
||||
this.error();
|
||||
}
|
||||
expectCharCode.call(this, i - this.tokenStart + 1, HYPHENMINUS);
|
||||
|
||||
if (a !== null && a.charCodeAt(0) === PLUSSIGN) {
|
||||
a = a.substr(1);
|
||||
// <ndash-dimension> <signless-integer>
|
||||
if (i + 2 === this.tokenEnd) {
|
||||
this.next();
|
||||
this.skipSC();
|
||||
checkTokenIsInteger.call(this, DISALLOW_SIGN);
|
||||
b = '-' + this.consume(Number);
|
||||
}
|
||||
// <ndashdigit-dimension>
|
||||
else {
|
||||
checkInteger.call(this, i - this.tokenStart + 2, DISALLOW_SIGN);
|
||||
this.next();
|
||||
b = this.substrToCursor(i + 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.error();
|
||||
}
|
||||
|
||||
if (b !== null && b.charCodeAt(0) === PLUSSIGN) {
|
||||
b = b.substr(1);
|
||||
}
|
||||
if (a !== null && a.charCodeAt(0) === PLUSSIGN) {
|
||||
a = a.substr(1);
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'AnPlusB',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
a,
|
||||
b
|
||||
};
|
||||
if (b !== null && b.charCodeAt(0) === PLUSSIGN) {
|
||||
b = b.substr(1);
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'AnPlusB',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
a,
|
||||
b,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
if (node.a) {
|
||||
const a =
|
||||
node.a === '+1' && 'n' ||
|
||||
node.a === '1' && 'n' ||
|
||||
node.a === '-1' && '-n' ||
|
||||
node.a + 'n';
|
||||
if (node.a) {
|
||||
const a =
|
||||
(node.a === '+1' && 'n') ||
|
||||
(node.a === '1' && 'n') ||
|
||||
(node.a === '-1' && '-n') ||
|
||||
node.a + 'n';
|
||||
|
||||
if (node.b) {
|
||||
const b = node.b[0] === '-' || node.b[0] === '+'
|
||||
? node.b
|
||||
: '+' + node.b;
|
||||
this.tokenize(a + b);
|
||||
} else {
|
||||
this.tokenize(a);
|
||||
}
|
||||
if (node.b) {
|
||||
const b = node.b[0] === '-' || node.b[0] === '+' ? node.b : '+' + node.b;
|
||||
this.tokenize(a + b);
|
||||
} else {
|
||||
this.tokenize(node.b);
|
||||
this.tokenize(a);
|
||||
}
|
||||
} else {
|
||||
this.tokenize(node.b);
|
||||
}
|
||||
}
|
||||
|
149
node_modules/css-tree/lib/syntax/node/Atrule.js
generated
vendored
149
node_modules/css-tree/lib/syntax/node/Atrule.js
generated
vendored
@ -1,100 +1,109 @@
|
||||
import {
|
||||
AtKeyword,
|
||||
Semicolon,
|
||||
LeftCurlyBracket,
|
||||
RightCurlyBracket
|
||||
AtKeyword,
|
||||
Semicolon,
|
||||
LeftCurlyBracket,
|
||||
RightCurlyBracket,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
function consumeRaw(startToken) {
|
||||
return this.Raw(startToken, this.consumeUntilLeftCurlyBracketOrSemicolon, true);
|
||||
return this.Raw(
|
||||
startToken,
|
||||
this.consumeUntilLeftCurlyBracketOrSemicolon,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
function isDeclarationBlockAtrule() {
|
||||
for (let offset = 1, type; type = this.lookupType(offset); offset++) {
|
||||
if (type === RightCurlyBracket) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type === LeftCurlyBracket ||
|
||||
type === AtKeyword) {
|
||||
return false;
|
||||
}
|
||||
for (let offset = 1, type; (type = this.lookupType(offset)); offset++) {
|
||||
if (type === RightCurlyBracket) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
if (type === LeftCurlyBracket || type === AtKeyword) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export const name = 'Atrule';
|
||||
export const walkContext = 'atrule';
|
||||
export const structure = {
|
||||
name: String,
|
||||
prelude: ['AtrulePrelude', 'Raw', null],
|
||||
block: ['Block', null]
|
||||
name: String,
|
||||
prelude: ['AtrulePrelude', 'Raw', null],
|
||||
block: ['Block', null],
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
let name;
|
||||
let nameLowerCase;
|
||||
let prelude = null;
|
||||
let block = null;
|
||||
const start = this.tokenStart;
|
||||
let name;
|
||||
let nameLowerCase;
|
||||
let prelude = null;
|
||||
let block = null;
|
||||
|
||||
this.eat(AtKeyword);
|
||||
this.eat(AtKeyword);
|
||||
|
||||
name = this.substrToCursor(start + 1);
|
||||
nameLowerCase = name.toLowerCase();
|
||||
this.skipSC();
|
||||
|
||||
// parse prelude
|
||||
if (
|
||||
this.eof === false &&
|
||||
this.tokenType !== LeftCurlyBracket &&
|
||||
this.tokenType !== Semicolon
|
||||
) {
|
||||
if (this.parseAtrulePrelude) {
|
||||
prelude = this.parseWithFallback(
|
||||
this.AtrulePrelude.bind(this, name),
|
||||
consumeRaw
|
||||
);
|
||||
} else {
|
||||
prelude = consumeRaw.call(this, this.tokenIndex);
|
||||
}
|
||||
|
||||
name = this.substrToCursor(start + 1);
|
||||
nameLowerCase = name.toLowerCase();
|
||||
this.skipSC();
|
||||
}
|
||||
|
||||
// parse prelude
|
||||
if (this.eof === false &&
|
||||
this.tokenType !== LeftCurlyBracket &&
|
||||
this.tokenType !== Semicolon) {
|
||||
if (this.parseAtrulePrelude) {
|
||||
prelude = this.parseWithFallback(this.AtrulePrelude.bind(this, name), consumeRaw);
|
||||
} else {
|
||||
prelude = consumeRaw.call(this, this.tokenIndex);
|
||||
}
|
||||
switch (this.tokenType) {
|
||||
case Semicolon:
|
||||
this.next();
|
||||
break;
|
||||
|
||||
this.skipSC();
|
||||
}
|
||||
case LeftCurlyBracket:
|
||||
if (
|
||||
hasOwnProperty.call(this.atrule, nameLowerCase) &&
|
||||
typeof this.atrule[nameLowerCase].block === 'function'
|
||||
) {
|
||||
block = this.atrule[nameLowerCase].block.call(this);
|
||||
} else {
|
||||
// TODO: should consume block content as Raw?
|
||||
block = this.Block(isDeclarationBlockAtrule.call(this));
|
||||
}
|
||||
|
||||
switch (this.tokenType) {
|
||||
case Semicolon:
|
||||
this.next();
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
case LeftCurlyBracket:
|
||||
if (hasOwnProperty.call(this.atrule, nameLowerCase) &&
|
||||
typeof this.atrule[nameLowerCase].block === 'function') {
|
||||
block = this.atrule[nameLowerCase].block.call(this);
|
||||
} else {
|
||||
// TODO: should consume block content as Raw?
|
||||
block = this.Block(isDeclarationBlockAtrule.call(this));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Atrule',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name,
|
||||
prelude,
|
||||
block
|
||||
};
|
||||
return {
|
||||
type: 'Atrule',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name,
|
||||
prelude,
|
||||
block,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(AtKeyword, '@' + node.name);
|
||||
this.token(AtKeyword, '@' + node.name);
|
||||
|
||||
if (node.prelude !== null) {
|
||||
this.node(node.prelude);
|
||||
}
|
||||
if (node.prelude !== null) {
|
||||
this.node(node.prelude);
|
||||
}
|
||||
|
||||
if (node.block) {
|
||||
this.node(node.block);
|
||||
} else {
|
||||
this.token(Semicolon, ';');
|
||||
}
|
||||
if (node.block) {
|
||||
this.node(node.block);
|
||||
} else {
|
||||
this.token(Semicolon, ';');
|
||||
}
|
||||
}
|
||||
|
61
node_modules/css-tree/lib/syntax/node/AtrulePrelude.js
generated
vendored
61
node_modules/css-tree/lib/syntax/node/AtrulePrelude.js
generated
vendored
@ -1,47 +1,48 @@
|
||||
import {
|
||||
Semicolon,
|
||||
LeftCurlyBracket
|
||||
} from '../../tokenizer/index.js';
|
||||
import { Semicolon, LeftCurlyBracket } from '../../tokenizer/index.js';
|
||||
|
||||
export const name = 'AtrulePrelude';
|
||||
export const walkContext = 'atrulePrelude';
|
||||
export const structure = {
|
||||
children: [[]]
|
||||
children: [[]],
|
||||
};
|
||||
|
||||
export function parse(name) {
|
||||
let children = null;
|
||||
let children = null;
|
||||
|
||||
if (name !== null) {
|
||||
name = name.toLowerCase();
|
||||
}
|
||||
if (name !== null) {
|
||||
name = name.toLowerCase();
|
||||
}
|
||||
|
||||
this.skipSC();
|
||||
this.skipSC();
|
||||
|
||||
if (hasOwnProperty.call(this.atrule, name) &&
|
||||
typeof this.atrule[name].prelude === 'function') {
|
||||
// custom consumer
|
||||
children = this.atrule[name].prelude.call(this);
|
||||
} else {
|
||||
// default consumer
|
||||
children = this.readSequence(this.scope.AtrulePrelude);
|
||||
}
|
||||
if (
|
||||
hasOwnProperty.call(this.atrule, name) &&
|
||||
typeof this.atrule[name].prelude === 'function'
|
||||
) {
|
||||
// custom consumer
|
||||
children = this.atrule[name].prelude.call(this);
|
||||
} else {
|
||||
// default consumer
|
||||
children = this.readSequence(this.scope.AtrulePrelude);
|
||||
}
|
||||
|
||||
this.skipSC();
|
||||
this.skipSC();
|
||||
|
||||
if (this.eof !== true &&
|
||||
this.tokenType !== LeftCurlyBracket &&
|
||||
this.tokenType !== Semicolon) {
|
||||
this.error('Semicolon or block is expected');
|
||||
}
|
||||
if (
|
||||
this.eof !== true &&
|
||||
this.tokenType !== LeftCurlyBracket &&
|
||||
this.tokenType !== Semicolon
|
||||
) {
|
||||
this.error('Semicolon or block is expected');
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'AtrulePrelude',
|
||||
loc: this.getLocationFromList(children),
|
||||
children
|
||||
};
|
||||
return {
|
||||
type: 'AtrulePrelude',
|
||||
loc: this.getLocationFromList(children),
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.children(node);
|
||||
this.children(node);
|
||||
}
|
||||
|
206
node_modules/css-tree/lib/syntax/node/AttributeSelector.js
generated
vendored
206
node_modules/css-tree/lib/syntax/node/AttributeSelector.js
generated
vendored
@ -1,147 +1,147 @@
|
||||
import {
|
||||
Ident,
|
||||
String as StringToken,
|
||||
Delim,
|
||||
LeftSquareBracket,
|
||||
RightSquareBracket
|
||||
Ident,
|
||||
String as StringToken,
|
||||
Delim,
|
||||
LeftSquareBracket,
|
||||
RightSquareBracket,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
const DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($)
|
||||
const ASTERISK = 0x002A; // U+002A ASTERISK (*)
|
||||
const EQUALSSIGN = 0x003D; // U+003D EQUALS SIGN (=)
|
||||
const CIRCUMFLEXACCENT = 0x005E; // U+005E (^)
|
||||
const VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|)
|
||||
const TILDE = 0x007E; // U+007E TILDE (~)
|
||||
const DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($)
|
||||
const ASTERISK = 0x002a; // U+002A ASTERISK (*)
|
||||
const EQUALSSIGN = 0x003d; // U+003D EQUALS SIGN (=)
|
||||
const CIRCUMFLEXACCENT = 0x005e; // U+005E (^)
|
||||
const VERTICALLINE = 0x007c; // U+007C VERTICAL LINE (|)
|
||||
const TILDE = 0x007e; // U+007E TILDE (~)
|
||||
|
||||
function getAttributeName() {
|
||||
if (this.eof) {
|
||||
this.error('Unexpected end of input');
|
||||
}
|
||||
if (this.eof) {
|
||||
this.error('Unexpected end of input');
|
||||
}
|
||||
|
||||
const start = this.tokenStart;
|
||||
let expectIdent = false;
|
||||
const start = this.tokenStart;
|
||||
let expectIdent = false;
|
||||
|
||||
if (this.isDelim(ASTERISK)) {
|
||||
expectIdent = true;
|
||||
this.next();
|
||||
} else if (!this.isDelim(VERTICALLINE)) {
|
||||
this.eat(Ident);
|
||||
}
|
||||
if (this.isDelim(ASTERISK)) {
|
||||
expectIdent = true;
|
||||
this.next();
|
||||
} else if (!this.isDelim(VERTICALLINE)) {
|
||||
this.eat(Ident);
|
||||
}
|
||||
|
||||
if (this.isDelim(VERTICALLINE)) {
|
||||
if (this.charCodeAt(this.tokenStart + 1) !== EQUALSSIGN) {
|
||||
this.next();
|
||||
this.eat(Ident);
|
||||
} else if (expectIdent) {
|
||||
this.error('Identifier is expected', this.tokenEnd);
|
||||
}
|
||||
if (this.isDelim(VERTICALLINE)) {
|
||||
if (this.charCodeAt(this.tokenStart + 1) !== EQUALSSIGN) {
|
||||
this.next();
|
||||
this.eat(Ident);
|
||||
} else if (expectIdent) {
|
||||
this.error('Vertical line is expected');
|
||||
this.error('Identifier is expected', this.tokenEnd);
|
||||
}
|
||||
} else if (expectIdent) {
|
||||
this.error('Vertical line is expected');
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Identifier',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name: this.substrToCursor(start)
|
||||
};
|
||||
return {
|
||||
type: 'Identifier',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name: this.substrToCursor(start),
|
||||
};
|
||||
}
|
||||
|
||||
function getOperator() {
|
||||
const start = this.tokenStart;
|
||||
const code = this.charCodeAt(start);
|
||||
const start = this.tokenStart;
|
||||
const code = this.charCodeAt(start);
|
||||
|
||||
if (code !== EQUALSSIGN && // =
|
||||
code !== TILDE && // ~=
|
||||
code !== CIRCUMFLEXACCENT && // ^=
|
||||
code !== DOLLARSIGN && // $=
|
||||
code !== ASTERISK && // *=
|
||||
code !== VERTICALLINE // |=
|
||||
) {
|
||||
this.error('Attribute selector (=, ~=, ^=, $=, *=, |=) is expected');
|
||||
if (
|
||||
code !== EQUALSSIGN && // =
|
||||
code !== TILDE && // ~=
|
||||
code !== CIRCUMFLEXACCENT && // ^=
|
||||
code !== DOLLARSIGN && // $=
|
||||
code !== ASTERISK && // *=
|
||||
code !== VERTICALLINE // |=
|
||||
) {
|
||||
this.error('Attribute selector (=, ~=, ^=, $=, *=, |=) is expected');
|
||||
}
|
||||
|
||||
this.next();
|
||||
|
||||
if (code !== EQUALSSIGN) {
|
||||
if (!this.isDelim(EQUALSSIGN)) {
|
||||
this.error('Equal sign is expected');
|
||||
}
|
||||
|
||||
this.next();
|
||||
}
|
||||
|
||||
if (code !== EQUALSSIGN) {
|
||||
if (!this.isDelim(EQUALSSIGN)) {
|
||||
this.error('Equal sign is expected');
|
||||
}
|
||||
|
||||
this.next();
|
||||
}
|
||||
|
||||
return this.substrToCursor(start);
|
||||
return this.substrToCursor(start);
|
||||
}
|
||||
|
||||
// '[' <wq-name> ']'
|
||||
// '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'
|
||||
export const name = 'AttributeSelector';
|
||||
export const structure = {
|
||||
name: 'Identifier',
|
||||
matcher: [String, null],
|
||||
value: ['String', 'Identifier', null],
|
||||
flags: [String, null]
|
||||
name: 'Identifier',
|
||||
matcher: [String, null],
|
||||
value: ['String', 'Identifier', null],
|
||||
flags: [String, null],
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
let name;
|
||||
let matcher = null;
|
||||
let value = null;
|
||||
let flags = null;
|
||||
const start = this.tokenStart;
|
||||
let name;
|
||||
let matcher = null;
|
||||
let value = null;
|
||||
let flags = null;
|
||||
|
||||
this.eat(LeftSquareBracket);
|
||||
this.skipSC();
|
||||
this.eat(LeftSquareBracket);
|
||||
this.skipSC();
|
||||
|
||||
name = getAttributeName.call(this);
|
||||
this.skipSC();
|
||||
name = getAttributeName.call(this);
|
||||
this.skipSC();
|
||||
|
||||
if (this.tokenType !== RightSquareBracket) {
|
||||
// avoid case `[name i]`
|
||||
if (this.tokenType !== Ident) {
|
||||
matcher = getOperator.call(this);
|
||||
if (this.tokenType !== RightSquareBracket) {
|
||||
// avoid case `[name i]`
|
||||
if (this.tokenType !== Ident) {
|
||||
matcher = getOperator.call(this);
|
||||
|
||||
this.skipSC();
|
||||
this.skipSC();
|
||||
|
||||
value = this.tokenType === StringToken
|
||||
? this.String()
|
||||
: this.Identifier();
|
||||
value =
|
||||
this.tokenType === StringToken ? this.String() : this.Identifier();
|
||||
|
||||
this.skipSC();
|
||||
}
|
||||
|
||||
// attribute flags
|
||||
if (this.tokenType === Ident) {
|
||||
flags = this.consume(Ident);
|
||||
|
||||
this.skipSC();
|
||||
}
|
||||
this.skipSC();
|
||||
}
|
||||
|
||||
this.eat(RightSquareBracket);
|
||||
// attribute flags
|
||||
if (this.tokenType === Ident) {
|
||||
flags = this.consume(Ident);
|
||||
|
||||
return {
|
||||
type: 'AttributeSelector',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name,
|
||||
matcher,
|
||||
value,
|
||||
flags
|
||||
};
|
||||
this.skipSC();
|
||||
}
|
||||
}
|
||||
|
||||
this.eat(RightSquareBracket);
|
||||
|
||||
return {
|
||||
type: 'AttributeSelector',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name,
|
||||
matcher,
|
||||
value,
|
||||
flags,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(Delim, '[');
|
||||
this.node(node.name);
|
||||
this.token(Delim, '[');
|
||||
this.node(node.name);
|
||||
|
||||
if (node.matcher !== null) {
|
||||
this.tokenize(node.matcher);
|
||||
this.node(node.value);
|
||||
}
|
||||
if (node.matcher !== null) {
|
||||
this.tokenize(node.matcher);
|
||||
this.node(node.value);
|
||||
}
|
||||
|
||||
if (node.flags !== null) {
|
||||
this.token(Ident, node.flags);
|
||||
}
|
||||
if (node.flags !== null) {
|
||||
this.token(Ident, node.flags);
|
||||
}
|
||||
|
||||
this.token(Delim, ']');
|
||||
this.token(Delim, ']');
|
||||
}
|
||||
|
107
node_modules/css-tree/lib/syntax/node/Block.js
generated
vendored
107
node_modules/css-tree/lib/syntax/node/Block.js
generated
vendored
@ -1,89 +1,84 @@
|
||||
import {
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
Semicolon,
|
||||
AtKeyword,
|
||||
LeftCurlyBracket,
|
||||
RightCurlyBracket
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
Semicolon,
|
||||
AtKeyword,
|
||||
LeftCurlyBracket,
|
||||
RightCurlyBracket,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
function consumeRaw(startToken) {
|
||||
return this.Raw(startToken, null, true);
|
||||
return this.Raw(startToken, null, true);
|
||||
}
|
||||
function consumeRule() {
|
||||
return this.parseWithFallback(this.Rule, consumeRaw);
|
||||
return this.parseWithFallback(this.Rule, consumeRaw);
|
||||
}
|
||||
function consumeRawDeclaration(startToken) {
|
||||
return this.Raw(startToken, this.consumeUntilSemicolonIncluded, true);
|
||||
return this.Raw(startToken, this.consumeUntilSemicolonIncluded, true);
|
||||
}
|
||||
function consumeDeclaration() {
|
||||
if (this.tokenType === Semicolon) {
|
||||
return consumeRawDeclaration.call(this, this.tokenIndex);
|
||||
}
|
||||
if (this.tokenType === Semicolon) {
|
||||
return consumeRawDeclaration.call(this, this.tokenIndex);
|
||||
}
|
||||
|
||||
const node = this.parseWithFallback(this.Declaration, consumeRawDeclaration);
|
||||
const node = this.parseWithFallback(this.Declaration, consumeRawDeclaration);
|
||||
|
||||
if (this.tokenType === Semicolon) {
|
||||
this.next();
|
||||
}
|
||||
if (this.tokenType === Semicolon) {
|
||||
this.next();
|
||||
}
|
||||
|
||||
return node;
|
||||
return node;
|
||||
}
|
||||
|
||||
export const name = 'Block';
|
||||
export const walkContext = 'block';
|
||||
export const structure = {
|
||||
children: [[
|
||||
'Atrule',
|
||||
'Rule',
|
||||
'Declaration'
|
||||
]]
|
||||
children: [['Atrule', 'Rule', 'Declaration']],
|
||||
};
|
||||
|
||||
export function parse(isDeclaration) {
|
||||
const consumer = isDeclaration ? consumeDeclaration : consumeRule;
|
||||
const start = this.tokenStart;
|
||||
let children = this.createList();
|
||||
const consumer = isDeclaration ? consumeDeclaration : consumeRule;
|
||||
const start = this.tokenStart;
|
||||
let children = this.createList();
|
||||
|
||||
this.eat(LeftCurlyBracket);
|
||||
this.eat(LeftCurlyBracket);
|
||||
|
||||
scan:
|
||||
while (!this.eof) {
|
||||
switch (this.tokenType) {
|
||||
case RightCurlyBracket:
|
||||
break scan;
|
||||
scan: while (!this.eof) {
|
||||
switch (this.tokenType) {
|
||||
case RightCurlyBracket:
|
||||
break scan;
|
||||
|
||||
case WhiteSpace:
|
||||
case Comment:
|
||||
this.next();
|
||||
break;
|
||||
case WhiteSpace:
|
||||
case Comment:
|
||||
this.next();
|
||||
break;
|
||||
|
||||
case AtKeyword:
|
||||
children.push(this.parseWithFallback(this.Atrule, consumeRaw));
|
||||
break;
|
||||
case AtKeyword:
|
||||
children.push(this.parseWithFallback(this.Atrule, consumeRaw));
|
||||
break;
|
||||
|
||||
default:
|
||||
children.push(consumer.call(this));
|
||||
}
|
||||
default:
|
||||
children.push(consumer.call(this));
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.eof) {
|
||||
this.eat(RightCurlyBracket);
|
||||
}
|
||||
if (!this.eof) {
|
||||
this.eat(RightCurlyBracket);
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Block',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
children
|
||||
};
|
||||
return {
|
||||
type: 'Block',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(LeftCurlyBracket, '{');
|
||||
this.children(node, prev => {
|
||||
if (prev.type === 'Declaration') {
|
||||
this.token(Semicolon, ';');
|
||||
}
|
||||
});
|
||||
this.token(RightCurlyBracket, '}');
|
||||
this.token(LeftCurlyBracket, '{');
|
||||
this.children(node, (prev) => {
|
||||
if (prev.type === 'Declaration') {
|
||||
this.token(Semicolon, ';');
|
||||
}
|
||||
});
|
||||
this.token(RightCurlyBracket, '}');
|
||||
}
|
||||
|
38
node_modules/css-tree/lib/syntax/node/Brackets.js
generated
vendored
38
node_modules/css-tree/lib/syntax/node/Brackets.js
generated
vendored
@ -1,35 +1,35 @@
|
||||
import {
|
||||
Delim,
|
||||
LeftSquareBracket,
|
||||
RightSquareBracket
|
||||
Delim,
|
||||
LeftSquareBracket,
|
||||
RightSquareBracket,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
export const name = 'Brackets';
|
||||
export const structure = {
|
||||
children: [[]]
|
||||
children: [[]],
|
||||
};
|
||||
|
||||
export function parse(readSequence, recognizer) {
|
||||
const start = this.tokenStart;
|
||||
let children = null;
|
||||
const start = this.tokenStart;
|
||||
let children = null;
|
||||
|
||||
this.eat(LeftSquareBracket);
|
||||
this.eat(LeftSquareBracket);
|
||||
|
||||
children = readSequence.call(this, recognizer);
|
||||
children = readSequence.call(this, recognizer);
|
||||
|
||||
if (!this.eof) {
|
||||
this.eat(RightSquareBracket);
|
||||
}
|
||||
if (!this.eof) {
|
||||
this.eat(RightSquareBracket);
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Brackets',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
children
|
||||
};
|
||||
return {
|
||||
type: 'Brackets',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(Delim, '[');
|
||||
this.children(node);
|
||||
this.token(Delim, ']');
|
||||
this.token(Delim, '[');
|
||||
this.children(node);
|
||||
this.token(Delim, ']');
|
||||
}
|
||||
|
14
node_modules/css-tree/lib/syntax/node/CDC.js
generated
vendored
14
node_modules/css-tree/lib/syntax/node/CDC.js
generated
vendored
@ -4,16 +4,16 @@ export const name = 'CDC';
|
||||
export const structure = [];
|
||||
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
const start = this.tokenStart;
|
||||
|
||||
this.eat(CDC); // -->
|
||||
this.eat(CDC); // -->
|
||||
|
||||
return {
|
||||
type: 'CDC',
|
||||
loc: this.getLocation(start, this.tokenStart)
|
||||
};
|
||||
return {
|
||||
type: 'CDC',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
};
|
||||
}
|
||||
|
||||
export function generate() {
|
||||
this.token(CDC, '-->');
|
||||
this.token(CDC, '-->');
|
||||
}
|
||||
|
14
node_modules/css-tree/lib/syntax/node/CDO.js
generated
vendored
14
node_modules/css-tree/lib/syntax/node/CDO.js
generated
vendored
@ -4,16 +4,16 @@ export const name = 'CDO';
|
||||
export const structure = [];
|
||||
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
const start = this.tokenStart;
|
||||
|
||||
this.eat(CDO); // <!--
|
||||
this.eat(CDO); // <!--
|
||||
|
||||
return {
|
||||
type: 'CDO',
|
||||
loc: this.getLocation(start, this.tokenStart)
|
||||
};
|
||||
return {
|
||||
type: 'CDO',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
};
|
||||
}
|
||||
|
||||
export function generate() {
|
||||
this.token(CDO, '<!--');
|
||||
this.token(CDO, '<!--');
|
||||
}
|
||||
|
20
node_modules/css-tree/lib/syntax/node/ClassSelector.js
generated
vendored
20
node_modules/css-tree/lib/syntax/node/ClassSelector.js
generated
vendored
@ -1,24 +1,24 @@
|
||||
import { Delim, Ident } from '../../tokenizer/index.js';
|
||||
|
||||
const FULLSTOP = 0x002E; // U+002E FULL STOP (.)
|
||||
const FULLSTOP = 0x002e; // U+002E FULL STOP (.)
|
||||
|
||||
// '.' ident
|
||||
export const name = 'ClassSelector';
|
||||
export const structure = {
|
||||
name: String
|
||||
name: String,
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
this.eatDelim(FULLSTOP);
|
||||
this.eatDelim(FULLSTOP);
|
||||
|
||||
return {
|
||||
type: 'ClassSelector',
|
||||
loc: this.getLocation(this.tokenStart - 1, this.tokenEnd),
|
||||
name: this.consume(Ident)
|
||||
};
|
||||
return {
|
||||
type: 'ClassSelector',
|
||||
loc: this.getLocation(this.tokenStart - 1, this.tokenEnd),
|
||||
name: this.consume(Ident),
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(Delim, '.');
|
||||
this.token(Ident, node.name);
|
||||
this.token(Delim, '.');
|
||||
this.token(Ident, node.name);
|
||||
}
|
||||
|
70
node_modules/css-tree/lib/syntax/node/Combinator.js
generated
vendored
70
node_modules/css-tree/lib/syntax/node/Combinator.js
generated
vendored
@ -1,54 +1,54 @@
|
||||
import { WhiteSpace, Delim } from '../../tokenizer/index.js';
|
||||
|
||||
const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
|
||||
const SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
|
||||
const GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>)
|
||||
const TILDE = 0x007E; // U+007E TILDE (~)
|
||||
const PLUSSIGN = 0x002b; // U+002B PLUS SIGN (+)
|
||||
const SOLIDUS = 0x002f; // U+002F SOLIDUS (/)
|
||||
const GREATERTHANSIGN = 0x003e; // U+003E GREATER-THAN SIGN (>)
|
||||
const TILDE = 0x007e; // U+007E TILDE (~)
|
||||
|
||||
export const name = 'Combinator';
|
||||
export const structure = {
|
||||
name: String
|
||||
name: String,
|
||||
};
|
||||
|
||||
// + | > | ~ | /deep/
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
let name;
|
||||
const start = this.tokenStart;
|
||||
let name;
|
||||
|
||||
switch (this.tokenType) {
|
||||
case WhiteSpace:
|
||||
name = ' ';
|
||||
break;
|
||||
switch (this.tokenType) {
|
||||
case WhiteSpace:
|
||||
name = ' ';
|
||||
break;
|
||||
|
||||
case Delim:
|
||||
switch (this.charCodeAt(this.tokenStart)) {
|
||||
case GREATERTHANSIGN:
|
||||
case PLUSSIGN:
|
||||
case TILDE:
|
||||
this.next();
|
||||
break;
|
||||
case Delim:
|
||||
switch (this.charCodeAt(this.tokenStart)) {
|
||||
case GREATERTHANSIGN:
|
||||
case PLUSSIGN:
|
||||
case TILDE:
|
||||
this.next();
|
||||
break;
|
||||
|
||||
case SOLIDUS:
|
||||
this.next();
|
||||
this.eatIdent('deep');
|
||||
this.eatDelim(SOLIDUS);
|
||||
break;
|
||||
case SOLIDUS:
|
||||
this.next();
|
||||
this.eatIdent('deep');
|
||||
this.eatDelim(SOLIDUS);
|
||||
break;
|
||||
|
||||
default:
|
||||
this.error('Combinator is expected');
|
||||
}
|
||||
default:
|
||||
this.error('Combinator is expected');
|
||||
}
|
||||
|
||||
name = this.substrToCursor(start);
|
||||
break;
|
||||
}
|
||||
name = this.substrToCursor(start);
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Combinator',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name
|
||||
};
|
||||
return {
|
||||
type: 'Combinator',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.tokenize(node.name);
|
||||
this.tokenize(node.name);
|
||||
}
|
||||
|
37
node_modules/css-tree/lib/syntax/node/Comment.js
generated
vendored
37
node_modules/css-tree/lib/syntax/node/Comment.js
generated
vendored
@ -1,33 +1,34 @@
|
||||
import { Comment } from '../../tokenizer/index.js';
|
||||
|
||||
const ASTERISK = 0x002A; // U+002A ASTERISK (*)
|
||||
const SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
|
||||
|
||||
const ASTERISK = 0x002a; // U+002A ASTERISK (*)
|
||||
const SOLIDUS = 0x002f; // U+002F SOLIDUS (/)
|
||||
|
||||
export const name = 'Comment';
|
||||
export const structure = {
|
||||
value: String
|
||||
value: String,
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
let end = this.tokenEnd;
|
||||
const start = this.tokenStart;
|
||||
let end = this.tokenEnd;
|
||||
|
||||
this.eat(Comment);
|
||||
this.eat(Comment);
|
||||
|
||||
if ((end - start + 2) >= 2 &&
|
||||
this.charCodeAt(end - 2) === ASTERISK &&
|
||||
this.charCodeAt(end - 1) === SOLIDUS) {
|
||||
end -= 2;
|
||||
}
|
||||
if (
|
||||
end - start + 2 >= 2 &&
|
||||
this.charCodeAt(end - 2) === ASTERISK &&
|
||||
this.charCodeAt(end - 1) === SOLIDUS
|
||||
) {
|
||||
end -= 2;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Comment',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
value: this.substring(start + 2, end)
|
||||
};
|
||||
return {
|
||||
type: 'Comment',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
value: this.substring(start + 2, end),
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(Comment, '/*' + node.value + '*/');
|
||||
this.token(Comment, '/*' + node.value + '*/');
|
||||
}
|
||||
|
240
node_modules/css-tree/lib/syntax/node/Declaration.js
generated
vendored
240
node_modules/css-tree/lib/syntax/node/Declaration.js
generated
vendored
@ -1,165 +1,179 @@
|
||||
import { isCustomProperty } from '../../utils/names.js';
|
||||
import {
|
||||
Ident,
|
||||
Hash,
|
||||
Colon,
|
||||
Semicolon,
|
||||
Delim,
|
||||
WhiteSpace
|
||||
Ident,
|
||||
Hash,
|
||||
Colon,
|
||||
Semicolon,
|
||||
Delim,
|
||||
WhiteSpace,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
const EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!)
|
||||
const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
|
||||
const DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($)
|
||||
const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&)
|
||||
const ASTERISK = 0x002A; // U+002A ASTERISK (*)
|
||||
const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
|
||||
const SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
|
||||
const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
|
||||
const DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($)
|
||||
const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&)
|
||||
const ASTERISK = 0x002a; // U+002A ASTERISK (*)
|
||||
const PLUSSIGN = 0x002b; // U+002B PLUS SIGN (+)
|
||||
const SOLIDUS = 0x002f; // U+002F SOLIDUS (/)
|
||||
|
||||
function consumeValueRaw(startToken) {
|
||||
return this.Raw(startToken, this.consumeUntilExclamationMarkOrSemicolon, true);
|
||||
return this.Raw(
|
||||
startToken,
|
||||
this.consumeUntilExclamationMarkOrSemicolon,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
function consumeCustomPropertyRaw(startToken) {
|
||||
return this.Raw(startToken, this.consumeUntilExclamationMarkOrSemicolon, false);
|
||||
return this.Raw(
|
||||
startToken,
|
||||
this.consumeUntilExclamationMarkOrSemicolon,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
function consumeValue() {
|
||||
const startValueToken = this.tokenIndex;
|
||||
const value = this.Value();
|
||||
const startValueToken = this.tokenIndex;
|
||||
const value = this.Value();
|
||||
|
||||
if (value.type !== 'Raw' &&
|
||||
this.eof === false &&
|
||||
this.tokenType !== Semicolon &&
|
||||
this.isDelim(EXCLAMATIONMARK) === false &&
|
||||
this.isBalanceEdge(startValueToken) === false) {
|
||||
this.error();
|
||||
}
|
||||
if (
|
||||
value.type !== 'Raw' &&
|
||||
this.eof === false &&
|
||||
this.tokenType !== Semicolon &&
|
||||
this.isDelim(EXCLAMATIONMARK) === false &&
|
||||
this.isBalanceEdge(startValueToken) === false
|
||||
) {
|
||||
this.error();
|
||||
}
|
||||
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
|
||||
export const name = 'Declaration';
|
||||
export const walkContext = 'declaration';
|
||||
export const structure = {
|
||||
important: [Boolean, String],
|
||||
property: String,
|
||||
value: ['Value', 'Raw']
|
||||
important: [Boolean, String],
|
||||
property: String,
|
||||
value: ['Value', 'Raw'],
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
const startToken = this.tokenIndex;
|
||||
const property = readProperty.call(this);
|
||||
const customProperty = isCustomProperty(property);
|
||||
const parseValue = customProperty ? this.parseCustomProperty : this.parseValue;
|
||||
const consumeRaw = customProperty ? consumeCustomPropertyRaw : consumeValueRaw;
|
||||
let important = false;
|
||||
let value;
|
||||
const start = this.tokenStart;
|
||||
const startToken = this.tokenIndex;
|
||||
const property = readProperty.call(this);
|
||||
const customProperty = isCustomProperty(property);
|
||||
const parseValue =
|
||||
customProperty ? this.parseCustomProperty : this.parseValue;
|
||||
const consumeRaw =
|
||||
customProperty ? consumeCustomPropertyRaw : consumeValueRaw;
|
||||
let important = false;
|
||||
let value;
|
||||
|
||||
this.skipSC();
|
||||
this.eat(Colon);
|
||||
|
||||
const valueStart = this.tokenIndex;
|
||||
|
||||
if (!customProperty) {
|
||||
this.skipSC();
|
||||
this.eat(Colon);
|
||||
}
|
||||
|
||||
const valueStart = this.tokenIndex;
|
||||
if (parseValue) {
|
||||
value = this.parseWithFallback(consumeValue, consumeRaw);
|
||||
} else {
|
||||
value = consumeRaw.call(this, this.tokenIndex);
|
||||
}
|
||||
|
||||
if (!customProperty) {
|
||||
this.skipSC();
|
||||
if (customProperty && value.type === 'Value' && value.children.isEmpty) {
|
||||
for (let offset = valueStart - this.tokenIndex; offset <= 0; offset++) {
|
||||
if (this.lookupType(offset) === WhiteSpace) {
|
||||
value.children.appendData({
|
||||
type: 'WhiteSpace',
|
||||
loc: null,
|
||||
value: ' ',
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parseValue) {
|
||||
value = this.parseWithFallback(consumeValue, consumeRaw);
|
||||
} else {
|
||||
value = consumeRaw.call(this, this.tokenIndex);
|
||||
}
|
||||
if (this.isDelim(EXCLAMATIONMARK)) {
|
||||
important = getImportant.call(this);
|
||||
this.skipSC();
|
||||
}
|
||||
|
||||
if (customProperty && value.type === 'Value' && value.children.isEmpty) {
|
||||
for (let offset = valueStart - this.tokenIndex; offset <= 0; offset++) {
|
||||
if (this.lookupType(offset) === WhiteSpace) {
|
||||
value.children.appendData({
|
||||
type: 'WhiteSpace',
|
||||
loc: null,
|
||||
value: ' '
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Do not include semicolon to range per spec
|
||||
// https://drafts.csswg.org/css-syntax/#declaration-diagram
|
||||
|
||||
if (this.isDelim(EXCLAMATIONMARK)) {
|
||||
important = getImportant.call(this);
|
||||
this.skipSC();
|
||||
}
|
||||
if (
|
||||
this.eof === false &&
|
||||
this.tokenType !== Semicolon &&
|
||||
this.isBalanceEdge(startToken) === false
|
||||
) {
|
||||
this.error();
|
||||
}
|
||||
|
||||
// Do not include semicolon to range per spec
|
||||
// https://drafts.csswg.org/css-syntax/#declaration-diagram
|
||||
|
||||
if (this.eof === false &&
|
||||
this.tokenType !== Semicolon &&
|
||||
this.isBalanceEdge(startToken) === false) {
|
||||
this.error();
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Declaration',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
important,
|
||||
property,
|
||||
value
|
||||
};
|
||||
return {
|
||||
type: 'Declaration',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
important,
|
||||
property,
|
||||
value,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(Ident, node.property);
|
||||
this.token(Colon, ':');
|
||||
this.node(node.value);
|
||||
this.token(Ident, node.property);
|
||||
this.token(Colon, ':');
|
||||
this.node(node.value);
|
||||
|
||||
if (node.important) {
|
||||
this.token(Delim, '!');
|
||||
this.token(Ident, node.important === true ? 'important' : node.important);
|
||||
}
|
||||
if (node.important) {
|
||||
this.token(Delim, '!');
|
||||
this.token(Ident, node.important === true ? 'important' : node.important);
|
||||
}
|
||||
}
|
||||
|
||||
function readProperty() {
|
||||
const start = this.tokenStart;
|
||||
const start = this.tokenStart;
|
||||
|
||||
// hacks
|
||||
if (this.tokenType === Delim) {
|
||||
switch (this.charCodeAt(this.tokenStart)) {
|
||||
case ASTERISK:
|
||||
case DOLLARSIGN:
|
||||
case PLUSSIGN:
|
||||
case NUMBERSIGN:
|
||||
case AMPERSAND:
|
||||
this.next();
|
||||
break;
|
||||
// hacks
|
||||
if (this.tokenType === Delim) {
|
||||
switch (this.charCodeAt(this.tokenStart)) {
|
||||
case ASTERISK:
|
||||
case DOLLARSIGN:
|
||||
case PLUSSIGN:
|
||||
case NUMBERSIGN:
|
||||
case AMPERSAND:
|
||||
this.next();
|
||||
break;
|
||||
|
||||
// TODO: not sure we should support this hack
|
||||
case SOLIDUS:
|
||||
this.next();
|
||||
if (this.isDelim(SOLIDUS)) {
|
||||
this.next();
|
||||
}
|
||||
break;
|
||||
// TODO: not sure we should support this hack
|
||||
case SOLIDUS:
|
||||
this.next();
|
||||
if (this.isDelim(SOLIDUS)) {
|
||||
this.next();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.tokenType === Hash) {
|
||||
this.eat(Hash);
|
||||
} else {
|
||||
this.eat(Ident);
|
||||
}
|
||||
if (this.tokenType === Hash) {
|
||||
this.eat(Hash);
|
||||
} else {
|
||||
this.eat(Ident);
|
||||
}
|
||||
|
||||
return this.substrToCursor(start);
|
||||
return this.substrToCursor(start);
|
||||
}
|
||||
|
||||
// ! ws* important
|
||||
function getImportant() {
|
||||
this.eat(Delim);
|
||||
this.skipSC();
|
||||
this.eat(Delim);
|
||||
this.skipSC();
|
||||
|
||||
const important = this.consume(Ident);
|
||||
const important = this.consume(Ident);
|
||||
|
||||
// store original value in case it differ from `important`
|
||||
// for better original source restoring and hacks like `!ie` support
|
||||
return important === 'important' ? true : important;
|
||||
// store original value in case it differ from `important`
|
||||
// for better original source restoring and hacks like `!ie` support
|
||||
return important === 'important' ? true : important;
|
||||
}
|
||||
|
56
node_modules/css-tree/lib/syntax/node/DeclarationList.js
generated
vendored
56
node_modules/css-tree/lib/syntax/node/DeclarationList.js
generated
vendored
@ -1,49 +1,41 @@
|
||||
import {
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
Semicolon
|
||||
} from '../../tokenizer/index.js';
|
||||
import { WhiteSpace, Comment, Semicolon } from '../../tokenizer/index.js';
|
||||
|
||||
function consumeRaw(startToken) {
|
||||
return this.Raw(startToken, this.consumeUntilSemicolonIncluded, true);
|
||||
return this.Raw(startToken, this.consumeUntilSemicolonIncluded, true);
|
||||
}
|
||||
|
||||
export const name = 'DeclarationList';
|
||||
export const structure = {
|
||||
children: [[
|
||||
'Declaration'
|
||||
]]
|
||||
children: [['Declaration']],
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const children = this.createList();
|
||||
const children = this.createList();
|
||||
|
||||
scan:
|
||||
while (!this.eof) {
|
||||
switch (this.tokenType) {
|
||||
case WhiteSpace:
|
||||
case Comment:
|
||||
case Semicolon:
|
||||
this.next();
|
||||
break;
|
||||
scan: while (!this.eof) {
|
||||
switch (this.tokenType) {
|
||||
case WhiteSpace:
|
||||
case Comment:
|
||||
case Semicolon:
|
||||
this.next();
|
||||
break;
|
||||
|
||||
default:
|
||||
children.push(this.parseWithFallback(this.Declaration, consumeRaw));
|
||||
}
|
||||
default:
|
||||
children.push(this.parseWithFallback(this.Declaration, consumeRaw));
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'DeclarationList',
|
||||
loc: this.getLocationFromList(children),
|
||||
children
|
||||
};
|
||||
return {
|
||||
type: 'DeclarationList',
|
||||
loc: this.getLocationFromList(children),
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.children(node, prev => {
|
||||
if (prev.type === 'Declaration') {
|
||||
this.token(Semicolon, ';');
|
||||
}
|
||||
});
|
||||
this.children(node, (prev) => {
|
||||
if (prev.type === 'Declaration') {
|
||||
this.token(Semicolon, ';');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
22
node_modules/css-tree/lib/syntax/node/Dimension.js
generated
vendored
22
node_modules/css-tree/lib/syntax/node/Dimension.js
generated
vendored
@ -2,22 +2,22 @@ import { Dimension } from '../../tokenizer/index.js';
|
||||
|
||||
export const name = 'Dimension';
|
||||
export const structure = {
|
||||
value: String,
|
||||
unit: String
|
||||
value: String,
|
||||
unit: String,
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
const value = this.consumeNumber(Dimension);
|
||||
const start = this.tokenStart;
|
||||
const value = this.consumeNumber(Dimension);
|
||||
|
||||
return {
|
||||
type: 'Dimension',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
value,
|
||||
unit: this.substring(start + value.length, this.tokenStart)
|
||||
};
|
||||
return {
|
||||
type: 'Dimension',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
value,
|
||||
unit: this.substring(start + value.length, this.tokenStart),
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(Dimension, node.value + node.unit);
|
||||
this.token(Dimension, node.value + node.unit);
|
||||
}
|
||||
|
48
node_modules/css-tree/lib/syntax/node/Function.js
generated
vendored
48
node_modules/css-tree/lib/syntax/node/Function.js
generated
vendored
@ -1,41 +1,41 @@
|
||||
import {
|
||||
Function as FunctionToken,
|
||||
RightParenthesis
|
||||
Function as FunctionToken,
|
||||
RightParenthesis,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
|
||||
export const name = 'Function';
|
||||
export const walkContext = 'function';
|
||||
export const structure = {
|
||||
name: String,
|
||||
children: [[]]
|
||||
name: String,
|
||||
children: [[]],
|
||||
};
|
||||
|
||||
// <function-token> <sequence> )
|
||||
export function parse(readSequence, recognizer) {
|
||||
const start = this.tokenStart;
|
||||
const name = this.consumeFunctionName();
|
||||
const nameLowerCase = name.toLowerCase();
|
||||
let children;
|
||||
const start = this.tokenStart;
|
||||
const name = this.consumeFunctionName();
|
||||
const nameLowerCase = name.toLowerCase();
|
||||
let children;
|
||||
|
||||
children = recognizer.hasOwnProperty(nameLowerCase)
|
||||
? recognizer[nameLowerCase].call(this, recognizer)
|
||||
: readSequence.call(this, recognizer);
|
||||
children =
|
||||
recognizer.hasOwnProperty(nameLowerCase) ?
|
||||
recognizer[nameLowerCase].call(this, recognizer)
|
||||
: readSequence.call(this, recognizer);
|
||||
|
||||
if (!this.eof) {
|
||||
this.eat(RightParenthesis);
|
||||
}
|
||||
if (!this.eof) {
|
||||
this.eat(RightParenthesis);
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Function',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name,
|
||||
children
|
||||
};
|
||||
return {
|
||||
type: 'Function',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name,
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(FunctionToken, node.name + '(');
|
||||
this.children(node);
|
||||
this.token(RightParenthesis, ')');
|
||||
this.token(FunctionToken, node.name + '(');
|
||||
this.children(node);
|
||||
this.token(RightParenthesis, ')');
|
||||
}
|
||||
|
19
node_modules/css-tree/lib/syntax/node/Hash.js
generated
vendored
19
node_modules/css-tree/lib/syntax/node/Hash.js
generated
vendored
@ -4,20 +4,19 @@ import { Hash } from '../../tokenizer/index.js';
|
||||
export const xxx = 'XXX';
|
||||
export const name = 'Hash';
|
||||
export const structure = {
|
||||
value: String
|
||||
value: String,
|
||||
};
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
const start = this.tokenStart;
|
||||
|
||||
this.eat(Hash);
|
||||
this.eat(Hash);
|
||||
|
||||
return {
|
||||
type: 'Hash',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
value: this.substrToCursor(start + 1)
|
||||
};
|
||||
return {
|
||||
type: 'Hash',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
value: this.substrToCursor(start + 1),
|
||||
};
|
||||
}
|
||||
export function generate(node) {
|
||||
this.token(Hash, '#' + node.value);
|
||||
this.token(Hash, '#' + node.value);
|
||||
}
|
||||
|
||||
|
26
node_modules/css-tree/lib/syntax/node/IdSelector.js
generated
vendored
26
node_modules/css-tree/lib/syntax/node/IdSelector.js
generated
vendored
@ -2,25 +2,25 @@ import { Hash, Delim } from '../../tokenizer/index.js';
|
||||
|
||||
export const name = 'IdSelector';
|
||||
export const structure = {
|
||||
name: String
|
||||
name: String,
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
const start = this.tokenStart;
|
||||
|
||||
// TODO: check value is an ident
|
||||
this.eat(Hash);
|
||||
// TODO: check value is an ident
|
||||
this.eat(Hash);
|
||||
|
||||
return {
|
||||
type: 'IdSelector',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name: this.substrToCursor(start + 1)
|
||||
};
|
||||
return {
|
||||
type: 'IdSelector',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name: this.substrToCursor(start + 1),
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
// Using Delim instead of Hash is a hack to avoid for a whitespace between ident and id-selector
|
||||
// in safe mode (e.g. "a#id"), because IE11 doesn't allow a sequence <ident-token> <hash-token>
|
||||
// without a whitespace in values (e.g. "1px solid#000")
|
||||
this.token(Delim, '#' + node.name);
|
||||
// Using Delim instead of Hash is a hack to avoid for a whitespace between ident and id-selector
|
||||
// in safe mode (e.g. "a#id"), because IE11 doesn't allow a sequence <ident-token> <hash-token>
|
||||
// without a whitespace in values (e.g. "1px solid#000")
|
||||
this.token(Delim, '#' + node.name);
|
||||
}
|
||||
|
14
node_modules/css-tree/lib/syntax/node/Identifier.js
generated
vendored
14
node_modules/css-tree/lib/syntax/node/Identifier.js
generated
vendored
@ -2,17 +2,17 @@ import { Ident } from '../../tokenizer/index.js';
|
||||
|
||||
export const name = 'Identifier';
|
||||
export const structure = {
|
||||
name: String
|
||||
name: String,
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
return {
|
||||
type: 'Identifier',
|
||||
loc: this.getLocation(this.tokenStart, this.tokenEnd),
|
||||
name: this.consume(Ident)
|
||||
};
|
||||
return {
|
||||
type: 'Identifier',
|
||||
loc: this.getLocation(this.tokenStart, this.tokenEnd),
|
||||
name: this.consume(Ident),
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(Ident, node.name);
|
||||
this.token(Ident, node.name);
|
||||
}
|
||||
|
110
node_modules/css-tree/lib/syntax/node/MediaFeature.js
generated
vendored
110
node_modules/css-tree/lib/syntax/node/MediaFeature.js
generated
vendored
@ -1,77 +1,77 @@
|
||||
import {
|
||||
Ident,
|
||||
Number,
|
||||
Dimension,
|
||||
LeftParenthesis,
|
||||
RightParenthesis,
|
||||
Colon,
|
||||
Delim
|
||||
Ident,
|
||||
Number,
|
||||
Dimension,
|
||||
LeftParenthesis,
|
||||
RightParenthesis,
|
||||
Colon,
|
||||
Delim,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
export const name = 'MediaFeature';
|
||||
export const structure = {
|
||||
name: String,
|
||||
value: ['Identifier', 'Number', 'Dimension', 'Ratio', null]
|
||||
name: String,
|
||||
value: ['Identifier', 'Number', 'Dimension', 'Ratio', null],
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
let name;
|
||||
let value = null;
|
||||
const start = this.tokenStart;
|
||||
let name;
|
||||
let value = null;
|
||||
|
||||
this.eat(LeftParenthesis);
|
||||
this.eat(LeftParenthesis);
|
||||
this.skipSC();
|
||||
|
||||
name = this.consume(Ident);
|
||||
this.skipSC();
|
||||
|
||||
if (this.tokenType !== RightParenthesis) {
|
||||
this.eat(Colon);
|
||||
this.skipSC();
|
||||
|
||||
name = this.consume(Ident);
|
||||
this.skipSC();
|
||||
|
||||
if (this.tokenType !== RightParenthesis) {
|
||||
this.eat(Colon);
|
||||
this.skipSC();
|
||||
|
||||
switch (this.tokenType) {
|
||||
case Number:
|
||||
if (this.lookupNonWSType(1) === Delim) {
|
||||
value = this.Ratio();
|
||||
} else {
|
||||
value = this.Number();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Dimension:
|
||||
value = this.Dimension();
|
||||
break;
|
||||
|
||||
case Ident:
|
||||
value = this.Identifier();
|
||||
break;
|
||||
|
||||
default:
|
||||
this.error('Number, dimension, ratio or identifier is expected');
|
||||
switch (this.tokenType) {
|
||||
case Number:
|
||||
if (this.lookupNonWSType(1) === Delim) {
|
||||
value = this.Ratio();
|
||||
} else {
|
||||
value = this.Number();
|
||||
}
|
||||
|
||||
this.skipSC();
|
||||
break;
|
||||
|
||||
case Dimension:
|
||||
value = this.Dimension();
|
||||
break;
|
||||
|
||||
case Ident:
|
||||
value = this.Identifier();
|
||||
break;
|
||||
|
||||
default:
|
||||
this.error('Number, dimension, ratio or identifier is expected');
|
||||
}
|
||||
|
||||
this.eat(RightParenthesis);
|
||||
this.skipSC();
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'MediaFeature',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name,
|
||||
value
|
||||
};
|
||||
this.eat(RightParenthesis);
|
||||
|
||||
return {
|
||||
type: 'MediaFeature',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name,
|
||||
value,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(LeftParenthesis, '(');
|
||||
this.token(Ident, node.name);
|
||||
this.token(LeftParenthesis, '(');
|
||||
this.token(Ident, node.name);
|
||||
|
||||
if (node.value !== null) {
|
||||
this.token(Colon, ':');
|
||||
this.node(node.value);
|
||||
}
|
||||
if (node.value !== null) {
|
||||
this.token(Colon, ':');
|
||||
this.node(node.value);
|
||||
}
|
||||
|
||||
this.token(RightParenthesis, ')');
|
||||
this.token(RightParenthesis, ')');
|
||||
}
|
||||
|
74
node_modules/css-tree/lib/syntax/node/MediaQuery.js
generated
vendored
74
node_modules/css-tree/lib/syntax/node/MediaQuery.js
generated
vendored
@ -1,60 +1,54 @@
|
||||
import {
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
Ident,
|
||||
LeftParenthesis
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
Ident,
|
||||
LeftParenthesis,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
export const name = 'MediaQuery';
|
||||
export const structure = {
|
||||
children: [[
|
||||
'Identifier',
|
||||
'MediaFeature',
|
||||
'WhiteSpace'
|
||||
]]
|
||||
children: [['Identifier', 'MediaFeature', 'WhiteSpace']],
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const children = this.createList();
|
||||
let child = null;
|
||||
const children = this.createList();
|
||||
let child = null;
|
||||
|
||||
this.skipSC();
|
||||
this.skipSC();
|
||||
|
||||
scan:
|
||||
while (!this.eof) {
|
||||
switch (this.tokenType) {
|
||||
case Comment:
|
||||
case WhiteSpace:
|
||||
this.next();
|
||||
continue;
|
||||
scan: while (!this.eof) {
|
||||
switch (this.tokenType) {
|
||||
case Comment:
|
||||
case WhiteSpace:
|
||||
this.next();
|
||||
continue;
|
||||
|
||||
case Ident:
|
||||
child = this.Identifier();
|
||||
break;
|
||||
case Ident:
|
||||
child = this.Identifier();
|
||||
break;
|
||||
|
||||
case LeftParenthesis:
|
||||
child = this.MediaFeature();
|
||||
break;
|
||||
case LeftParenthesis:
|
||||
child = this.MediaFeature();
|
||||
break;
|
||||
|
||||
default:
|
||||
break scan;
|
||||
}
|
||||
|
||||
children.push(child);
|
||||
default:
|
||||
break scan;
|
||||
}
|
||||
|
||||
if (child === null) {
|
||||
this.error('Identifier or parenthesis is expected');
|
||||
}
|
||||
children.push(child);
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'MediaQuery',
|
||||
loc: this.getLocationFromList(children),
|
||||
children
|
||||
};
|
||||
if (child === null) {
|
||||
this.error('Identifier or parenthesis is expected');
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'MediaQuery',
|
||||
loc: this.getLocationFromList(children),
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.children(node);
|
||||
this.children(node);
|
||||
}
|
||||
|
||||
|
34
node_modules/css-tree/lib/syntax/node/MediaQueryList.js
generated
vendored
34
node_modules/css-tree/lib/syntax/node/MediaQueryList.js
generated
vendored
@ -2,33 +2,31 @@ import { Comma } from '../../tokenizer/index.js';
|
||||
|
||||
export const name = 'MediaQueryList';
|
||||
export const structure = {
|
||||
children: [[
|
||||
'MediaQuery'
|
||||
]]
|
||||
children: [['MediaQuery']],
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const children = this.createList();
|
||||
const children = this.createList();
|
||||
|
||||
this.skipSC();
|
||||
this.skipSC();
|
||||
|
||||
while (!this.eof) {
|
||||
children.push(this.MediaQuery());
|
||||
while (!this.eof) {
|
||||
children.push(this.MediaQuery());
|
||||
|
||||
if (this.tokenType !== Comma) {
|
||||
break;
|
||||
}
|
||||
|
||||
this.next();
|
||||
if (this.tokenType !== Comma) {
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'MediaQueryList',
|
||||
loc: this.getLocationFromList(children),
|
||||
children
|
||||
};
|
||||
this.next();
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'MediaQueryList',
|
||||
loc: this.getLocationFromList(children),
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.children(node, () => this.token(Comma, ','));
|
||||
this.children(node, () => this.token(Comma, ','));
|
||||
}
|
||||
|
62
node_modules/css-tree/lib/syntax/node/Nth.js
generated
vendored
62
node_modules/css-tree/lib/syntax/node/Nth.js
generated
vendored
@ -2,46 +2,46 @@ import { Ident } from '../../tokenizer/index.js';
|
||||
|
||||
export const name = 'Nth';
|
||||
export const structure = {
|
||||
nth: ['AnPlusB', 'Identifier'],
|
||||
selector: ['SelectorList', null]
|
||||
nth: ['AnPlusB', 'Identifier'],
|
||||
selector: ['SelectorList', null],
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
this.skipSC();
|
||||
this.skipSC();
|
||||
|
||||
const start = this.tokenStart;
|
||||
let end = start;
|
||||
let selector = null;
|
||||
let nth;
|
||||
const start = this.tokenStart;
|
||||
let end = start;
|
||||
let selector = null;
|
||||
let nth;
|
||||
|
||||
if (this.lookupValue(0, 'odd') || this.lookupValue(0, 'even')) {
|
||||
nth = this.Identifier();
|
||||
} else {
|
||||
nth = this.AnPlusB();
|
||||
}
|
||||
if (this.lookupValue(0, 'odd') || this.lookupValue(0, 'even')) {
|
||||
nth = this.Identifier();
|
||||
} else {
|
||||
nth = this.AnPlusB();
|
||||
}
|
||||
|
||||
end = this.tokenStart;
|
||||
this.skipSC();
|
||||
|
||||
if (this.lookupValue(0, 'of')) {
|
||||
this.next();
|
||||
|
||||
selector = this.SelectorList();
|
||||
end = this.tokenStart;
|
||||
this.skipSC();
|
||||
}
|
||||
|
||||
if (this.lookupValue(0, 'of')) {
|
||||
this.next();
|
||||
|
||||
selector = this.SelectorList();
|
||||
end = this.tokenStart;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Nth',
|
||||
loc: this.getLocation(start, end),
|
||||
nth,
|
||||
selector
|
||||
};
|
||||
return {
|
||||
type: 'Nth',
|
||||
loc: this.getLocation(start, end),
|
||||
nth,
|
||||
selector,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.node(node.nth);
|
||||
if (node.selector !== null) {
|
||||
this.token(Ident, 'of');
|
||||
this.node(node.selector);
|
||||
}
|
||||
this.node(node.nth);
|
||||
if (node.selector !== null) {
|
||||
this.token(Ident, 'of');
|
||||
this.node(node.selector);
|
||||
}
|
||||
}
|
||||
|
14
node_modules/css-tree/lib/syntax/node/Number.js
generated
vendored
14
node_modules/css-tree/lib/syntax/node/Number.js
generated
vendored
@ -2,17 +2,17 @@ import { Number as NumberToken } from '../../tokenizer/index.js';
|
||||
|
||||
export const name = 'Number';
|
||||
export const structure = {
|
||||
value: String
|
||||
value: String,
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
return {
|
||||
type: 'Number',
|
||||
loc: this.getLocation(this.tokenStart, this.tokenEnd),
|
||||
value: this.consume(NumberToken)
|
||||
};
|
||||
return {
|
||||
type: 'Number',
|
||||
loc: this.getLocation(this.tokenStart, this.tokenEnd),
|
||||
value: this.consume(NumberToken),
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(NumberToken, node.value);
|
||||
this.token(NumberToken, node.value);
|
||||
}
|
||||
|
18
node_modules/css-tree/lib/syntax/node/Operator.js
generated
vendored
18
node_modules/css-tree/lib/syntax/node/Operator.js
generated
vendored
@ -1,21 +1,21 @@
|
||||
// '/' | '*' | ',' | ':' | '+' | '-'
|
||||
export const name = 'Operator';
|
||||
export const structure = {
|
||||
value: String
|
||||
value: String,
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
const start = this.tokenStart;
|
||||
|
||||
this.next();
|
||||
this.next();
|
||||
|
||||
return {
|
||||
type: 'Operator',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
value: this.substrToCursor(start)
|
||||
};
|
||||
return {
|
||||
type: 'Operator',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
value: this.substrToCursor(start),
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.tokenize(node.value);
|
||||
this.tokenize(node.value);
|
||||
}
|
||||
|
37
node_modules/css-tree/lib/syntax/node/Parentheses.js
generated
vendored
37
node_modules/css-tree/lib/syntax/node/Parentheses.js
generated
vendored
@ -1,34 +1,31 @@
|
||||
import {
|
||||
LeftParenthesis,
|
||||
RightParenthesis
|
||||
} from '../../tokenizer/index.js';
|
||||
import { LeftParenthesis, RightParenthesis } from '../../tokenizer/index.js';
|
||||
|
||||
export const name = 'Parentheses';
|
||||
export const structure = {
|
||||
children: [[]]
|
||||
children: [[]],
|
||||
};
|
||||
|
||||
export function parse(readSequence, recognizer) {
|
||||
const start = this.tokenStart;
|
||||
let children = null;
|
||||
const start = this.tokenStart;
|
||||
let children = null;
|
||||
|
||||
this.eat(LeftParenthesis);
|
||||
this.eat(LeftParenthesis);
|
||||
|
||||
children = readSequence.call(this, recognizer);
|
||||
children = readSequence.call(this, recognizer);
|
||||
|
||||
if (!this.eof) {
|
||||
this.eat(RightParenthesis);
|
||||
}
|
||||
if (!this.eof) {
|
||||
this.eat(RightParenthesis);
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Parentheses',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
children
|
||||
};
|
||||
return {
|
||||
type: 'Parentheses',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(LeftParenthesis, '(');
|
||||
this.children(node);
|
||||
this.token(RightParenthesis, ')');
|
||||
this.token(LeftParenthesis, '(');
|
||||
this.children(node);
|
||||
this.token(RightParenthesis, ')');
|
||||
}
|
||||
|
14
node_modules/css-tree/lib/syntax/node/Percentage.js
generated
vendored
14
node_modules/css-tree/lib/syntax/node/Percentage.js
generated
vendored
@ -2,17 +2,17 @@ import { Percentage } from '../../tokenizer/index.js';
|
||||
|
||||
export const name = 'Percentage';
|
||||
export const structure = {
|
||||
value: String
|
||||
value: String,
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
return {
|
||||
type: 'Percentage',
|
||||
loc: this.getLocation(this.tokenStart, this.tokenEnd),
|
||||
value: this.consumeNumber(Percentage)
|
||||
};
|
||||
return {
|
||||
type: 'Percentage',
|
||||
loc: this.getLocation(this.tokenStart, this.tokenEnd),
|
||||
value: this.consumeNumber(Percentage),
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(Percentage, node.value + '%');
|
||||
this.token(Percentage, node.value + '%');
|
||||
}
|
||||
|
81
node_modules/css-tree/lib/syntax/node/PseudoClassSelector.js
generated
vendored
81
node_modules/css-tree/lib/syntax/node/PseudoClassSelector.js
generated
vendored
@ -1,63 +1,60 @@
|
||||
import {
|
||||
Ident,
|
||||
Function as FunctionToken,
|
||||
Colon,
|
||||
RightParenthesis
|
||||
Ident,
|
||||
Function as FunctionToken,
|
||||
Colon,
|
||||
RightParenthesis,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
|
||||
export const name = 'PseudoClassSelector';
|
||||
export const walkContext = 'function';
|
||||
export const structure = {
|
||||
name: String,
|
||||
children: [['Raw'], null]
|
||||
name: String,
|
||||
children: [['Raw'], null],
|
||||
};
|
||||
|
||||
// : [ <ident> | <function-token> <any-value>? ) ]
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
let children = null;
|
||||
let name;
|
||||
let nameLowerCase;
|
||||
const start = this.tokenStart;
|
||||
let children = null;
|
||||
let name;
|
||||
let nameLowerCase;
|
||||
|
||||
this.eat(Colon);
|
||||
this.eat(Colon);
|
||||
|
||||
if (this.tokenType === FunctionToken) {
|
||||
name = this.consumeFunctionName();
|
||||
nameLowerCase = name.toLowerCase();
|
||||
if (this.tokenType === FunctionToken) {
|
||||
name = this.consumeFunctionName();
|
||||
nameLowerCase = name.toLowerCase();
|
||||
|
||||
if (hasOwnProperty.call(this.pseudo, nameLowerCase)) {
|
||||
this.skipSC();
|
||||
children = this.pseudo[nameLowerCase].call(this);
|
||||
this.skipSC();
|
||||
} else {
|
||||
children = this.createList();
|
||||
children.push(
|
||||
this.Raw(this.tokenIndex, null, false)
|
||||
);
|
||||
}
|
||||
|
||||
this.eat(RightParenthesis);
|
||||
if (hasOwnProperty.call(this.pseudo, nameLowerCase)) {
|
||||
this.skipSC();
|
||||
children = this.pseudo[nameLowerCase].call(this);
|
||||
this.skipSC();
|
||||
} else {
|
||||
name = this.consume(Ident);
|
||||
children = this.createList();
|
||||
children.push(this.Raw(this.tokenIndex, null, false));
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'PseudoClassSelector',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name,
|
||||
children
|
||||
};
|
||||
this.eat(RightParenthesis);
|
||||
} else {
|
||||
name = this.consume(Ident);
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'PseudoClassSelector',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name,
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(Colon, ':');
|
||||
this.token(Colon, ':');
|
||||
|
||||
if (node.children === null) {
|
||||
this.token(Ident, node.name);
|
||||
} else {
|
||||
this.token(FunctionToken, node.name + '(');
|
||||
this.children(node);
|
||||
this.token(RightParenthesis, ')');
|
||||
}
|
||||
if (node.children === null) {
|
||||
this.token(Ident, node.name);
|
||||
} else {
|
||||
this.token(FunctionToken, node.name + '(');
|
||||
this.children(node);
|
||||
this.token(RightParenthesis, ')');
|
||||
}
|
||||
}
|
||||
|
84
node_modules/css-tree/lib/syntax/node/PseudoElementSelector.js
generated
vendored
84
node_modules/css-tree/lib/syntax/node/PseudoElementSelector.js
generated
vendored
@ -1,64 +1,62 @@
|
||||
import {
|
||||
Ident,
|
||||
Function as FunctionToken,
|
||||
Colon,
|
||||
RightParenthesis
|
||||
Ident,
|
||||
Function as FunctionToken,
|
||||
Colon,
|
||||
RightParenthesis,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
export const name = 'PseudoElementSelector';
|
||||
export const walkContext = 'function';
|
||||
export const structure = {
|
||||
name: String,
|
||||
children: [['Raw'], null]
|
||||
name: String,
|
||||
children: [['Raw'], null],
|
||||
};
|
||||
|
||||
// :: [ <ident> | <function-token> <any-value>? ) ]
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
let children = null;
|
||||
let name;
|
||||
let nameLowerCase;
|
||||
const start = this.tokenStart;
|
||||
let children = null;
|
||||
let name;
|
||||
let nameLowerCase;
|
||||
|
||||
this.eat(Colon);
|
||||
this.eat(Colon);
|
||||
this.eat(Colon);
|
||||
this.eat(Colon);
|
||||
|
||||
if (this.tokenType === FunctionToken) {
|
||||
name = this.consumeFunctionName();
|
||||
nameLowerCase = name.toLowerCase();
|
||||
if (this.tokenType === FunctionToken) {
|
||||
name = this.consumeFunctionName();
|
||||
nameLowerCase = name.toLowerCase();
|
||||
|
||||
if (hasOwnProperty.call(this.pseudo, nameLowerCase)) {
|
||||
this.skipSC();
|
||||
children = this.pseudo[nameLowerCase].call(this);
|
||||
this.skipSC();
|
||||
} else {
|
||||
children = this.createList();
|
||||
children.push(
|
||||
this.Raw(this.tokenIndex, null, false)
|
||||
);
|
||||
}
|
||||
|
||||
this.eat(RightParenthesis);
|
||||
if (hasOwnProperty.call(this.pseudo, nameLowerCase)) {
|
||||
this.skipSC();
|
||||
children = this.pseudo[nameLowerCase].call(this);
|
||||
this.skipSC();
|
||||
} else {
|
||||
name = this.consume(Ident);
|
||||
children = this.createList();
|
||||
children.push(this.Raw(this.tokenIndex, null, false));
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'PseudoElementSelector',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name,
|
||||
children
|
||||
};
|
||||
this.eat(RightParenthesis);
|
||||
} else {
|
||||
name = this.consume(Ident);
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'PseudoElementSelector',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name,
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(Colon, ':');
|
||||
this.token(Colon, ':');
|
||||
this.token(Colon, ':');
|
||||
this.token(Colon, ':');
|
||||
|
||||
if (node.children === null) {
|
||||
this.token(Ident, node.name);
|
||||
} else {
|
||||
this.token(FunctionToken, node.name + '(');
|
||||
this.children(node);
|
||||
this.token(RightParenthesis, ')');
|
||||
}
|
||||
if (node.children === null) {
|
||||
this.token(Ident, node.name);
|
||||
} else {
|
||||
this.token(FunctionToken, node.name + '(');
|
||||
this.children(node);
|
||||
this.token(RightParenthesis, ')');
|
||||
}
|
||||
}
|
||||
|
69
node_modules/css-tree/lib/syntax/node/Ratio.js
generated
vendored
69
node_modules/css-tree/lib/syntax/node/Ratio.js
generated
vendored
@ -1,7 +1,11 @@
|
||||
import { isDigit, Delim, Number as NumberToken } from '../../tokenizer/index.js';
|
||||
import {
|
||||
isDigit,
|
||||
Delim,
|
||||
Number as NumberToken,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
const SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
|
||||
const FULLSTOP = 0x002E; // U+002E FULL STOP (.)
|
||||
const SOLIDUS = 0x002f; // U+002F SOLIDUS (/)
|
||||
const FULLSTOP = 0x002e; // U+002E FULL STOP (.)
|
||||
|
||||
// Terms of <ratio> should be a positive numbers (not zero or negative)
|
||||
// (see https://drafts.csswg.org/mediaqueries-3/#values)
|
||||
@ -10,50 +14,53 @@ const FULLSTOP = 0x002E; // U+002E FULL STOP (.)
|
||||
// to test a term is unsigned number without an exponent part.
|
||||
// Additional checking may be applied on lexer validation.
|
||||
function consumeNumber() {
|
||||
this.skipSC();
|
||||
this.skipSC();
|
||||
|
||||
const value = this.consume(NumberToken);
|
||||
const value = this.consume(NumberToken);
|
||||
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const code = value.charCodeAt(i);
|
||||
if (!isDigit(code) && code !== FULLSTOP) {
|
||||
this.error('Unsigned number is expected', this.tokenStart - value.length + i);
|
||||
}
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const code = value.charCodeAt(i);
|
||||
if (!isDigit(code) && code !== FULLSTOP) {
|
||||
this.error(
|
||||
'Unsigned number is expected',
|
||||
this.tokenStart - value.length + i
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (Number(value) === 0) {
|
||||
this.error('Zero number is not allowed', this.tokenStart - value.length);
|
||||
}
|
||||
if (Number(value) === 0) {
|
||||
this.error('Zero number is not allowed', this.tokenStart - value.length);
|
||||
}
|
||||
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
|
||||
export const name = 'Ratio';
|
||||
export const structure = {
|
||||
left: String,
|
||||
right: String
|
||||
left: String,
|
||||
right: String,
|
||||
};
|
||||
|
||||
// <positive-integer> S* '/' S* <positive-integer>
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
const left = consumeNumber.call(this);
|
||||
let right;
|
||||
const start = this.tokenStart;
|
||||
const left = consumeNumber.call(this);
|
||||
let right;
|
||||
|
||||
this.skipSC();
|
||||
this.eatDelim(SOLIDUS);
|
||||
right = consumeNumber.call(this);
|
||||
this.skipSC();
|
||||
this.eatDelim(SOLIDUS);
|
||||
right = consumeNumber.call(this);
|
||||
|
||||
return {
|
||||
type: 'Ratio',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
left,
|
||||
right
|
||||
};
|
||||
return {
|
||||
type: 'Ratio',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
left,
|
||||
right,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(NumberToken, node.left);
|
||||
this.token(Delim, '/');
|
||||
this.token(NumberToken, node.right);
|
||||
this.token(NumberToken, node.left);
|
||||
this.token(Delim, '/');
|
||||
this.token(NumberToken, node.right);
|
||||
}
|
||||
|
47
node_modules/css-tree/lib/syntax/node/Raw.js
generated
vendored
47
node_modules/css-tree/lib/syntax/node/Raw.js
generated
vendored
@ -1,41 +1,44 @@
|
||||
import { WhiteSpace } from '../../tokenizer/index.js';
|
||||
|
||||
function getOffsetExcludeWS() {
|
||||
if (this.tokenIndex > 0) {
|
||||
if (this.lookupType(-1) === WhiteSpace) {
|
||||
return this.tokenIndex > 1
|
||||
? this.getTokenStart(this.tokenIndex - 1)
|
||||
: this.firstCharOffset;
|
||||
}
|
||||
if (this.tokenIndex > 0) {
|
||||
if (this.lookupType(-1) === WhiteSpace) {
|
||||
return this.tokenIndex > 1 ?
|
||||
this.getTokenStart(this.tokenIndex - 1)
|
||||
: this.firstCharOffset;
|
||||
}
|
||||
}
|
||||
|
||||
return this.tokenStart;
|
||||
return this.tokenStart;
|
||||
}
|
||||
|
||||
export const name = 'Raw';
|
||||
export const structure = {
|
||||
value: String
|
||||
value: String,
|
||||
};
|
||||
|
||||
export function parse(startToken, consumeUntil, excludeWhiteSpace) {
|
||||
const startOffset = this.getTokenStart(startToken);
|
||||
let endOffset;
|
||||
const startOffset = this.getTokenStart(startToken);
|
||||
let endOffset;
|
||||
|
||||
this.skipUntilBalanced(startToken, consumeUntil || this.consumeUntilBalanceEnd);
|
||||
this.skipUntilBalanced(
|
||||
startToken,
|
||||
consumeUntil || this.consumeUntilBalanceEnd
|
||||
);
|
||||
|
||||
if (excludeWhiteSpace && this.tokenStart > startOffset) {
|
||||
endOffset = getOffsetExcludeWS.call(this);
|
||||
} else {
|
||||
endOffset = this.tokenStart;
|
||||
}
|
||||
if (excludeWhiteSpace && this.tokenStart > startOffset) {
|
||||
endOffset = getOffsetExcludeWS.call(this);
|
||||
} else {
|
||||
endOffset = this.tokenStart;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Raw',
|
||||
loc: this.getLocation(startOffset, endOffset),
|
||||
value: this.substring(startOffset, endOffset)
|
||||
};
|
||||
return {
|
||||
type: 'Raw',
|
||||
loc: this.getLocation(startOffset, endOffset),
|
||||
value: this.substring(startOffset, endOffset),
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.tokenize(node.value);
|
||||
this.tokenize(node.value);
|
||||
}
|
||||
|
59
node_modules/css-tree/lib/syntax/node/Rule.js
generated
vendored
59
node_modules/css-tree/lib/syntax/node/Rule.js
generated
vendored
@ -1,51 +1,52 @@
|
||||
import { LeftCurlyBracket } from '../../tokenizer/index.js';
|
||||
|
||||
function consumeRaw(startToken) {
|
||||
return this.Raw(startToken, this.consumeUntilLeftCurlyBracket, true);
|
||||
return this.Raw(startToken, this.consumeUntilLeftCurlyBracket, true);
|
||||
}
|
||||
|
||||
function consumePrelude() {
|
||||
const prelude = this.SelectorList();
|
||||
const prelude = this.SelectorList();
|
||||
|
||||
if (prelude.type !== 'Raw' &&
|
||||
this.eof === false &&
|
||||
this.tokenType !== LeftCurlyBracket) {
|
||||
this.error();
|
||||
}
|
||||
if (
|
||||
prelude.type !== 'Raw' &&
|
||||
this.eof === false &&
|
||||
this.tokenType !== LeftCurlyBracket
|
||||
) {
|
||||
this.error();
|
||||
}
|
||||
|
||||
return prelude;
|
||||
return prelude;
|
||||
}
|
||||
|
||||
export const name = 'Rule';
|
||||
export const walkContext = 'rule';
|
||||
export const structure = {
|
||||
prelude: ['SelectorList', 'Raw'],
|
||||
block: ['Block']
|
||||
prelude: ['SelectorList', 'Raw'],
|
||||
block: ['Block'],
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const startToken = this.tokenIndex;
|
||||
const startOffset = this.tokenStart;
|
||||
let prelude;
|
||||
let block;
|
||||
const startToken = this.tokenIndex;
|
||||
const startOffset = this.tokenStart;
|
||||
let prelude;
|
||||
let block;
|
||||
|
||||
if (this.parseRulePrelude) {
|
||||
prelude = this.parseWithFallback(consumePrelude, consumeRaw);
|
||||
} else {
|
||||
prelude = consumeRaw.call(this, startToken);
|
||||
}
|
||||
if (this.parseRulePrelude) {
|
||||
prelude = this.parseWithFallback(consumePrelude, consumeRaw);
|
||||
} else {
|
||||
prelude = consumeRaw.call(this, startToken);
|
||||
}
|
||||
|
||||
block = this.Block(true);
|
||||
block = this.Block(true);
|
||||
|
||||
return {
|
||||
type: 'Rule',
|
||||
loc: this.getLocation(startOffset, this.tokenStart),
|
||||
prelude,
|
||||
block
|
||||
};
|
||||
return {
|
||||
type: 'Rule',
|
||||
loc: this.getLocation(startOffset, this.tokenStart),
|
||||
prelude,
|
||||
block,
|
||||
};
|
||||
}
|
||||
export function generate(node) {
|
||||
this.node(node.prelude);
|
||||
this.node(node.block);
|
||||
this.node(node.prelude);
|
||||
this.node(node.block);
|
||||
}
|
||||
|
||||
|
44
node_modules/css-tree/lib/syntax/node/Selector.js
generated
vendored
44
node_modules/css-tree/lib/syntax/node/Selector.js
generated
vendored
@ -1,32 +1,34 @@
|
||||
export const name = 'Selector';
|
||||
export const structure = {
|
||||
children: [[
|
||||
'TypeSelector',
|
||||
'IdSelector',
|
||||
'ClassSelector',
|
||||
'AttributeSelector',
|
||||
'PseudoClassSelector',
|
||||
'PseudoElementSelector',
|
||||
'Combinator',
|
||||
'WhiteSpace'
|
||||
]]
|
||||
children: [
|
||||
[
|
||||
'TypeSelector',
|
||||
'IdSelector',
|
||||
'ClassSelector',
|
||||
'AttributeSelector',
|
||||
'PseudoClassSelector',
|
||||
'PseudoElementSelector',
|
||||
'Combinator',
|
||||
'WhiteSpace',
|
||||
],
|
||||
],
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const children = this.readSequence(this.scope.Selector);
|
||||
const children = this.readSequence(this.scope.Selector);
|
||||
|
||||
// nothing were consumed
|
||||
if (this.getFirstListNode(children) === null) {
|
||||
this.error('Selector is expected');
|
||||
}
|
||||
// nothing were consumed
|
||||
if (this.getFirstListNode(children) === null) {
|
||||
this.error('Selector is expected');
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Selector',
|
||||
loc: this.getLocationFromList(children),
|
||||
children
|
||||
};
|
||||
return {
|
||||
type: 'Selector',
|
||||
loc: this.getLocationFromList(children),
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.children(node);
|
||||
this.children(node);
|
||||
}
|
||||
|
35
node_modules/css-tree/lib/syntax/node/SelectorList.js
generated
vendored
35
node_modules/css-tree/lib/syntax/node/SelectorList.js
generated
vendored
@ -3,33 +3,30 @@ import { Comma } from '../../tokenizer/index.js';
|
||||
export const name = 'SelectorList';
|
||||
export const walkContext = 'selector';
|
||||
export const structure = {
|
||||
children: [[
|
||||
'Selector',
|
||||
'Raw'
|
||||
]]
|
||||
children: [['Selector', 'Raw']],
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const children = this.createList();
|
||||
const children = this.createList();
|
||||
|
||||
while (!this.eof) {
|
||||
children.push(this.Selector());
|
||||
while (!this.eof) {
|
||||
children.push(this.Selector());
|
||||
|
||||
if (this.tokenType === Comma) {
|
||||
this.next();
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
if (this.tokenType === Comma) {
|
||||
this.next();
|
||||
continue;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'SelectorList',
|
||||
loc: this.getLocationFromList(children),
|
||||
children
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'SelectorList',
|
||||
loc: this.getLocationFromList(children),
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.children(node, () => this.token(Comma, ','));
|
||||
this.children(node, () => this.token(Comma, ','));
|
||||
}
|
||||
|
14
node_modules/css-tree/lib/syntax/node/String.js
generated
vendored
14
node_modules/css-tree/lib/syntax/node/String.js
generated
vendored
@ -3,17 +3,17 @@ import { decode, encode } from '../../utils/string.js';
|
||||
|
||||
export const name = 'String';
|
||||
export const structure = {
|
||||
value: String
|
||||
value: String,
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
return {
|
||||
type: 'String',
|
||||
loc: this.getLocation(this.tokenStart, this.tokenEnd),
|
||||
value: decode(this.consume(StringToken))
|
||||
};
|
||||
return {
|
||||
type: 'String',
|
||||
loc: this.getLocation(this.tokenStart, this.tokenEnd),
|
||||
value: decode(this.consume(StringToken)),
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(StringToken, encode(node.value));
|
||||
this.token(StringToken, encode(node.value));
|
||||
}
|
||||
|
108
node_modules/css-tree/lib/syntax/node/StyleSheet.js
generated
vendored
108
node_modules/css-tree/lib/syntax/node/StyleSheet.js
generated
vendored
@ -1,82 +1,74 @@
|
||||
import {
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
AtKeyword,
|
||||
CDO,
|
||||
CDC
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
AtKeyword,
|
||||
CDO,
|
||||
CDC,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
const EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!)
|
||||
|
||||
function consumeRaw(startToken) {
|
||||
return this.Raw(startToken, null, false);
|
||||
return this.Raw(startToken, null, false);
|
||||
}
|
||||
|
||||
export const name = 'StyleSheet';
|
||||
export const walkContext = 'stylesheet';
|
||||
export const structure = {
|
||||
children: [[
|
||||
'Comment',
|
||||
'CDO',
|
||||
'CDC',
|
||||
'Atrule',
|
||||
'Rule',
|
||||
'Raw'
|
||||
]]
|
||||
children: [['Comment', 'CDO', 'CDC', 'Atrule', 'Rule', 'Raw']],
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
const children = this.createList();
|
||||
let child;
|
||||
const start = this.tokenStart;
|
||||
const children = this.createList();
|
||||
let child;
|
||||
|
||||
scan:
|
||||
while (!this.eof) {
|
||||
switch (this.tokenType) {
|
||||
case WhiteSpace:
|
||||
this.next();
|
||||
continue;
|
||||
scan: while (!this.eof) {
|
||||
switch (this.tokenType) {
|
||||
case WhiteSpace:
|
||||
this.next();
|
||||
continue;
|
||||
|
||||
case Comment:
|
||||
// ignore comments except exclamation comments (i.e. /*! .. */) on top level
|
||||
if (this.charCodeAt(this.tokenStart + 2) !== EXCLAMATIONMARK) {
|
||||
this.next();
|
||||
continue;
|
||||
}
|
||||
|
||||
child = this.Comment();
|
||||
break;
|
||||
|
||||
case CDO: // <!--
|
||||
child = this.CDO();
|
||||
break;
|
||||
|
||||
case CDC: // -->
|
||||
child = this.CDC();
|
||||
break;
|
||||
|
||||
// CSS Syntax Module Level 3
|
||||
// §2.2 Error handling
|
||||
// At the "top level" of a stylesheet, an <at-keyword-token> starts an at-rule.
|
||||
case AtKeyword:
|
||||
child = this.parseWithFallback(this.Atrule, consumeRaw);
|
||||
break;
|
||||
|
||||
// Anything else starts a qualified rule ...
|
||||
default:
|
||||
child = this.parseWithFallback(this.Rule, consumeRaw);
|
||||
case Comment:
|
||||
// ignore comments except exclamation comments (i.e. /*! .. */) on top level
|
||||
if (this.charCodeAt(this.tokenStart + 2) !== EXCLAMATIONMARK) {
|
||||
this.next();
|
||||
continue;
|
||||
}
|
||||
|
||||
children.push(child);
|
||||
child = this.Comment();
|
||||
break;
|
||||
|
||||
case CDO: // <!--
|
||||
child = this.CDO();
|
||||
break;
|
||||
|
||||
case CDC: // -->
|
||||
child = this.CDC();
|
||||
break;
|
||||
|
||||
// CSS Syntax Module Level 3
|
||||
// §2.2 Error handling
|
||||
// At the "top level" of a stylesheet, an <at-keyword-token> starts an at-rule.
|
||||
case AtKeyword:
|
||||
child = this.parseWithFallback(this.Atrule, consumeRaw);
|
||||
break;
|
||||
|
||||
// Anything else starts a qualified rule ...
|
||||
default:
|
||||
child = this.parseWithFallback(this.Rule, consumeRaw);
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'StyleSheet',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
children
|
||||
};
|
||||
children.push(child);
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'StyleSheet',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.children(node);
|
||||
this.children(node);
|
||||
}
|
||||
|
47
node_modules/css-tree/lib/syntax/node/TypeSelector.js
generated
vendored
47
node_modules/css-tree/lib/syntax/node/TypeSelector.js
generated
vendored
@ -1,20 +1,19 @@
|
||||
import { Ident } from '../../tokenizer/index.js';
|
||||
|
||||
const ASTERISK = 0x002A; // U+002A ASTERISK (*)
|
||||
const VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|)
|
||||
const ASTERISK = 0x002a; // U+002A ASTERISK (*)
|
||||
const VERTICALLINE = 0x007c; // U+007C VERTICAL LINE (|)
|
||||
|
||||
function eatIdentifierOrAsterisk() {
|
||||
if (this.tokenType !== Ident &&
|
||||
this.isDelim(ASTERISK) === false) {
|
||||
this.error('Identifier or asterisk is expected');
|
||||
}
|
||||
if (this.tokenType !== Ident && this.isDelim(ASTERISK) === false) {
|
||||
this.error('Identifier or asterisk is expected');
|
||||
}
|
||||
|
||||
this.next();
|
||||
this.next();
|
||||
}
|
||||
|
||||
export const name = 'TypeSelector';
|
||||
export const structure = {
|
||||
name: String
|
||||
name: String,
|
||||
};
|
||||
|
||||
// ident
|
||||
@ -26,27 +25,27 @@ export const structure = {
|
||||
// |ident
|
||||
// |*
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
const start = this.tokenStart;
|
||||
|
||||
if (this.isDelim(VERTICALLINE)) {
|
||||
this.next();
|
||||
eatIdentifierOrAsterisk.call(this);
|
||||
} else {
|
||||
eatIdentifierOrAsterisk.call(this);
|
||||
|
||||
if (this.isDelim(VERTICALLINE)) {
|
||||
this.next();
|
||||
eatIdentifierOrAsterisk.call(this);
|
||||
} else {
|
||||
eatIdentifierOrAsterisk.call(this);
|
||||
|
||||
if (this.isDelim(VERTICALLINE)) {
|
||||
this.next();
|
||||
eatIdentifierOrAsterisk.call(this);
|
||||
}
|
||||
this.next();
|
||||
eatIdentifierOrAsterisk.call(this);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'TypeSelector',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name: this.substrToCursor(start)
|
||||
};
|
||||
return {
|
||||
type: 'TypeSelector',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
name: this.substrToCursor(start),
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.tokenize(node.name);
|
||||
this.tokenize(node.name);
|
||||
}
|
||||
|
187
node_modules/css-tree/lib/syntax/node/UnicodeRange.js
generated
vendored
187
node_modules/css-tree/lib/syntax/node/UnicodeRange.js
generated
vendored
@ -1,59 +1,57 @@
|
||||
import {
|
||||
isHexDigit,
|
||||
Ident,
|
||||
Number,
|
||||
Dimension
|
||||
} from '../../tokenizer/index.js';
|
||||
import { isHexDigit, Ident, Number, Dimension } from '../../tokenizer/index.js';
|
||||
|
||||
const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
|
||||
const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)
|
||||
const QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?)
|
||||
const PLUSSIGN = 0x002b; // U+002B PLUS SIGN (+)
|
||||
const HYPHENMINUS = 0x002d; // U+002D HYPHEN-MINUS (-)
|
||||
const QUESTIONMARK = 0x003f; // U+003F QUESTION MARK (?)
|
||||
|
||||
function eatHexSequence(offset, allowDash) {
|
||||
let len = 0;
|
||||
let len = 0;
|
||||
|
||||
for (let pos = this.tokenStart + offset; pos < this.tokenEnd; pos++) {
|
||||
const code = this.charCodeAt(pos);
|
||||
for (let pos = this.tokenStart + offset; pos < this.tokenEnd; pos++) {
|
||||
const code = this.charCodeAt(pos);
|
||||
|
||||
if (code === HYPHENMINUS && allowDash && len !== 0) {
|
||||
eatHexSequence.call(this, offset + len + 1, false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!isHexDigit(code)) {
|
||||
this.error(
|
||||
allowDash && len !== 0
|
||||
? 'Hyphen minus' + (len < 6 ? ' or hex digit' : '') + ' is expected'
|
||||
: (len < 6 ? 'Hex digit is expected' : 'Unexpected input'),
|
||||
pos
|
||||
);
|
||||
}
|
||||
|
||||
if (++len > 6) {
|
||||
this.error('Too many hex digits', pos);
|
||||
};
|
||||
if (code === HYPHENMINUS && allowDash && len !== 0) {
|
||||
eatHexSequence.call(this, offset + len + 1, false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
this.next();
|
||||
return len;
|
||||
if (!isHexDigit(code)) {
|
||||
this.error(
|
||||
allowDash && len !== 0 ?
|
||||
'Hyphen minus' + (len < 6 ? ' or hex digit' : '') + ' is expected'
|
||||
: len < 6 ? 'Hex digit is expected'
|
||||
: 'Unexpected input',
|
||||
pos
|
||||
);
|
||||
}
|
||||
|
||||
if (++len > 6) {
|
||||
this.error('Too many hex digits', pos);
|
||||
}
|
||||
}
|
||||
|
||||
this.next();
|
||||
return len;
|
||||
}
|
||||
|
||||
function eatQuestionMarkSequence(max) {
|
||||
let count = 0;
|
||||
let count = 0;
|
||||
|
||||
while (this.isDelim(QUESTIONMARK)) {
|
||||
if (++count > max) {
|
||||
this.error('Too many question marks');
|
||||
}
|
||||
|
||||
this.next();
|
||||
while (this.isDelim(QUESTIONMARK)) {
|
||||
if (++count > max) {
|
||||
this.error('Too many question marks');
|
||||
}
|
||||
|
||||
this.next();
|
||||
}
|
||||
}
|
||||
|
||||
function startsWith(code) {
|
||||
if (this.charCodeAt(this.tokenStart) !== code) {
|
||||
this.error((code === PLUSSIGN ? 'Plus sign' : 'Hyphen minus') + ' is expected');
|
||||
}
|
||||
if (this.charCodeAt(this.tokenStart) !== code) {
|
||||
this.error(
|
||||
(code === PLUSSIGN ? 'Plus sign' : 'Hyphen minus') + ' is expected'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-syntax/#urange
|
||||
@ -76,81 +74,80 @@ function startsWith(code) {
|
||||
// u <number-token> <number-token> |
|
||||
// u '+' '?'+
|
||||
function scanUnicodeRange() {
|
||||
let hexLength = 0;
|
||||
let hexLength = 0;
|
||||
|
||||
switch (this.tokenType) {
|
||||
case Number:
|
||||
// u <number-token> '?'*
|
||||
// u <number-token> <dimension-token>
|
||||
// u <number-token> <number-token>
|
||||
hexLength = eatHexSequence.call(this, 1, true);
|
||||
switch (this.tokenType) {
|
||||
case Number:
|
||||
// u <number-token> '?'*
|
||||
// u <number-token> <dimension-token>
|
||||
// u <number-token> <number-token>
|
||||
hexLength = eatHexSequence.call(this, 1, true);
|
||||
|
||||
if (this.isDelim(QUESTIONMARK)) {
|
||||
eatQuestionMarkSequence.call(this, 6 - hexLength);
|
||||
break;
|
||||
}
|
||||
if (this.isDelim(QUESTIONMARK)) {
|
||||
eatQuestionMarkSequence.call(this, 6 - hexLength);
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.tokenType === Dimension ||
|
||||
this.tokenType === Number) {
|
||||
startsWith.call(this, HYPHENMINUS);
|
||||
eatHexSequence.call(this, 1, false);
|
||||
break;
|
||||
}
|
||||
if (this.tokenType === Dimension || this.tokenType === Number) {
|
||||
startsWith.call(this, HYPHENMINUS);
|
||||
eatHexSequence.call(this, 1, false);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case Dimension:
|
||||
// u <dimension-token> '?'*
|
||||
hexLength = eatHexSequence.call(this, 1, true);
|
||||
case Dimension:
|
||||
// u <dimension-token> '?'*
|
||||
hexLength = eatHexSequence.call(this, 1, true);
|
||||
|
||||
if (hexLength > 0) {
|
||||
eatQuestionMarkSequence.call(this, 6 - hexLength);
|
||||
}
|
||||
if (hexLength > 0) {
|
||||
eatQuestionMarkSequence.call(this, 6 - hexLength);
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
// u '+' <ident-token> '?'*
|
||||
// u '+' '?'+
|
||||
this.eatDelim(PLUSSIGN);
|
||||
default:
|
||||
// u '+' <ident-token> '?'*
|
||||
// u '+' '?'+
|
||||
this.eatDelim(PLUSSIGN);
|
||||
|
||||
if (this.tokenType === Ident) {
|
||||
hexLength = eatHexSequence.call(this, 0, true);
|
||||
if (hexLength > 0) {
|
||||
eatQuestionMarkSequence.call(this, 6 - hexLength);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (this.tokenType === Ident) {
|
||||
hexLength = eatHexSequence.call(this, 0, true);
|
||||
if (hexLength > 0) {
|
||||
eatQuestionMarkSequence.call(this, 6 - hexLength);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.isDelim(QUESTIONMARK)) {
|
||||
this.next();
|
||||
eatQuestionMarkSequence.call(this, 5);
|
||||
break;
|
||||
}
|
||||
if (this.isDelim(QUESTIONMARK)) {
|
||||
this.next();
|
||||
eatQuestionMarkSequence.call(this, 5);
|
||||
break;
|
||||
}
|
||||
|
||||
this.error('Hex digit or question mark is expected');
|
||||
}
|
||||
this.error('Hex digit or question mark is expected');
|
||||
}
|
||||
}
|
||||
|
||||
export const name = 'UnicodeRange';
|
||||
export const structure = {
|
||||
value: String
|
||||
value: String,
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
const start = this.tokenStart;
|
||||
|
||||
// U or u
|
||||
this.eatIdent('u');
|
||||
scanUnicodeRange.call(this);
|
||||
// U or u
|
||||
this.eatIdent('u');
|
||||
scanUnicodeRange.call(this);
|
||||
|
||||
return {
|
||||
type: 'UnicodeRange',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
value: this.substrToCursor(start)
|
||||
};
|
||||
return {
|
||||
type: 'UnicodeRange',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
value: this.substrToCursor(start),
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.tokenize(node.value);
|
||||
this.tokenize(node.value);
|
||||
}
|
||||
|
64
node_modules/css-tree/lib/syntax/node/Url.js
generated
vendored
64
node_modules/css-tree/lib/syntax/node/Url.js
generated
vendored
@ -1,52 +1,52 @@
|
||||
import * as url from '../../utils/url.js';
|
||||
import * as string from '../../utils/string.js';
|
||||
import {
|
||||
Function as FunctionToken,
|
||||
String as StringToken,
|
||||
Url,
|
||||
RightParenthesis
|
||||
Function as FunctionToken,
|
||||
String as StringToken,
|
||||
Url,
|
||||
RightParenthesis,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
export const name = 'Url';
|
||||
export const structure = {
|
||||
value: String
|
||||
value: String,
|
||||
};
|
||||
|
||||
// <url-token> | <function-token> <string> )
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
let value;
|
||||
const start = this.tokenStart;
|
||||
let value;
|
||||
|
||||
switch (this.tokenType) {
|
||||
case Url:
|
||||
value = url.decode(this.consume(Url));
|
||||
break;
|
||||
switch (this.tokenType) {
|
||||
case Url:
|
||||
value = url.decode(this.consume(Url));
|
||||
break;
|
||||
|
||||
case FunctionToken:
|
||||
if (!this.cmpStr(this.tokenStart, this.tokenEnd, 'url(')) {
|
||||
this.error('Function name must be `url`');
|
||||
}
|
||||
case FunctionToken:
|
||||
if (!this.cmpStr(this.tokenStart, this.tokenEnd, 'url(')) {
|
||||
this.error('Function name must be `url`');
|
||||
}
|
||||
|
||||
this.eat(FunctionToken);
|
||||
this.skipSC();
|
||||
value = string.decode(this.consume(StringToken));
|
||||
this.skipSC();
|
||||
if (!this.eof) {
|
||||
this.eat(RightParenthesis);
|
||||
}
|
||||
break;
|
||||
this.eat(FunctionToken);
|
||||
this.skipSC();
|
||||
value = string.decode(this.consume(StringToken));
|
||||
this.skipSC();
|
||||
if (!this.eof) {
|
||||
this.eat(RightParenthesis);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
this.error('Url or Function is expected');
|
||||
}
|
||||
default:
|
||||
this.error('Url or Function is expected');
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Url',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
value
|
||||
};
|
||||
return {
|
||||
type: 'Url',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
value,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(Url, url.encode(node.value));
|
||||
this.token(Url, url.encode(node.value));
|
||||
}
|
||||
|
18
node_modules/css-tree/lib/syntax/node/Value.js
generated
vendored
18
node_modules/css-tree/lib/syntax/node/Value.js
generated
vendored
@ -1,19 +1,19 @@
|
||||
export const name = 'Value';
|
||||
export const structure = {
|
||||
children: [[]]
|
||||
children: [[]],
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
const start = this.tokenStart;
|
||||
const children = this.readSequence(this.scope.Value);
|
||||
const start = this.tokenStart;
|
||||
const children = this.readSequence(this.scope.Value);
|
||||
|
||||
return {
|
||||
type: 'Value',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
children
|
||||
};
|
||||
return {
|
||||
type: 'Value',
|
||||
loc: this.getLocation(start, this.tokenStart),
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.children(node);
|
||||
this.children(node);
|
||||
}
|
||||
|
24
node_modules/css-tree/lib/syntax/node/WhiteSpace.js
generated
vendored
24
node_modules/css-tree/lib/syntax/node/WhiteSpace.js
generated
vendored
@ -1,27 +1,27 @@
|
||||
import { WhiteSpace } from '../../tokenizer/index.js';
|
||||
|
||||
const SPACE = Object.freeze({
|
||||
type: 'WhiteSpace',
|
||||
loc: null,
|
||||
value: ' '
|
||||
type: 'WhiteSpace',
|
||||
loc: null,
|
||||
value: ' ',
|
||||
});
|
||||
|
||||
export const name = 'WhiteSpace';
|
||||
export const structure = {
|
||||
value: String
|
||||
value: String,
|
||||
};
|
||||
|
||||
export function parse() {
|
||||
this.eat(WhiteSpace);
|
||||
return SPACE;
|
||||
this.eat(WhiteSpace);
|
||||
return SPACE;
|
||||
|
||||
// return {
|
||||
// type: 'WhiteSpace',
|
||||
// loc: this.getLocation(this.tokenStart, this.tokenEnd),
|
||||
// value: this.consume(WHITESPACE)
|
||||
// };
|
||||
// return {
|
||||
// type: 'WhiteSpace',
|
||||
// loc: this.getLocation(this.tokenStart, this.tokenEnd),
|
||||
// value: this.consume(WHITESPACE)
|
||||
// };
|
||||
}
|
||||
|
||||
export function generate(node) {
|
||||
this.token(WhiteSpace, node.value);
|
||||
this.token(WhiteSpace, node.value);
|
||||
}
|
||||
|
60
node_modules/css-tree/lib/syntax/pseudo/index.js
generated
vendored
60
node_modules/css-tree/lib/syntax/pseudo/index.js
generated
vendored
@ -1,48 +1,40 @@
|
||||
const selectorList = {
|
||||
parse() {
|
||||
return this.createSingleNodeList(
|
||||
this.SelectorList()
|
||||
);
|
||||
}
|
||||
parse() {
|
||||
return this.createSingleNodeList(this.SelectorList());
|
||||
},
|
||||
};
|
||||
|
||||
const selector = {
|
||||
parse() {
|
||||
return this.createSingleNodeList(
|
||||
this.Selector()
|
||||
);
|
||||
}
|
||||
parse() {
|
||||
return this.createSingleNodeList(this.Selector());
|
||||
},
|
||||
};
|
||||
|
||||
const identList = {
|
||||
parse() {
|
||||
return this.createSingleNodeList(
|
||||
this.Identifier()
|
||||
);
|
||||
}
|
||||
parse() {
|
||||
return this.createSingleNodeList(this.Identifier());
|
||||
},
|
||||
};
|
||||
|
||||
const nth = {
|
||||
parse() {
|
||||
return this.createSingleNodeList(
|
||||
this.Nth()
|
||||
);
|
||||
}
|
||||
parse() {
|
||||
return this.createSingleNodeList(this.Nth());
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
'dir': identList,
|
||||
'has': selectorList,
|
||||
'lang': identList,
|
||||
'matches': selectorList,
|
||||
'is': selectorList,
|
||||
'-moz-any': selectorList,
|
||||
'-webkit-any': selectorList,
|
||||
'where': selectorList,
|
||||
'not': selectorList,
|
||||
'nth-child': nth,
|
||||
'nth-last-child': nth,
|
||||
'nth-last-of-type': nth,
|
||||
'nth-of-type': nth,
|
||||
'slotted': selector
|
||||
dir: identList,
|
||||
has: selectorList,
|
||||
lang: identList,
|
||||
matches: selectorList,
|
||||
is: selectorList,
|
||||
'-moz-any': selectorList,
|
||||
'-webkit-any': selectorList,
|
||||
where: selectorList,
|
||||
not: selectorList,
|
||||
'nth-child': nth,
|
||||
'nth-last-child': nth,
|
||||
'nth-last-of-type': nth,
|
||||
'nth-of-type': nth,
|
||||
slotted: selector,
|
||||
};
|
||||
|
2
node_modules/css-tree/lib/syntax/scope/atrulePrelude.js
generated
vendored
2
node_modules/css-tree/lib/syntax/scope/atrulePrelude.js
generated
vendored
@ -1,5 +1,5 @@
|
||||
import getNode from './default.js';
|
||||
|
||||
export default {
|
||||
getNode
|
||||
getNode,
|
||||
};
|
||||
|
132
node_modules/css-tree/lib/syntax/scope/default.js
generated
vendored
132
node_modules/css-tree/lib/syntax/scope/default.js
generated
vendored
@ -1,85 +1,89 @@
|
||||
import {
|
||||
Ident,
|
||||
String as StringToken,
|
||||
Number as NumberToken,
|
||||
Function as FunctionToken,
|
||||
Url,
|
||||
Hash,
|
||||
Dimension,
|
||||
Percentage,
|
||||
LeftParenthesis,
|
||||
LeftSquareBracket,
|
||||
Comma,
|
||||
Delim
|
||||
Ident,
|
||||
String as StringToken,
|
||||
Number as NumberToken,
|
||||
Function as FunctionToken,
|
||||
Url,
|
||||
Hash,
|
||||
Dimension,
|
||||
Percentage,
|
||||
LeftParenthesis,
|
||||
LeftSquareBracket,
|
||||
Comma,
|
||||
Delim,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
|
||||
const ASTERISK = 0x002A; // U+002A ASTERISK (*)
|
||||
const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
|
||||
const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)
|
||||
const SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
|
||||
const U = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
|
||||
const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
|
||||
const ASTERISK = 0x002a; // U+002A ASTERISK (*)
|
||||
const PLUSSIGN = 0x002b; // U+002B PLUS SIGN (+)
|
||||
const HYPHENMINUS = 0x002d; // U+002D HYPHEN-MINUS (-)
|
||||
const SOLIDUS = 0x002f; // U+002F SOLIDUS (/)
|
||||
const U = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
|
||||
|
||||
export default function defaultRecognizer(context) {
|
||||
switch (this.tokenType) {
|
||||
case Hash:
|
||||
return this.Hash();
|
||||
switch (this.tokenType) {
|
||||
case Hash:
|
||||
return this.Hash();
|
||||
|
||||
case Comma:
|
||||
return this.Operator();
|
||||
case Comma:
|
||||
return this.Operator();
|
||||
|
||||
case LeftParenthesis:
|
||||
return this.Parentheses(this.readSequence, context.recognizer);
|
||||
case LeftParenthesis:
|
||||
return this.Parentheses(this.readSequence, context.recognizer);
|
||||
|
||||
case LeftSquareBracket:
|
||||
return this.Brackets(this.readSequence, context.recognizer);
|
||||
case LeftSquareBracket:
|
||||
return this.Brackets(this.readSequence, context.recognizer);
|
||||
|
||||
case StringToken:
|
||||
return this.String();
|
||||
case StringToken:
|
||||
return this.String();
|
||||
|
||||
case Dimension:
|
||||
return this.Dimension();
|
||||
case Dimension:
|
||||
return this.Dimension();
|
||||
|
||||
case Percentage:
|
||||
return this.Percentage();
|
||||
case Percentage:
|
||||
return this.Percentage();
|
||||
|
||||
case NumberToken:
|
||||
return this.Number();
|
||||
case NumberToken:
|
||||
return this.Number();
|
||||
|
||||
case FunctionToken:
|
||||
return this.cmpStr(this.tokenStart, this.tokenEnd, 'url(')
|
||||
? this.Url()
|
||||
: this.Function(this.readSequence, context.recognizer);
|
||||
case FunctionToken:
|
||||
return this.cmpStr(this.tokenStart, this.tokenEnd, 'url(') ?
|
||||
this.Url()
|
||||
: this.Function(this.readSequence, context.recognizer);
|
||||
|
||||
case Url:
|
||||
return this.Url();
|
||||
case Url:
|
||||
return this.Url();
|
||||
|
||||
case Ident:
|
||||
// check for unicode range, it should start with u+ or U+
|
||||
if (this.cmpChar(this.tokenStart, U) &&
|
||||
this.cmpChar(this.tokenStart + 1, PLUSSIGN)) {
|
||||
return this.UnicodeRange();
|
||||
} else {
|
||||
return this.Identifier();
|
||||
}
|
||||
case Ident:
|
||||
// check for unicode range, it should start with u+ or U+
|
||||
if (
|
||||
this.cmpChar(this.tokenStart, U) &&
|
||||
this.cmpChar(this.tokenStart + 1, PLUSSIGN)
|
||||
) {
|
||||
return this.UnicodeRange();
|
||||
} else {
|
||||
return this.Identifier();
|
||||
}
|
||||
|
||||
case Delim: {
|
||||
const code = this.charCodeAt(this.tokenStart);
|
||||
case Delim: {
|
||||
const code = this.charCodeAt(this.tokenStart);
|
||||
|
||||
if (code === SOLIDUS ||
|
||||
code === ASTERISK ||
|
||||
code === PLUSSIGN ||
|
||||
code === HYPHENMINUS) {
|
||||
return this.Operator(); // TODO: replace with Delim
|
||||
}
|
||||
if (
|
||||
code === SOLIDUS ||
|
||||
code === ASTERISK ||
|
||||
code === PLUSSIGN ||
|
||||
code === HYPHENMINUS
|
||||
) {
|
||||
return this.Operator(); // TODO: replace with Delim
|
||||
}
|
||||
|
||||
// TODO: produce a node with Delim node type
|
||||
// TODO: produce a node with Delim node type
|
||||
|
||||
if (code === NUMBERSIGN) {
|
||||
this.error('Hex or identifier is expected', this.tokenStart + 1);
|
||||
}
|
||||
if (code === NUMBERSIGN) {
|
||||
this.error('Hex or identifier is expected', this.tokenStart + 1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
139
node_modules/css-tree/lib/syntax/scope/selector.js
generated
vendored
139
node_modules/css-tree/lib/syntax/scope/selector.js
generated
vendored
@ -1,90 +1,95 @@
|
||||
import {
|
||||
Delim,
|
||||
Ident,
|
||||
Dimension,
|
||||
Percentage,
|
||||
Number as NumberToken,
|
||||
Hash,
|
||||
Colon,
|
||||
LeftSquareBracket
|
||||
Delim,
|
||||
Ident,
|
||||
Dimension,
|
||||
Percentage,
|
||||
Number as NumberToken,
|
||||
Hash,
|
||||
Colon,
|
||||
LeftSquareBracket,
|
||||
} from '../../tokenizer/index.js';
|
||||
|
||||
const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
|
||||
const ASTERISK = 0x002A; // U+002A ASTERISK (*)
|
||||
const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
|
||||
const SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
|
||||
const FULLSTOP = 0x002E; // U+002E FULL STOP (.)
|
||||
const GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>)
|
||||
const VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|)
|
||||
const TILDE = 0x007E; // U+007E TILDE (~)
|
||||
const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
|
||||
const ASTERISK = 0x002a; // U+002A ASTERISK (*)
|
||||
const PLUSSIGN = 0x002b; // U+002B PLUS SIGN (+)
|
||||
const SOLIDUS = 0x002f; // U+002F SOLIDUS (/)
|
||||
const FULLSTOP = 0x002e; // U+002E FULL STOP (.)
|
||||
const GREATERTHANSIGN = 0x003e; // U+003E GREATER-THAN SIGN (>)
|
||||
const VERTICALLINE = 0x007c; // U+007C VERTICAL LINE (|)
|
||||
const TILDE = 0x007e; // U+007E TILDE (~)
|
||||
|
||||
function onWhiteSpace(next, children) {
|
||||
if (children.last !== null && children.last.type !== 'Combinator' &&
|
||||
next !== null && next.type !== 'Combinator') {
|
||||
children.push({ // FIXME: this.Combinator() should be used instead
|
||||
type: 'Combinator',
|
||||
loc: null,
|
||||
name: ' '
|
||||
});
|
||||
}
|
||||
if (
|
||||
children.last !== null &&
|
||||
children.last.type !== 'Combinator' &&
|
||||
next !== null &&
|
||||
next.type !== 'Combinator'
|
||||
) {
|
||||
children.push({
|
||||
// FIXME: this.Combinator() should be used instead
|
||||
type: 'Combinator',
|
||||
loc: null,
|
||||
name: ' ',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getNode() {
|
||||
switch (this.tokenType) {
|
||||
case LeftSquareBracket:
|
||||
return this.AttributeSelector();
|
||||
switch (this.tokenType) {
|
||||
case LeftSquareBracket:
|
||||
return this.AttributeSelector();
|
||||
|
||||
case Hash:
|
||||
return this.IdSelector();
|
||||
case Hash:
|
||||
return this.IdSelector();
|
||||
|
||||
case Colon:
|
||||
if (this.lookupType(1) === Colon) {
|
||||
return this.PseudoElementSelector();
|
||||
} else {
|
||||
return this.PseudoClassSelector();
|
||||
}
|
||||
case Colon:
|
||||
if (this.lookupType(1) === Colon) {
|
||||
return this.PseudoElementSelector();
|
||||
} else {
|
||||
return this.PseudoClassSelector();
|
||||
}
|
||||
|
||||
case Ident:
|
||||
return this.TypeSelector();
|
||||
case Ident:
|
||||
return this.TypeSelector();
|
||||
|
||||
case NumberToken:
|
||||
case Percentage:
|
||||
return this.Percentage();
|
||||
case NumberToken:
|
||||
case Percentage:
|
||||
return this.Percentage();
|
||||
|
||||
case Dimension:
|
||||
// throws when .123ident
|
||||
if (this.charCodeAt(this.tokenStart) === FULLSTOP) {
|
||||
this.error('Identifier is expected', this.tokenStart + 1);
|
||||
}
|
||||
break;
|
||||
case Dimension:
|
||||
// throws when .123ident
|
||||
if (this.charCodeAt(this.tokenStart) === FULLSTOP) {
|
||||
this.error('Identifier is expected', this.tokenStart + 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case Delim: {
|
||||
const code = this.charCodeAt(this.tokenStart);
|
||||
case Delim: {
|
||||
const code = this.charCodeAt(this.tokenStart);
|
||||
|
||||
switch (code) {
|
||||
case PLUSSIGN:
|
||||
case GREATERTHANSIGN:
|
||||
case TILDE:
|
||||
case SOLIDUS: // /deep/
|
||||
return this.Combinator();
|
||||
switch (code) {
|
||||
case PLUSSIGN:
|
||||
case GREATERTHANSIGN:
|
||||
case TILDE:
|
||||
case SOLIDUS: // /deep/
|
||||
return this.Combinator();
|
||||
|
||||
case FULLSTOP:
|
||||
return this.ClassSelector();
|
||||
case FULLSTOP:
|
||||
return this.ClassSelector();
|
||||
|
||||
case ASTERISK:
|
||||
case VERTICALLINE:
|
||||
return this.TypeSelector();
|
||||
case ASTERISK:
|
||||
case VERTICALLINE:
|
||||
return this.TypeSelector();
|
||||
|
||||
case NUMBERSIGN:
|
||||
return this.IdSelector();
|
||||
}
|
||||
case NUMBERSIGN:
|
||||
return this.IdSelector();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
onWhiteSpace,
|
||||
getNode
|
||||
onWhiteSpace,
|
||||
getNode,
|
||||
};
|
||||
|
33
node_modules/css-tree/lib/syntax/scope/value.js
generated
vendored
33
node_modules/css-tree/lib/syntax/scope/value.js
generated
vendored
@ -3,23 +3,24 @@ import expressionFn from '../function/expression.js';
|
||||
import varFn from '../function/var.js';
|
||||
|
||||
function isPlusMinusOperator(node) {
|
||||
return (
|
||||
node !== null &&
|
||||
node.type === 'Operator' &&
|
||||
(node.value[node.value.length - 1] === '-' || node.value[node.value.length - 1] === '+')
|
||||
);
|
||||
return (
|
||||
node !== null &&
|
||||
node.type === 'Operator' &&
|
||||
(node.value[node.value.length - 1] === '-' ||
|
||||
node.value[node.value.length - 1] === '+')
|
||||
);
|
||||
}
|
||||
|
||||
export default {
|
||||
getNode,
|
||||
onWhiteSpace(next, children) {
|
||||
if (isPlusMinusOperator(next)) {
|
||||
next.value = ' ' + next.value;
|
||||
}
|
||||
if (isPlusMinusOperator(children.last)) {
|
||||
children.last.value += ' ';
|
||||
}
|
||||
},
|
||||
'expression': expressionFn,
|
||||
'var': varFn
|
||||
getNode,
|
||||
onWhiteSpace(next, children) {
|
||||
if (isPlusMinusOperator(next)) {
|
||||
next.value = ' ' + next.value;
|
||||
}
|
||||
if (isPlusMinusOperator(children.last)) {
|
||||
children.last.value += ' ';
|
||||
}
|
||||
},
|
||||
expression: expressionFn,
|
||||
var: varFn,
|
||||
};
|
||||
|
134
node_modules/css-tree/lib/tokenizer/OffsetToLocation.js
generated
vendored
134
node_modules/css-tree/lib/tokenizer/OffsetToLocation.js
generated
vendored
@ -6,82 +6,86 @@ 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;
|
||||
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);
|
||||
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++;
|
||||
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;
|
||||
}
|
||||
line++;
|
||||
column = 1;
|
||||
}
|
||||
}
|
||||
|
||||
lines[sourceLength] = line;
|
||||
columns[sourceLength] = column;
|
||||
lines[sourceLength] = line;
|
||||
columns[sourceLength] = column;
|
||||
|
||||
host.lines = lines;
|
||||
host.columns = columns;
|
||||
host.computed = true;
|
||||
host.lines = lines;
|
||||
host.columns = columns;
|
||||
host.computed = true;
|
||||
}
|
||||
|
||||
export class OffsetToLocation {
|
||||
constructor() {
|
||||
this.lines = null;
|
||||
this.columns = null;
|
||||
this.computed = false;
|
||||
constructor() {
|
||||
this.lines = null;
|
||||
this.columns = null;
|
||||
this.computed = false;
|
||||
}
|
||||
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);
|
||||
}
|
||||
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]
|
||||
};
|
||||
return {
|
||||
source: filename,
|
||||
offset: this.startOffset + offset,
|
||||
line: this.lines[offset],
|
||||
column: this.columns[offset],
|
||||
};
|
||||
}
|
||||
getLocationRange(start, end, filename) {
|
||||
if (!this.computed) {
|
||||
computeLinesAndColumns(this);
|
||||
}
|
||||
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]
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
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],
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
476
node_modules/css-tree/lib/tokenizer/TokenStream.js
generated
vendored
476
node_modules/css-tree/lib/tokenizer/TokenStream.js
generated
vendored
@ -2,271 +2,273 @@ 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
|
||||
WhiteSpace,
|
||||
Comment,
|
||||
Delim,
|
||||
EOF,
|
||||
Function as FunctionToken,
|
||||
LeftParenthesis,
|
||||
RightParenthesis,
|
||||
LeftSquareBracket,
|
||||
RightSquareBracket,
|
||||
LeftCurlyBracket,
|
||||
RightCurlyBracket,
|
||||
} from './types.js';
|
||||
|
||||
const OFFSET_MASK = 0x00FFFFFF;
|
||||
const OFFSET_MASK = 0x00ffffff;
|
||||
const TYPE_SHIFT = 24;
|
||||
const balancePair = new Map([
|
||||
[FunctionToken, RightParenthesis],
|
||||
[LeftParenthesis, RightParenthesis],
|
||||
[LeftSquareBracket, RightSquareBracket],
|
||||
[LeftCurlyBracket, RightCurlyBracket]
|
||||
[FunctionToken, RightParenthesis],
|
||||
[LeftParenthesis, RightParenthesis],
|
||||
[LeftSquareBracket, RightSquareBracket],
|
||||
[LeftCurlyBracket, RightCurlyBracket],
|
||||
]);
|
||||
|
||||
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 || '');
|
||||
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 balanceCloseType = 0;
|
||||
let balanceStart = 0;
|
||||
let firstCharOffset = -1;
|
||||
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 balanceCloseType = 0;
|
||||
let balanceStart = 0;
|
||||
let firstCharOffset = -1;
|
||||
|
||||
// capture buffers
|
||||
this.offsetAndType = null;
|
||||
this.balance = null;
|
||||
// capture buffers
|
||||
this.offsetAndType = null;
|
||||
this.balance = null;
|
||||
|
||||
tokenize(source, (type, start, end) => {
|
||||
switch (type) {
|
||||
default:
|
||||
balance[tokenCount] = sourceLength;
|
||||
break;
|
||||
tokenize(source, (type, start, end) => {
|
||||
switch (type) {
|
||||
default:
|
||||
balance[tokenCount] = sourceLength;
|
||||
break;
|
||||
|
||||
case balanceCloseType: {
|
||||
let 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 LeftParenthesis:
|
||||
case FunctionToken:
|
||||
case LeftSquareBracket:
|
||||
case LeftCurlyBracket:
|
||||
balance[tokenCount] = balanceStart;
|
||||
balanceCloseType = balancePair.get(type);
|
||||
balanceStart = (balanceCloseType << TYPE_SHIFT) | tokenCount;
|
||||
break;
|
||||
case balanceCloseType: {
|
||||
let 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;
|
||||
}
|
||||
|
||||
offsetAndType[tokenCount++] = (type << TYPE_SHIFT) | end;
|
||||
if (firstCharOffset === -1) {
|
||||
firstCharOffset = start;
|
||||
}
|
||||
});
|
||||
|
||||
// finalize buffers
|
||||
offsetAndType[tokenCount] = (EOF << TYPE_SHIFT) | sourceLength; // <EOF-token>
|
||||
balance[tokenCount] = sourceLength;
|
||||
balance[sourceLength] = sourceLength; // prevents false positive balance match with any token
|
||||
while (balanceStart !== 0) {
|
||||
const balancePrev = balanceStart & OFFSET_MASK;
|
||||
balanceStart = balance[balancePrev];
|
||||
balance[balancePrev] = sourceLength;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this.source = source;
|
||||
this.firstCharOffset = firstCharOffset === -1 ? 0 : firstCharOffset;
|
||||
this.tokenCount = tokenCount;
|
||||
this.offsetAndType = offsetAndType;
|
||||
this.balance = balance;
|
||||
case LeftParenthesis:
|
||||
case FunctionToken:
|
||||
case LeftSquareBracket:
|
||||
case LeftCurlyBracket:
|
||||
balance[tokenCount] = balanceStart;
|
||||
balanceCloseType = balancePair.get(type);
|
||||
balanceStart = (balanceCloseType << TYPE_SHIFT) | tokenCount;
|
||||
break;
|
||||
}
|
||||
|
||||
this.reset();
|
||||
this.next();
|
||||
offsetAndType[tokenCount++] = (type << TYPE_SHIFT) | end;
|
||||
if (firstCharOffset === -1) {
|
||||
firstCharOffset = start;
|
||||
}
|
||||
});
|
||||
|
||||
// finalize buffers
|
||||
offsetAndType[tokenCount] = (EOF << TYPE_SHIFT) | sourceLength; // <EOF-token>
|
||||
balance[tokenCount] = sourceLength;
|
||||
balance[sourceLength] = sourceLength; // prevents false positive balance match with any token
|
||||
while (balanceStart !== 0) {
|
||||
const balancePrev = balanceStart & OFFSET_MASK;
|
||||
balanceStart = balance[balancePrev];
|
||||
balance[balancePrev] = sourceLength;
|
||||
}
|
||||
|
||||
lookupType(offset) {
|
||||
offset += this.tokenIndex;
|
||||
this.source = source;
|
||||
this.firstCharOffset = firstCharOffset === -1 ? 0 : firstCharOffset;
|
||||
this.tokenCount = tokenCount;
|
||||
this.offsetAndType = offsetAndType;
|
||||
this.balance = balance;
|
||||
|
||||
if (offset < this.tokenCount) {
|
||||
return this.offsetAndType[offset] >> TYPE_SHIFT;
|
||||
}
|
||||
this.reset();
|
||||
this.next();
|
||||
}
|
||||
|
||||
return EOF;
|
||||
}
|
||||
lookupOffset(offset) {
|
||||
offset += this.tokenIndex;
|
||||
lookupType(offset) {
|
||||
offset += this.tokenIndex;
|
||||
|
||||
if (offset < this.tokenCount) {
|
||||
return this.offsetAndType[offset - 1] & OFFSET_MASK;
|
||||
}
|
||||
|
||||
return this.source.length;
|
||||
}
|
||||
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);
|
||||
if (offset < this.tokenCount) {
|
||||
return this.offsetAndType[offset] >> TYPE_SHIFT;
|
||||
}
|
||||
|
||||
isBalanceEdge(pos) {
|
||||
return this.balance[this.tokenIndex] < pos;
|
||||
}
|
||||
isDelim(code, offset) {
|
||||
if (offset) {
|
||||
return (
|
||||
this.lookupType(offset) === Delim &&
|
||||
this.source.charCodeAt(this.lookupOffset(offset)) === code
|
||||
);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
lookupOffset(offset) {
|
||||
offset += this.tokenIndex;
|
||||
|
||||
return (
|
||||
this.tokenType === Delim &&
|
||||
this.source.charCodeAt(this.tokenStart) === code
|
||||
);
|
||||
if (offset < this.tokenCount) {
|
||||
return this.offsetAndType[offset - 1] & OFFSET_MASK;
|
||||
}
|
||||
|
||||
skip(tokenCount) {
|
||||
let next = this.tokenIndex + tokenCount;
|
||||
return this.source.length;
|
||||
}
|
||||
lookupValue(offset, referenceStr) {
|
||||
offset += this.tokenIndex;
|
||||
|
||||
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;
|
||||
let offset;
|
||||
|
||||
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
|
||||
if (this.balance[balanceEnd] === cursor) {
|
||||
cursor = balanceEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.skip(cursor - this.tokenIndex);
|
||||
if (offset < this.tokenCount) {
|
||||
return cmpStr(
|
||||
this.source,
|
||||
this.offsetAndType[offset - 1] & OFFSET_MASK,
|
||||
this.offsetAndType[offset] & OFFSET_MASK,
|
||||
referenceStr
|
||||
);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
getTokenStart(tokenIndex) {
|
||||
if (tokenIndex === this.tokenIndex) {
|
||||
return this.tokenStart;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
let offset;
|
||||
|
||||
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
|
||||
if (this.balance[balanceEnd] === cursor) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
10
node_modules/css-tree/lib/tokenizer/adopt-buffer.js
generated
vendored
10
node_modules/css-tree/lib/tokenizer/adopt-buffer.js
generated
vendored
@ -1,9 +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));
|
||||
}
|
||||
if (buffer === null || buffer.length < size) {
|
||||
return new Uint32Array(Math.max(size + 1024, MIN_SIZE));
|
||||
}
|
||||
|
||||
return buffer;
|
||||
};
|
||||
return buffer;
|
||||
}
|
||||
|
191
node_modules/css-tree/lib/tokenizer/char-code-definitions.js
generated
vendored
191
node_modules/css-tree/lib/tokenizer/char-code-definitions.js
generated
vendored
@ -6,66 +6,66 @@ const EOF = 0;
|
||||
// digit
|
||||
// A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9).
|
||||
export function isDigit(code) {
|
||||
return code >= 0x0030 && code <= 0x0039;
|
||||
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).
|
||||
export function isHexDigit(code) {
|
||||
return (
|
||||
isDigit(code) || // 0 .. 9
|
||||
(code >= 0x0041 && code <= 0x0046) || // A .. F
|
||||
(code >= 0x0061 && code <= 0x0066) // a .. f
|
||||
);
|
||||
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).
|
||||
export function isUppercaseLetter(code) {
|
||||
return code >= 0x0041 && code <= 0x005A;
|
||||
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).
|
||||
export function isLowercaseLetter(code) {
|
||||
return code >= 0x0061 && code <= 0x007A;
|
||||
return code >= 0x0061 && code <= 0x007a;
|
||||
}
|
||||
|
||||
// letter
|
||||
// An uppercase letter or a lowercase letter.
|
||||
export function isLetter(code) {
|
||||
return isUppercaseLetter(code) || isLowercaseLetter(code);
|
||||
return isUppercaseLetter(code) || isLowercaseLetter(code);
|
||||
}
|
||||
|
||||
// non-ASCII code point
|
||||
// A code point with a value equal to or greater than U+0080 <control>.
|
||||
export function isNonAscii(code) {
|
||||
return code >= 0x0080;
|
||||
return code >= 0x0080;
|
||||
}
|
||||
|
||||
// name-start code point
|
||||
// A letter, a non-ASCII code point, or U+005F LOW LINE (_).
|
||||
export function isNameStart(code) {
|
||||
return isLetter(code) || isNonAscii(code) || code === 0x005F;
|
||||
return isLetter(code) || isNonAscii(code) || code === 0x005f;
|
||||
}
|
||||
|
||||
// name code point
|
||||
// A name-start code point, a digit, or U+002D HYPHEN-MINUS (-).
|
||||
export function isName(code) {
|
||||
return isNameStart(code) || isDigit(code) || code === 0x002D;
|
||||
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.
|
||||
export function isNonPrintable(code) {
|
||||
return (
|
||||
(code >= 0x0000 && code <= 0x0008) ||
|
||||
(code === 0x000B) ||
|
||||
(code >= 0x000E && code <= 0x001F) ||
|
||||
(code === 0x007F)
|
||||
);
|
||||
return (
|
||||
(code >= 0x0000 && code <= 0x0008) ||
|
||||
code === 0x000b ||
|
||||
(code >= 0x000e && code <= 0x001f) ||
|
||||
code === 0x007f
|
||||
);
|
||||
}
|
||||
|
||||
// newline
|
||||
@ -73,96 +73,94 @@ export function isNonPrintable(code) {
|
||||
// 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
|
||||
export function isNewline(code) {
|
||||
return code === 0x000A || code === 0x000D || code === 0x000C;
|
||||
return code === 0x000a || code === 0x000d || code === 0x000c;
|
||||
}
|
||||
|
||||
// whitespace
|
||||
// A newline, U+0009 CHARACTER TABULATION, or U+0020 SPACE.
|
||||
export function isWhiteSpace(code) {
|
||||
return isNewline(code) || code === 0x0020 || code === 0x0009;
|
||||
return isNewline(code) || code === 0x0020 || code === 0x0009;
|
||||
}
|
||||
|
||||
// § 4.3.8. Check if two code points are a valid escape
|
||||
export function isValidEscape(first, second) {
|
||||
// If the first code point is not U+005C REVERSE SOLIDUS (\), return false.
|
||||
if (first !== 0x005C) {
|
||||
return false;
|
||||
}
|
||||
// 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, if the second code point is a newline or EOF, return false.
|
||||
if (isNewline(second) || second === EOF) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, return true.
|
||||
return true;
|
||||
// Otherwise, return true.
|
||||
return true;
|
||||
}
|
||||
|
||||
// § 4.3.9. Check if three code points would start an identifier
|
||||
export function isIdentifierStart(first, second, third) {
|
||||
// Look at the first code point:
|
||||
// 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)
|
||||
);
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
// 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;
|
||||
// anything else
|
||||
// Return false.
|
||||
return false;
|
||||
}
|
||||
|
||||
// § 4.3.10. Check if three code points would start a number
|
||||
export function isNumberStart(first, second, third) {
|
||||
// Look at the first code point:
|
||||
// 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+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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
// digit
|
||||
if (isDigit(first)) {
|
||||
// Return true.
|
||||
return 1;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
// anything else
|
||||
// Return false.
|
||||
return 0;
|
||||
// digit
|
||||
if (isDigit(first)) {
|
||||
// Return true.
|
||||
return 1;
|
||||
}
|
||||
|
||||
// anything else
|
||||
// Return false.
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
@ -171,17 +169,17 @@ export function isNumberStart(first, second, third) {
|
||||
|
||||
// detect BOM (https://en.wikipedia.org/wiki/Byte_order_mark)
|
||||
export function isBOM(code) {
|
||||
// UTF-16BE
|
||||
if (code === 0xFEFF) {
|
||||
return 1;
|
||||
}
|
||||
// UTF-16BE
|
||||
if (code === 0xfeff) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// UTF-16LE
|
||||
if (code === 0xFFFE) {
|
||||
return 1;
|
||||
}
|
||||
// UTF-16LE
|
||||
if (code === 0xfffe) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Fast code category
|
||||
@ -194,14 +192,15 @@ export const NameStartCategory = 0x84;
|
||||
export 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;
|
||||
CATEGORY[i] =
|
||||
(isWhiteSpace(i) && WhiteSpaceCategory) ||
|
||||
(isDigit(i) && DigitCategory) ||
|
||||
(isNameStart(i) && NameStartCategory) ||
|
||||
(isNonPrintable(i) && NonPrintableCategory) ||
|
||||
i ||
|
||||
EofCategory;
|
||||
}
|
||||
|
||||
export function charCodeCategory(code) {
|
||||
return code < 0x80 ? CATEGORY[code] : NameStartCategory;
|
||||
return code < 0x80 ? CATEGORY[code] : NameStartCategory;
|
||||
}
|
||||
|
973
node_modules/css-tree/lib/tokenizer/index.js
generated
vendored
973
node_modules/css-tree/lib/tokenizer/index.js
generated
vendored
File diff suppressed because it is too large
Load Diff
50
node_modules/css-tree/lib/tokenizer/names.js
generated
vendored
50
node_modules/css-tree/lib/tokenizer/names.js
generated
vendored
@ -1,27 +1,27 @@
|
||||
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'
|
||||
'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',
|
||||
];
|
||||
|
48
node_modules/css-tree/lib/tokenizer/types.js
generated
vendored
48
node_modules/css-tree/lib/tokenizer/types.js
generated
vendored
@ -1,28 +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 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 LeftParenthesis = 21; // <(-token>
|
||||
export const RightParenthesis = 22; // <)-token>
|
||||
export const LeftCurlyBracket = 23; // <{-token>
|
||||
export const RightCurlyBracket = 24; // <}-token>
|
||||
export const Comment = 25;
|
||||
|
352
node_modules/css-tree/lib/tokenizer/utils.js
generated
vendored
352
node_modules/css-tree/lib/tokenizer/utils.js
generated
vendored
@ -1,115 +1,119 @@
|
||||
import {
|
||||
isDigit,
|
||||
isHexDigit,
|
||||
isUppercaseLetter,
|
||||
isName,
|
||||
isWhiteSpace,
|
||||
isValidEscape
|
||||
isDigit,
|
||||
isHexDigit,
|
||||
isUppercaseLetter,
|
||||
isName,
|
||||
isWhiteSpace,
|
||||
isValidEscape,
|
||||
} from './char-code-definitions.js';
|
||||
|
||||
function getCharCode(source, offset) {
|
||||
return offset < source.length ? source.charCodeAt(offset) : 0;
|
||||
return offset < source.length ? source.charCodeAt(offset) : 0;
|
||||
}
|
||||
|
||||
export function getNewlineLength(source, offset, code) {
|
||||
if (code === 13 /* \r */ && getCharCode(source, offset + 1) === 10 /* \n */) {
|
||||
return 2;
|
||||
}
|
||||
if (code === 13 /* \r */ && getCharCode(source, offset + 1) === 10 /* \n */) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
export function cmpChar(testStr, offset, referenceCode) {
|
||||
let code = testStr.charCodeAt(offset);
|
||||
let code = testStr.charCodeAt(offset);
|
||||
|
||||
// code.toLowerCase() for A..Z
|
||||
if (isUppercaseLetter(code)) {
|
||||
code = code | 32;
|
||||
}
|
||||
// code.toLowerCase() for A..Z
|
||||
if (isUppercaseLetter(code)) {
|
||||
code = code | 32;
|
||||
}
|
||||
|
||||
return code === referenceCode;
|
||||
return code === referenceCode;
|
||||
}
|
||||
|
||||
export function cmpStr(testStr, start, end, referenceStr) {
|
||||
if (end - start !== referenceStr.length) {
|
||||
return false;
|
||||
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 (isUppercaseLetter(testCode)) {
|
||||
testCode = testCode | 32;
|
||||
}
|
||||
|
||||
if (start < 0 || end > testStr.length) {
|
||||
return false;
|
||||
if (testCode !== referenceCode) {
|
||||
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 (isUppercaseLetter(testCode)) {
|
||||
testCode = testCode | 32;
|
||||
}
|
||||
|
||||
if (testCode !== referenceCode) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
export function findWhiteSpaceStart(source, offset) {
|
||||
for (; offset >= 0; offset--) {
|
||||
if (!isWhiteSpace(source.charCodeAt(offset))) {
|
||||
break;
|
||||
}
|
||||
for (; offset >= 0; offset--) {
|
||||
if (!isWhiteSpace(source.charCodeAt(offset))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return offset + 1;
|
||||
return offset + 1;
|
||||
}
|
||||
|
||||
export function findWhiteSpaceEnd(source, offset) {
|
||||
for (; offset < source.length; offset++) {
|
||||
if (!isWhiteSpace(source.charCodeAt(offset))) {
|
||||
break;
|
||||
}
|
||||
for (; offset < source.length; offset++) {
|
||||
if (!isWhiteSpace(source.charCodeAt(offset))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
return offset;
|
||||
}
|
||||
|
||||
export function findDecimalNumberEnd(source, offset) {
|
||||
for (; offset < source.length; offset++) {
|
||||
if (!isDigit(source.charCodeAt(offset))) {
|
||||
break;
|
||||
}
|
||||
for (; offset < source.length; offset++) {
|
||||
if (!isDigit(source.charCodeAt(offset))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
return offset;
|
||||
}
|
||||
|
||||
// § 4.3.7. Consume an escaped code point
|
||||
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;
|
||||
// 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 (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 (!isHexDigit(getCharCode(source, offset))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the next input code point is whitespace, consume it as well.
|
||||
const code = getCharCode(source, offset);
|
||||
if (isWhiteSpace(code)) {
|
||||
offset += getNewlineLength(source, offset, code);
|
||||
}
|
||||
// hex digit
|
||||
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 (
|
||||
const maxOffset = Math.min(source.length, offset + 5);
|
||||
offset < maxOffset;
|
||||
offset++
|
||||
) {
|
||||
if (!isHexDigit(getCharCode(source, offset))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
// If the next input code point is whitespace, consume it as well.
|
||||
const code = getCharCode(source, offset);
|
||||
if (isWhiteSpace(code)) {
|
||||
offset += getNewlineLength(source, offset, code);
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
// §4.3.11. Consume a name
|
||||
@ -117,138 +121,138 @@ export function consumeEscaped(source, offset) {
|
||||
// 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.
|
||||
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++) {
|
||||
const code = source.charCodeAt(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 (isName(code)) {
|
||||
// Append the code point to result.
|
||||
continue;
|
||||
}
|
||||
|
||||
// the stream starts with a valid escape
|
||||
if (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;
|
||||
// name code point
|
||||
if (isName(code)) {
|
||||
// Append the code point to result.
|
||||
continue;
|
||||
}
|
||||
|
||||
return offset;
|
||||
// the stream starts with a valid escape
|
||||
if (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
|
||||
export function consumeNumber(source, offset) {
|
||||
let code = source.charCodeAt(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);
|
||||
// 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 (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 && 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);
|
||||
}
|
||||
|
||||
// 3. While the next input code point is a digit, consume it and append it to repr.
|
||||
// ... followed by a digit
|
||||
if (isDigit(code)) {
|
||||
offset = findDecimalNumberEnd(source, offset + 1);
|
||||
code = source.charCodeAt(offset);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. If the next 2 input code points are U+002E FULL STOP (.) followed by a digit, then:
|
||||
if (code === 0x002E && 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 (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;
|
||||
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.
|
||||
export function consumeBadUrlRemnants(source, offset) {
|
||||
// Repeatedly consume the next input code point from the stream:
|
||||
for (; offset < source.length; offset++) {
|
||||
const code = source.charCodeAt(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 (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);
|
||||
}
|
||||
// U+0029 RIGHT PARENTHESIS ())
|
||||
// EOF
|
||||
if (code === 0x0029) {
|
||||
// Return.
|
||||
offset++;
|
||||
break;
|
||||
}
|
||||
|
||||
return offset;
|
||||
if (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 (\)
|
||||
export function decodeEscaped(escaped) {
|
||||
// Single char escaped that's not a hex digit
|
||||
if (escaped.length === 1 && !isHexDigit(escaped.charCodeAt(0))) {
|
||||
return escaped[0];
|
||||
}
|
||||
// Single char escaped that's not a hex digit
|
||||
if (escaped.length === 1 && !isHexDigit(escaped.charCodeAt(0))) {
|
||||
return escaped[0];
|
||||
}
|
||||
|
||||
// Interpret the hex digits as a hexadecimal number.
|
||||
let code = parseInt(escaped, 16);
|
||||
// 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;
|
||||
}
|
||||
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);
|
||||
// Otherwise, return the code point with that value.
|
||||
return String.fromCodePoint(code);
|
||||
}
|
||||
|
850
node_modules/css-tree/lib/utils/List.js
generated
vendored
850
node_modules/css-tree/lib/utils/List.js
generated
vendored
@ -17,453 +17,453 @@
|
||||
let releasedCursors = null;
|
||||
|
||||
export class List {
|
||||
static createItem(data) {
|
||||
return {
|
||||
prev: null,
|
||||
next: null,
|
||||
data
|
||||
};
|
||||
static createItem(data) {
|
||||
return {
|
||||
prev: null,
|
||||
next: null,
|
||||
data,
|
||||
};
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
this.cursor = null;
|
||||
}
|
||||
createItem(data) {
|
||||
return List.createItem(data);
|
||||
}
|
||||
|
||||
// cursor helpers
|
||||
allocateCursor(prev, next) {
|
||||
let cursor;
|
||||
|
||||
if (releasedCursors !== null) {
|
||||
cursor = releasedCursors;
|
||||
releasedCursors = releasedCursors.cursor;
|
||||
cursor.prev = prev;
|
||||
cursor.next = next;
|
||||
cursor.cursor = this.cursor;
|
||||
} else {
|
||||
cursor = {
|
||||
prev,
|
||||
next,
|
||||
cursor: this.cursor,
|
||||
};
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
this.cursor = null;
|
||||
this.cursor = cursor;
|
||||
|
||||
return cursor;
|
||||
}
|
||||
releaseCursor() {
|
||||
const { cursor } = this;
|
||||
|
||||
this.cursor = cursor.cursor;
|
||||
cursor.prev = null;
|
||||
cursor.next = null;
|
||||
cursor.cursor = releasedCursors;
|
||||
releasedCursors = cursor;
|
||||
}
|
||||
updateCursors(prevOld, prevNew, nextOld, nextNew) {
|
||||
let { cursor } = this;
|
||||
|
||||
while (cursor !== null) {
|
||||
if (cursor.prev === prevOld) {
|
||||
cursor.prev = prevNew;
|
||||
}
|
||||
|
||||
if (cursor.next === nextOld) {
|
||||
cursor.next = nextNew;
|
||||
}
|
||||
|
||||
cursor = cursor.cursor;
|
||||
}
|
||||
createItem(data) {
|
||||
return List.createItem(data);
|
||||
}
|
||||
*[Symbol.iterator]() {
|
||||
for (let cursor = this.head; cursor !== null; cursor = cursor.next) {
|
||||
yield cursor.data;
|
||||
}
|
||||
}
|
||||
|
||||
// getters
|
||||
get size() {
|
||||
let size = 0;
|
||||
|
||||
for (let cursor = this.head; cursor !== null; cursor = cursor.next) {
|
||||
size++;
|
||||
}
|
||||
|
||||
// cursor helpers
|
||||
allocateCursor(prev, next) {
|
||||
let cursor;
|
||||
return size;
|
||||
}
|
||||
get isEmpty() {
|
||||
return this.head === null;
|
||||
}
|
||||
get first() {
|
||||
return this.head && this.head.data;
|
||||
}
|
||||
get last() {
|
||||
return this.tail && this.tail.data;
|
||||
}
|
||||
|
||||
if (releasedCursors !== null) {
|
||||
cursor = releasedCursors;
|
||||
releasedCursors = releasedCursors.cursor;
|
||||
cursor.prev = prev;
|
||||
cursor.next = next;
|
||||
cursor.cursor = this.cursor;
|
||||
} else {
|
||||
cursor = {
|
||||
prev,
|
||||
next,
|
||||
cursor: this.cursor
|
||||
};
|
||||
}
|
||||
// convertors
|
||||
fromArray(array) {
|
||||
let cursor = null;
|
||||
this.head = null;
|
||||
|
||||
this.cursor = cursor;
|
||||
for (let data of array) {
|
||||
const item = List.createItem(data);
|
||||
|
||||
return cursor;
|
||||
}
|
||||
releaseCursor() {
|
||||
const { cursor } = this;
|
||||
|
||||
this.cursor = cursor.cursor;
|
||||
cursor.prev = null;
|
||||
cursor.next = null;
|
||||
cursor.cursor = releasedCursors;
|
||||
releasedCursors = cursor;
|
||||
}
|
||||
updateCursors(prevOld, prevNew, nextOld, nextNew) {
|
||||
let { cursor } = this;
|
||||
|
||||
while (cursor !== null) {
|
||||
if (cursor.prev === prevOld) {
|
||||
cursor.prev = prevNew;
|
||||
}
|
||||
|
||||
if (cursor.next === nextOld) {
|
||||
cursor.next = nextNew;
|
||||
}
|
||||
|
||||
cursor = cursor.cursor;
|
||||
}
|
||||
}
|
||||
*[Symbol.iterator]() {
|
||||
for (let cursor = this.head; cursor !== null; cursor = cursor.next) {
|
||||
yield cursor.data;
|
||||
}
|
||||
}
|
||||
|
||||
// getters
|
||||
get size() {
|
||||
let size = 0;
|
||||
|
||||
for (let cursor = this.head; cursor !== null; cursor = cursor.next) {
|
||||
size++;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
get isEmpty() {
|
||||
return this.head === null;
|
||||
}
|
||||
get first() {
|
||||
return this.head && this.head.data;
|
||||
}
|
||||
get last() {
|
||||
return this.tail && this.tail.data;
|
||||
}
|
||||
|
||||
// convertors
|
||||
fromArray(array) {
|
||||
let cursor = null;
|
||||
this.head = null;
|
||||
|
||||
for (let data of array) {
|
||||
const item = List.createItem(data);
|
||||
|
||||
if (cursor !== null) {
|
||||
cursor.next = item;
|
||||
} else {
|
||||
this.head = item;
|
||||
}
|
||||
|
||||
item.prev = cursor;
|
||||
cursor = item;
|
||||
}
|
||||
|
||||
this.tail = cursor;
|
||||
return this;
|
||||
}
|
||||
toArray() {
|
||||
return [...this];
|
||||
}
|
||||
toJSON() {
|
||||
return [...this];
|
||||
}
|
||||
|
||||
// array-like methods
|
||||
forEach(fn, thisArg = this) {
|
||||
// push cursor
|
||||
const cursor = this.allocateCursor(null, this.head);
|
||||
|
||||
while (cursor.next !== null) {
|
||||
const item = cursor.next;
|
||||
cursor.next = item.next;
|
||||
fn.call(thisArg, item.data, item, this);
|
||||
}
|
||||
|
||||
// pop cursor
|
||||
this.releaseCursor();
|
||||
}
|
||||
forEachRight(fn, thisArg = this) {
|
||||
// push cursor
|
||||
const cursor = this.allocateCursor(this.tail, null);
|
||||
|
||||
while (cursor.prev !== null) {
|
||||
const item = cursor.prev;
|
||||
cursor.prev = item.prev;
|
||||
fn.call(thisArg, item.data, item, this);
|
||||
}
|
||||
|
||||
// pop cursor
|
||||
this.releaseCursor();
|
||||
}
|
||||
reduce(fn, initialValue, thisArg = this) {
|
||||
// push cursor
|
||||
let cursor = this.allocateCursor(null, this.head);
|
||||
let acc = initialValue;
|
||||
let item;
|
||||
|
||||
while (cursor.next !== null) {
|
||||
item = cursor.next;
|
||||
cursor.next = item.next;
|
||||
|
||||
acc = fn.call(thisArg, acc, item.data, item, this);
|
||||
}
|
||||
|
||||
// pop cursor
|
||||
this.releaseCursor();
|
||||
|
||||
return acc;
|
||||
}
|
||||
reduceRight(fn, initialValue, thisArg = this) {
|
||||
// push cursor
|
||||
let cursor = this.allocateCursor(this.tail, null);
|
||||
let acc = initialValue;
|
||||
let item;
|
||||
|
||||
while (cursor.prev !== null) {
|
||||
item = cursor.prev;
|
||||
cursor.prev = item.prev;
|
||||
|
||||
acc = fn.call(thisArg, acc, item.data, item, this);
|
||||
}
|
||||
|
||||
// pop cursor
|
||||
this.releaseCursor();
|
||||
|
||||
return acc;
|
||||
}
|
||||
some(fn, thisArg = this) {
|
||||
for (let cursor = this.head; cursor !== null; cursor = cursor.next) {
|
||||
if (fn.call(thisArg, cursor.data, cursor, this)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
map(fn, thisArg = this) {
|
||||
const result = new List();
|
||||
|
||||
for (let cursor = this.head; cursor !== null; cursor = cursor.next) {
|
||||
result.appendData(fn.call(thisArg, cursor.data, cursor, this));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
filter(fn, thisArg = this) {
|
||||
const result = new List();
|
||||
|
||||
for (let cursor = this.head; cursor !== null; cursor = cursor.next) {
|
||||
if (fn.call(thisArg, cursor.data, cursor, this)) {
|
||||
result.appendData(cursor.data);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nextUntil(start, fn, thisArg = this) {
|
||||
if (start === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// push cursor
|
||||
const cursor = this.allocateCursor(null, start);
|
||||
|
||||
while (cursor.next !== null) {
|
||||
const item = cursor.next;
|
||||
cursor.next = item.next;
|
||||
if (fn.call(thisArg, item.data, item, this)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// pop cursor
|
||||
this.releaseCursor();
|
||||
}
|
||||
prevUntil(start, fn, thisArg = this) {
|
||||
if (start === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// push cursor
|
||||
const cursor = this.allocateCursor(start, null);
|
||||
|
||||
while (cursor.prev !== null) {
|
||||
const item = cursor.prev;
|
||||
cursor.prev = item.prev;
|
||||
if (fn.call(thisArg, item.data, item, this)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// pop cursor
|
||||
this.releaseCursor();
|
||||
}
|
||||
|
||||
// mutation
|
||||
clear() {
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
}
|
||||
copy() {
|
||||
const result = new List();
|
||||
|
||||
for (let data of this) {
|
||||
result.appendData(data);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
prepend(item) {
|
||||
// head
|
||||
// ^
|
||||
// item
|
||||
this.updateCursors(null, item, this.head, item);
|
||||
|
||||
// insert to the beginning of the list
|
||||
if (this.head !== null) {
|
||||
// new item <- first item
|
||||
this.head.prev = item;
|
||||
// new item -> first item
|
||||
item.next = this.head;
|
||||
} else {
|
||||
// if list has no head, then it also has no tail
|
||||
// in this case tail points to the new item
|
||||
this.tail = item;
|
||||
}
|
||||
|
||||
// head always points to new item
|
||||
if (cursor !== null) {
|
||||
cursor.next = item;
|
||||
} else {
|
||||
this.head = item;
|
||||
return this;
|
||||
}
|
||||
prependData(data) {
|
||||
return this.prepend(List.createItem(data));
|
||||
}
|
||||
append(item) {
|
||||
return this.insert(item);
|
||||
}
|
||||
appendData(data) {
|
||||
return this.insert(List.createItem(data));
|
||||
}
|
||||
insert(item, before = null) {
|
||||
if (before !== null) {
|
||||
// prev before
|
||||
// ^
|
||||
// item
|
||||
this.updateCursors(before.prev, item, before, item);
|
||||
}
|
||||
|
||||
if (before.prev === null) {
|
||||
// insert to the beginning of list
|
||||
if (this.head !== before) {
|
||||
throw new Error('before doesn\'t belong to list');
|
||||
}
|
||||
// since head points to before therefore list doesn't empty
|
||||
// no need to check tail
|
||||
this.head = item;
|
||||
before.prev = item;
|
||||
item.next = before;
|
||||
this.updateCursors(null, item);
|
||||
} else {
|
||||
// insert between two items
|
||||
before.prev.next = item;
|
||||
item.prev = before.prev;
|
||||
before.prev = item;
|
||||
item.next = before;
|
||||
}
|
||||
} else {
|
||||
// tail
|
||||
// ^
|
||||
// item
|
||||
this.updateCursors(this.tail, item, null, item);
|
||||
item.prev = cursor;
|
||||
cursor = item;
|
||||
}
|
||||
|
||||
// insert to the ending of the list
|
||||
if (this.tail !== null) {
|
||||
// last item -> new item
|
||||
this.tail.next = item;
|
||||
// last item <- new item
|
||||
item.prev = this.tail;
|
||||
} else {
|
||||
// if list has no tail, then it also has no head
|
||||
// in this case head points to new item
|
||||
this.head = item;
|
||||
}
|
||||
this.tail = cursor;
|
||||
return this;
|
||||
}
|
||||
toArray() {
|
||||
return [...this];
|
||||
}
|
||||
toJSON() {
|
||||
return [...this];
|
||||
}
|
||||
|
||||
// tail always points to new item
|
||||
this.tail = item;
|
||||
// array-like methods
|
||||
forEach(fn, thisArg = this) {
|
||||
// push cursor
|
||||
const cursor = this.allocateCursor(null, this.head);
|
||||
|
||||
while (cursor.next !== null) {
|
||||
const item = cursor.next;
|
||||
cursor.next = item.next;
|
||||
fn.call(thisArg, item.data, item, this);
|
||||
}
|
||||
|
||||
// pop cursor
|
||||
this.releaseCursor();
|
||||
}
|
||||
forEachRight(fn, thisArg = this) {
|
||||
// push cursor
|
||||
const cursor = this.allocateCursor(this.tail, null);
|
||||
|
||||
while (cursor.prev !== null) {
|
||||
const item = cursor.prev;
|
||||
cursor.prev = item.prev;
|
||||
fn.call(thisArg, item.data, item, this);
|
||||
}
|
||||
|
||||
// pop cursor
|
||||
this.releaseCursor();
|
||||
}
|
||||
reduce(fn, initialValue, thisArg = this) {
|
||||
// push cursor
|
||||
let cursor = this.allocateCursor(null, this.head);
|
||||
let acc = initialValue;
|
||||
let item;
|
||||
|
||||
while (cursor.next !== null) {
|
||||
item = cursor.next;
|
||||
cursor.next = item.next;
|
||||
|
||||
acc = fn.call(thisArg, acc, item.data, item, this);
|
||||
}
|
||||
|
||||
// pop cursor
|
||||
this.releaseCursor();
|
||||
|
||||
return acc;
|
||||
}
|
||||
reduceRight(fn, initialValue, thisArg = this) {
|
||||
// push cursor
|
||||
let cursor = this.allocateCursor(this.tail, null);
|
||||
let acc = initialValue;
|
||||
let item;
|
||||
|
||||
while (cursor.prev !== null) {
|
||||
item = cursor.prev;
|
||||
cursor.prev = item.prev;
|
||||
|
||||
acc = fn.call(thisArg, acc, item.data, item, this);
|
||||
}
|
||||
|
||||
// pop cursor
|
||||
this.releaseCursor();
|
||||
|
||||
return acc;
|
||||
}
|
||||
some(fn, thisArg = this) {
|
||||
for (let cursor = this.head; cursor !== null; cursor = cursor.next) {
|
||||
if (fn.call(thisArg, cursor.data, cursor, this)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
map(fn, thisArg = this) {
|
||||
const result = new List();
|
||||
|
||||
for (let cursor = this.head; cursor !== null; cursor = cursor.next) {
|
||||
result.appendData(fn.call(thisArg, cursor.data, cursor, this));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
filter(fn, thisArg = this) {
|
||||
const result = new List();
|
||||
|
||||
for (let cursor = this.head; cursor !== null; cursor = cursor.next) {
|
||||
if (fn.call(thisArg, cursor.data, cursor, this)) {
|
||||
result.appendData(cursor.data);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nextUntil(start, fn, thisArg = this) {
|
||||
if (start === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// push cursor
|
||||
const cursor = this.allocateCursor(null, start);
|
||||
|
||||
while (cursor.next !== null) {
|
||||
const item = cursor.next;
|
||||
cursor.next = item.next;
|
||||
if (fn.call(thisArg, item.data, item, this)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// pop cursor
|
||||
this.releaseCursor();
|
||||
}
|
||||
prevUntil(start, fn, thisArg = this) {
|
||||
if (start === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// push cursor
|
||||
const cursor = this.allocateCursor(start, null);
|
||||
|
||||
while (cursor.prev !== null) {
|
||||
const item = cursor.prev;
|
||||
cursor.prev = item.prev;
|
||||
if (fn.call(thisArg, item.data, item, this)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// pop cursor
|
||||
this.releaseCursor();
|
||||
}
|
||||
|
||||
// mutation
|
||||
clear() {
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
}
|
||||
copy() {
|
||||
const result = new List();
|
||||
|
||||
for (let data of this) {
|
||||
result.appendData(data);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
prepend(item) {
|
||||
// head
|
||||
// ^
|
||||
// item
|
||||
this.updateCursors(null, item, this.head, item);
|
||||
|
||||
// insert to the beginning of the list
|
||||
if (this.head !== null) {
|
||||
// new item <- first item
|
||||
this.head.prev = item;
|
||||
// new item -> first item
|
||||
item.next = this.head;
|
||||
} else {
|
||||
// if list has no head, then it also has no tail
|
||||
// in this case tail points to the new item
|
||||
this.tail = item;
|
||||
}
|
||||
|
||||
// head always points to new item
|
||||
this.head = item;
|
||||
return this;
|
||||
}
|
||||
prependData(data) {
|
||||
return this.prepend(List.createItem(data));
|
||||
}
|
||||
append(item) {
|
||||
return this.insert(item);
|
||||
}
|
||||
appendData(data) {
|
||||
return this.insert(List.createItem(data));
|
||||
}
|
||||
insert(item, before = null) {
|
||||
if (before !== null) {
|
||||
// prev before
|
||||
// ^
|
||||
// item
|
||||
this.updateCursors(before.prev, item, before, item);
|
||||
|
||||
if (before.prev === null) {
|
||||
// insert to the beginning of list
|
||||
if (this.head !== before) {
|
||||
throw new Error("before doesn't belong to list");
|
||||
}
|
||||
// since head points to before therefore list doesn't empty
|
||||
// no need to check tail
|
||||
this.head = item;
|
||||
before.prev = item;
|
||||
item.next = before;
|
||||
this.updateCursors(null, item);
|
||||
} else {
|
||||
// insert between two items
|
||||
before.prev.next = item;
|
||||
item.prev = before.prev;
|
||||
before.prev = item;
|
||||
item.next = before;
|
||||
}
|
||||
} else {
|
||||
// tail
|
||||
// ^
|
||||
// item
|
||||
this.updateCursors(this.tail, item, null, item);
|
||||
|
||||
return this;
|
||||
// insert to the ending of the list
|
||||
if (this.tail !== null) {
|
||||
// last item -> new item
|
||||
this.tail.next = item;
|
||||
// last item <- new item
|
||||
item.prev = this.tail;
|
||||
} else {
|
||||
// if list has no tail, then it also has no head
|
||||
// in this case head points to new item
|
||||
this.head = item;
|
||||
}
|
||||
|
||||
// tail always points to new item
|
||||
this.tail = item;
|
||||
}
|
||||
insertData(data, before) {
|
||||
return this.insert(List.createItem(data), before);
|
||||
|
||||
return this;
|
||||
}
|
||||
insertData(data, before) {
|
||||
return this.insert(List.createItem(data), before);
|
||||
}
|
||||
remove(item) {
|
||||
// item
|
||||
// ^
|
||||
// prev next
|
||||
this.updateCursors(item, item.prev, item, item.next);
|
||||
|
||||
if (item.prev !== null) {
|
||||
item.prev.next = item.next;
|
||||
} else {
|
||||
if (this.head !== item) {
|
||||
throw new Error("item doesn't belong to list");
|
||||
}
|
||||
|
||||
this.head = item.next;
|
||||
}
|
||||
remove(item) {
|
||||
// item
|
||||
// ^
|
||||
// prev next
|
||||
this.updateCursors(item, item.prev, item, item.next);
|
||||
|
||||
if (item.prev !== null) {
|
||||
item.prev.next = item.next;
|
||||
} else {
|
||||
if (this.head !== item) {
|
||||
throw new Error('item doesn\'t belong to list');
|
||||
}
|
||||
if (item.next !== null) {
|
||||
item.next.prev = item.prev;
|
||||
} else {
|
||||
if (this.tail !== item) {
|
||||
throw new Error("item doesn't belong to list");
|
||||
}
|
||||
|
||||
this.head = item.next;
|
||||
}
|
||||
|
||||
if (item.next !== null) {
|
||||
item.next.prev = item.prev;
|
||||
} else {
|
||||
if (this.tail !== item) {
|
||||
throw new Error('item doesn\'t belong to list');
|
||||
}
|
||||
|
||||
this.tail = item.prev;
|
||||
}
|
||||
|
||||
item.prev = null;
|
||||
item.next = null;
|
||||
|
||||
return item;
|
||||
this.tail = item.prev;
|
||||
}
|
||||
push(data) {
|
||||
this.insert(List.createItem(data));
|
||||
}
|
||||
pop() {
|
||||
return this.tail !== null ? this.remove(this.tail) : null;
|
||||
}
|
||||
unshift(data) {
|
||||
this.prepend(List.createItem(data));
|
||||
}
|
||||
shift() {
|
||||
return this.head !== null ? this.remove(this.head) : null;
|
||||
}
|
||||
prependList(list) {
|
||||
return this.insertList(list, this.head);
|
||||
}
|
||||
appendList(list) {
|
||||
return this.insertList(list);
|
||||
}
|
||||
insertList(list, before) {
|
||||
// ignore empty lists
|
||||
if (list.head === null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (before !== undefined && before !== null) {
|
||||
this.updateCursors(before.prev, list.tail, before, list.head);
|
||||
item.prev = null;
|
||||
item.next = null;
|
||||
|
||||
// insert in the middle of dist list
|
||||
if (before.prev !== null) {
|
||||
// before.prev <-> list.head
|
||||
before.prev.next = list.head;
|
||||
list.head.prev = before.prev;
|
||||
} else {
|
||||
this.head = list.head;
|
||||
}
|
||||
|
||||
before.prev = list.tail;
|
||||
list.tail.next = before;
|
||||
} else {
|
||||
this.updateCursors(this.tail, list.tail, null, list.head);
|
||||
|
||||
// insert to end of the list
|
||||
if (this.tail !== null) {
|
||||
// if destination list has a tail, then it also has a head,
|
||||
// but head doesn't change
|
||||
// dest tail -> source head
|
||||
this.tail.next = list.head;
|
||||
// dest tail <- source head
|
||||
list.head.prev = this.tail;
|
||||
} else {
|
||||
// if list has no a tail, then it also has no a head
|
||||
// in this case points head to new item
|
||||
this.head = list.head;
|
||||
}
|
||||
|
||||
// tail always start point to new item
|
||||
this.tail = list.tail;
|
||||
}
|
||||
|
||||
list.head = null;
|
||||
list.tail = null;
|
||||
return this;
|
||||
return item;
|
||||
}
|
||||
push(data) {
|
||||
this.insert(List.createItem(data));
|
||||
}
|
||||
pop() {
|
||||
return this.tail !== null ? this.remove(this.tail) : null;
|
||||
}
|
||||
unshift(data) {
|
||||
this.prepend(List.createItem(data));
|
||||
}
|
||||
shift() {
|
||||
return this.head !== null ? this.remove(this.head) : null;
|
||||
}
|
||||
prependList(list) {
|
||||
return this.insertList(list, this.head);
|
||||
}
|
||||
appendList(list) {
|
||||
return this.insertList(list);
|
||||
}
|
||||
insertList(list, before) {
|
||||
// ignore empty lists
|
||||
if (list.head === null) {
|
||||
return this;
|
||||
}
|
||||
replace(oldItem, newItemOrList) {
|
||||
if ('head' in newItemOrList) {
|
||||
this.insertList(newItemOrList, oldItem);
|
||||
} else {
|
||||
this.insert(newItemOrList, oldItem);
|
||||
}
|
||||
|
||||
this.remove(oldItem);
|
||||
if (before !== undefined && before !== null) {
|
||||
this.updateCursors(before.prev, list.tail, before, list.head);
|
||||
|
||||
// insert in the middle of dist list
|
||||
if (before.prev !== null) {
|
||||
// before.prev <-> list.head
|
||||
before.prev.next = list.head;
|
||||
list.head.prev = before.prev;
|
||||
} else {
|
||||
this.head = list.head;
|
||||
}
|
||||
|
||||
before.prev = list.tail;
|
||||
list.tail.next = before;
|
||||
} else {
|
||||
this.updateCursors(this.tail, list.tail, null, list.head);
|
||||
|
||||
// insert to end of the list
|
||||
if (this.tail !== null) {
|
||||
// if destination list has a tail, then it also has a head,
|
||||
// but head doesn't change
|
||||
// dest tail -> source head
|
||||
this.tail.next = list.head;
|
||||
// dest tail <- source head
|
||||
list.head.prev = this.tail;
|
||||
} else {
|
||||
// if list has no a tail, then it also has no a head
|
||||
// in this case points head to new item
|
||||
this.head = list.head;
|
||||
}
|
||||
|
||||
// tail always start point to new item
|
||||
this.tail = list.tail;
|
||||
}
|
||||
|
||||
list.head = null;
|
||||
list.tail = null;
|
||||
return this;
|
||||
}
|
||||
replace(oldItem, newItemOrList) {
|
||||
if ('head' in newItemOrList) {
|
||||
this.insertList(newItemOrList, oldItem);
|
||||
} else {
|
||||
this.insert(newItemOrList, oldItem);
|
||||
}
|
||||
|
||||
this.remove(oldItem);
|
||||
}
|
||||
}
|
||||
|
26
node_modules/css-tree/lib/utils/clone.js
generated
vendored
26
node_modules/css-tree/lib/utils/clone.js
generated
vendored
@ -1,21 +1,21 @@
|
||||
import { List } from './List.js';
|
||||
|
||||
export function clone(node) {
|
||||
const result = {};
|
||||
const result = {};
|
||||
|
||||
for (const key in node) {
|
||||
let value = node[key];
|
||||
for (const key in node) {
|
||||
let value = node[key];
|
||||
|
||||
if (value) {
|
||||
if (Array.isArray(value) || value instanceof List) {
|
||||
value = value.map(clone);
|
||||
} else if (value.constructor === Object) {
|
||||
value = clone(value);
|
||||
}
|
||||
}
|
||||
|
||||
result[key] = value;
|
||||
if (value) {
|
||||
if (Array.isArray(value) || value instanceof List) {
|
||||
value = value.map(clone);
|
||||
} else if (value.constructor === Object) {
|
||||
value = clone(value);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
result[key] = value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
27
node_modules/css-tree/lib/utils/create-custom-error.js
generated
vendored
27
node_modules/css-tree/lib/utils/create-custom-error.js
generated
vendored
@ -1,14 +1,17 @@
|
||||
export function createCustomError(name, message) {
|
||||
// use Object.create(), because some VMs prevent setting line/column otherwise
|
||||
// (iOS Safari 10 even throws an exception)
|
||||
const error = Object.create(SyntaxError.prototype);
|
||||
const errorStack = new Error();
|
||||
// use Object.create(), because some VMs prevent setting line/column otherwise
|
||||
// (iOS Safari 10 even throws an exception)
|
||||
const error = Object.create(SyntaxError.prototype);
|
||||
const errorStack = new Error();
|
||||
|
||||
return Object.assign(error, {
|
||||
name,
|
||||
message,
|
||||
get stack() {
|
||||
return (errorStack.stack || '').replace(/^(.+\n){1,3}/, `${name}: ${message}\n`);
|
||||
}
|
||||
});
|
||||
};
|
||||
return Object.assign(error, {
|
||||
name,
|
||||
message,
|
||||
get stack() {
|
||||
return (errorStack.stack || '').replace(
|
||||
/^(.+\n){1,3}/,
|
||||
`${name}: ${message}\n`
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
153
node_modules/css-tree/lib/utils/ident.js
generated
vendored
153
node_modules/css-tree/lib/utils/ident.js
generated
vendored
@ -1,101 +1,102 @@
|
||||
import {
|
||||
isName,
|
||||
isValidEscape,
|
||||
consumeEscaped,
|
||||
decodeEscaped
|
||||
isName,
|
||||
isValidEscape,
|
||||
consumeEscaped,
|
||||
decodeEscaped,
|
||||
} from '../tokenizer/index.js';
|
||||
|
||||
const REVERSE_SOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\)
|
||||
|
||||
export function decode(str) {
|
||||
const end = str.length - 1;
|
||||
let decoded = '';
|
||||
const end = str.length - 1;
|
||||
let decoded = '';
|
||||
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
let code = str.charCodeAt(i);
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
let code = str.charCodeAt(i);
|
||||
|
||||
if (code === REVERSE_SOLIDUS) {
|
||||
// special case at the ending
|
||||
if (i === end) {
|
||||
// if the next input code point is EOF, do nothing
|
||||
break;
|
||||
}
|
||||
if (code === REVERSE_SOLIDUS) {
|
||||
// special case at the ending
|
||||
if (i === end) {
|
||||
// if the next input code point is EOF, do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
code = str.charCodeAt(++i);
|
||||
code = str.charCodeAt(++i);
|
||||
|
||||
// consume escaped
|
||||
if (isValidEscape(REVERSE_SOLIDUS, code)) {
|
||||
const escapeStart = i - 1;
|
||||
const escapeEnd = consumeEscaped(str, escapeStart);
|
||||
// consume escaped
|
||||
if (isValidEscape(REVERSE_SOLIDUS, code)) {
|
||||
const escapeStart = i - 1;
|
||||
const escapeEnd = consumeEscaped(str, escapeStart);
|
||||
|
||||
i = escapeEnd - 1;
|
||||
decoded += decodeEscaped(str.substring(escapeStart + 1, escapeEnd));
|
||||
} else {
|
||||
// \r\n
|
||||
if (code === 0x000d && str.charCodeAt(i + 1) === 0x000a) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
decoded += str[i];
|
||||
i = escapeEnd - 1;
|
||||
decoded += decodeEscaped(str.substring(escapeStart + 1, escapeEnd));
|
||||
} else {
|
||||
// \r\n
|
||||
if (code === 0x000d && str.charCodeAt(i + 1) === 0x000a) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
decoded += str[i];
|
||||
}
|
||||
}
|
||||
|
||||
return decoded;
|
||||
return decoded;
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom/#serialize-an-identifier
|
||||
// § 2.1. Common Serializing Idioms
|
||||
export function encode(str) {
|
||||
let encoded = '';
|
||||
let encoded = '';
|
||||
|
||||
// If the character is the first character and is a "-" (U+002D),
|
||||
// and there is no second character, then the escaped character.
|
||||
// Note: That's means a single dash string "-" return as escaped dash,
|
||||
// so move the condition out of the main loop
|
||||
if (str.length === 1 && str.charCodeAt(0) === 0x002D) {
|
||||
return '\\-';
|
||||
// If the character is the first character and is a "-" (U+002D),
|
||||
// and there is no second character, then the escaped character.
|
||||
// Note: That's means a single dash string "-" return as escaped dash,
|
||||
// so move the condition out of the main loop
|
||||
if (str.length === 1 && str.charCodeAt(0) === 0x002d) {
|
||||
return '\\-';
|
||||
}
|
||||
|
||||
// To serialize an identifier means to create a string represented
|
||||
// by the concatenation of, for each character of the identifier:
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
const code = str.charCodeAt(i);
|
||||
|
||||
// If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD).
|
||||
if (code === 0x0000) {
|
||||
encoded += '\uFFFD';
|
||||
continue;
|
||||
}
|
||||
|
||||
// To serialize an identifier means to create a string represented
|
||||
// by the concatenation of, for each character of the identifier:
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
const code = str.charCodeAt(i);
|
||||
|
||||
// If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD).
|
||||
if (code === 0x0000) {
|
||||
encoded += '\uFFFD';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
// If the character is in the range [\1-\1f] (U+0001 to U+001F) or is U+007F ...
|
||||
// Note: Do not compare with 0x0001 since 0x0000 is precessed before
|
||||
code <= 0x001F || code === 0x007F ||
|
||||
// [or] ... is in the range [0-9] (U+0030 to U+0039),
|
||||
(code >= 0x0030 && code <= 0x0039 && (
|
||||
// If the character is the first character ...
|
||||
i === 0 ||
|
||||
// If the character is the second character ... and the first character is a "-" (U+002D)
|
||||
i === 1 && str.charCodeAt(0) === 0x002D
|
||||
))
|
||||
) {
|
||||
// ... then the character escaped as code point.
|
||||
encoded += '\\' + code.toString(16) + ' ';
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the character is not handled by one of the above rules and is greater
|
||||
// than or equal to U+0080, is "-" (U+002D) or "_" (U+005F), or is in one
|
||||
// of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to U+005A),
|
||||
// or \[a-z] (U+0061 to U+007A), then the character itself.
|
||||
if (isName(code)) {
|
||||
encoded += str.charAt(i);
|
||||
} else {
|
||||
// Otherwise, the escaped character.
|
||||
encoded += '\\' + str.charAt(i);
|
||||
}
|
||||
if (
|
||||
// If the character is in the range [\1-\1f] (U+0001 to U+001F) or is U+007F ...
|
||||
// Note: Do not compare with 0x0001 since 0x0000 is precessed before
|
||||
code <= 0x001f ||
|
||||
code === 0x007f ||
|
||||
// [or] ... is in the range [0-9] (U+0030 to U+0039),
|
||||
(code >= 0x0030 &&
|
||||
code <= 0x0039 &&
|
||||
// If the character is the first character ...
|
||||
(i === 0 ||
|
||||
// If the character is the second character ... and the first character is a "-" (U+002D)
|
||||
(i === 1 && str.charCodeAt(0) === 0x002d)))
|
||||
) {
|
||||
// ... then the character escaped as code point.
|
||||
encoded += '\\' + code.toString(16) + ' ';
|
||||
continue;
|
||||
}
|
||||
|
||||
return encoded;
|
||||
// If the character is not handled by one of the above rules and is greater
|
||||
// than or equal to U+0080, is "-" (U+002D) or "_" (U+005F), or is in one
|
||||
// of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to U+005A),
|
||||
// or \[a-z] (U+0061 to U+007A), then the character itself.
|
||||
if (isName(code)) {
|
||||
encoded += str.charAt(i);
|
||||
} else {
|
||||
// Otherwise, the escaped character.
|
||||
encoded += '\\' + str.charAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
156
node_modules/css-tree/lib/utils/names.js
generated
vendored
156
node_modules/css-tree/lib/utils/names.js
generated
vendored
@ -6,101 +6,107 @@ export const keyword = getKeywordDescriptor;
|
||||
export const property = getPropertyDescriptor;
|
||||
export const vendorPrefix = getVendorPrefix;
|
||||
export function isCustomProperty(str, offset) {
|
||||
offset = offset || 0;
|
||||
offset = offset || 0;
|
||||
|
||||
return str.length - offset >= 2 &&
|
||||
str.charCodeAt(offset) === HYPHENMINUS &&
|
||||
str.charCodeAt(offset + 1) === HYPHENMINUS;
|
||||
return (
|
||||
str.length - offset >= 2 &&
|
||||
str.charCodeAt(offset) === HYPHENMINUS &&
|
||||
str.charCodeAt(offset + 1) === HYPHENMINUS
|
||||
);
|
||||
}
|
||||
|
||||
function getVendorPrefix(str, offset) {
|
||||
offset = offset || 0;
|
||||
offset = offset || 0;
|
||||
|
||||
// verdor prefix should be at least 3 chars length
|
||||
if (str.length - offset >= 3) {
|
||||
// vendor prefix starts with hyper minus following non-hyper minus
|
||||
if (str.charCodeAt(offset) === HYPHENMINUS &&
|
||||
str.charCodeAt(offset + 1) !== HYPHENMINUS) {
|
||||
// vendor prefix should contain a hyper minus at the ending
|
||||
const secondDashIndex = str.indexOf('-', offset + 2);
|
||||
// verdor prefix should be at least 3 chars length
|
||||
if (str.length - offset >= 3) {
|
||||
// vendor prefix starts with hyper minus following non-hyper minus
|
||||
if (
|
||||
str.charCodeAt(offset) === HYPHENMINUS &&
|
||||
str.charCodeAt(offset + 1) !== HYPHENMINUS
|
||||
) {
|
||||
// vendor prefix should contain a hyper minus at the ending
|
||||
const secondDashIndex = str.indexOf('-', offset + 2);
|
||||
|
||||
if (secondDashIndex !== -1) {
|
||||
return str.substring(offset, secondDashIndex + 1);
|
||||
}
|
||||
}
|
||||
if (secondDashIndex !== -1) {
|
||||
return str.substring(offset, secondDashIndex + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
return '';
|
||||
}
|
||||
|
||||
function getKeywordDescriptor(keyword) {
|
||||
if (keywords.has(keyword)) {
|
||||
return keywords.get(keyword);
|
||||
}
|
||||
if (keywords.has(keyword)) {
|
||||
return keywords.get(keyword);
|
||||
}
|
||||
|
||||
const name = keyword.toLowerCase();
|
||||
let descriptor = keywords.get(name);
|
||||
const name = keyword.toLowerCase();
|
||||
let descriptor = keywords.get(name);
|
||||
|
||||
if (descriptor === undefined) {
|
||||
const custom = isCustomProperty(name, 0);
|
||||
const vendor = !custom ? getVendorPrefix(name, 0) : '';
|
||||
descriptor = Object.freeze({
|
||||
basename: name.substr(vendor.length),
|
||||
name,
|
||||
prefix: vendor,
|
||||
vendor,
|
||||
custom
|
||||
});
|
||||
}
|
||||
if (descriptor === undefined) {
|
||||
const custom = isCustomProperty(name, 0);
|
||||
const vendor = !custom ? getVendorPrefix(name, 0) : '';
|
||||
descriptor = Object.freeze({
|
||||
basename: name.substr(vendor.length),
|
||||
name,
|
||||
prefix: vendor,
|
||||
vendor,
|
||||
custom,
|
||||
});
|
||||
}
|
||||
|
||||
keywords.set(keyword, descriptor);
|
||||
keywords.set(keyword, descriptor);
|
||||
|
||||
return descriptor;
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
function getPropertyDescriptor(property) {
|
||||
if (properties.has(property)) {
|
||||
return properties.get(property);
|
||||
if (properties.has(property)) {
|
||||
return properties.get(property);
|
||||
}
|
||||
|
||||
let name = property;
|
||||
let hack = property[0];
|
||||
|
||||
if (hack === '/') {
|
||||
hack = property[1] === '/' ? '//' : '/';
|
||||
} else if (
|
||||
hack !== '_' &&
|
||||
hack !== '*' &&
|
||||
hack !== '$' &&
|
||||
hack !== '#' &&
|
||||
hack !== '+' &&
|
||||
hack !== '&'
|
||||
) {
|
||||
hack = '';
|
||||
}
|
||||
|
||||
const custom = isCustomProperty(name, hack.length);
|
||||
|
||||
// re-use result when possible (the same as for lower case)
|
||||
if (!custom) {
|
||||
name = name.toLowerCase();
|
||||
if (properties.has(name)) {
|
||||
const descriptor = properties.get(name);
|
||||
properties.set(property, descriptor);
|
||||
return descriptor;
|
||||
}
|
||||
}
|
||||
|
||||
let name = property;
|
||||
let hack = property[0];
|
||||
const vendor = !custom ? getVendorPrefix(name, hack.length) : '';
|
||||
const prefix = name.substr(0, hack.length + vendor.length);
|
||||
const descriptor = Object.freeze({
|
||||
basename: name.substr(prefix.length),
|
||||
name: name.substr(hack.length),
|
||||
hack,
|
||||
vendor,
|
||||
prefix,
|
||||
custom,
|
||||
});
|
||||
|
||||
if (hack === '/') {
|
||||
hack = property[1] === '/' ? '//' : '/';
|
||||
} else if (hack !== '_' &&
|
||||
hack !== '*' &&
|
||||
hack !== '$' &&
|
||||
hack !== '#' &&
|
||||
hack !== '+' &&
|
||||
hack !== '&') {
|
||||
hack = '';
|
||||
}
|
||||
properties.set(property, descriptor);
|
||||
|
||||
const custom = isCustomProperty(name, hack.length);
|
||||
|
||||
// re-use result when possible (the same as for lower case)
|
||||
if (!custom) {
|
||||
name = name.toLowerCase();
|
||||
if (properties.has(name)) {
|
||||
const descriptor = properties.get(name);
|
||||
properties.set(property, descriptor);
|
||||
return descriptor;
|
||||
}
|
||||
}
|
||||
|
||||
const vendor = !custom ? getVendorPrefix(name, hack.length) : '';
|
||||
const prefix = name.substr(0, hack.length + vendor.length);
|
||||
const descriptor = Object.freeze({
|
||||
basename: name.substr(prefix.length),
|
||||
name: name.substr(hack.length),
|
||||
hack,
|
||||
vendor,
|
||||
prefix,
|
||||
custom
|
||||
});
|
||||
|
||||
properties.set(property, descriptor);
|
||||
|
||||
return descriptor;
|
||||
return descriptor;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user