diff options
| author | Adam Mathes <adam@adammathes.com> | 2026-02-13 21:34:48 -0800 |
|---|---|---|
| committer | Adam Mathes <adam@adammathes.com> | 2026-02-13 21:34:48 -0800 |
| commit | 76cb9c2a39d477a64824a985ade40507e3bbade1 (patch) | |
| tree | 41e997aa9c6f538d3a136af61dae9424db2005a9 /vanilla/node_modules/css-tree/cjs/syntax | |
| parent | 819a39a21ac992b1393244a4c283bbb125208c69 (diff) | |
| download | neko-76cb9c2a39d477a64824a985ade40507e3bbade1.tar.gz neko-76cb9c2a39d477a64824a985ade40507e3bbade1.tar.bz2 neko-76cb9c2a39d477a64824a985ade40507e3bbade1.zip | |
feat(vanilla): add testing infrastructure and tests (NK-wjnczv)
Diffstat (limited to 'vanilla/node_modules/css-tree/cjs/syntax')
89 files changed, 4934 insertions, 0 deletions
diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/container.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/container.cjs new file mode 100644 index 0000000..7413f45 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/container.cjs @@ -0,0 +1,32 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +// https://drafts.csswg.org/css-contain-3/#container-rule +// The keywords `none`, `and`, `not`, and `or` are excluded from the <custom-ident> above. +const nonContainerNameKeywords = new Set(['none', 'and', 'not', 'or']); + +const container = { + parse: { + prelude() { + const children = this.createList(); + + if (this.tokenType === types.Ident) { + const name = this.substring(this.tokenStart, this.tokenEnd); + + if (!nonContainerNameKeywords.has(name.toLowerCase())) { + children.push(this.Identifier()); + } + } + + children.push(this.Condition('container')); + + return children; + }, + block(nested = false) { + return this.Block(nested); + } + } +}; + +module.exports = container; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/font-face.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/font-face.cjs new file mode 100644 index 0000000..fc7f64a --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/font-face.cjs @@ -0,0 +1,12 @@ +'use strict'; + +const fontFace = { + parse: { + prelude: null, + block() { + return this.Block(true); + } + } +}; + +module.exports = fontFace; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/import.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/import.cjs new file mode 100644 index 0000000..09fc11c --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/import.cjs @@ -0,0 +1,101 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +function parseWithFallback(parse, fallback) { + return this.parseWithFallback( + () => { + try { + return parse.call(this); + } finally { + this.skipSC(); + if (this.lookupNonWSType(0) !== types.RightParenthesis) { + this.error(); + } + } + }, + fallback || (() => this.Raw(null, true)) + ); +} + +const parseFunctions = { + layer() { + this.skipSC(); + + const children = this.createList(); + const node = parseWithFallback.call(this, this.Layer); + + if (node.type !== 'Raw' || node.value !== '') { + children.push(node); + } + + return children; + }, + supports() { + this.skipSC(); + + const children = this.createList(); + const node = parseWithFallback.call( + this, + this.Declaration, + () => parseWithFallback.call(this, () => this.Condition('supports')) + ); + + if (node.type !== 'Raw' || node.value !== '') { + children.push(node); + } + + return children; + } +}; + +const importAtrule = { + parse: { + prelude() { + const children = this.createList(); + + switch (this.tokenType) { + case types.String: + children.push(this.String()); + break; + + case types.Url: + case types.Function: + children.push(this.Url()); + break; + + default: + this.error('String or url() is expected'); + } + + this.skipSC(); + + if (this.tokenType === types.Ident && + this.cmpStr(this.tokenStart, this.tokenEnd, 'layer')) { + children.push(this.Identifier()); + } else if ( + this.tokenType === types.Function && + this.cmpStr(this.tokenStart, this.tokenEnd, 'layer(') + ) { + children.push(this.Function(null, parseFunctions)); + } + + this.skipSC(); + + if (this.tokenType === types.Function && + this.cmpStr(this.tokenStart, this.tokenEnd, 'supports(')) { + children.push(this.Function(null, parseFunctions)); + } + + if (this.lookupNonWSType(0) === types.Ident || + this.lookupNonWSType(0) === types.LeftParenthesis) { + children.push(this.MediaQueryList()); + } + + return children; + }, + block: null + } +}; + +module.exports = importAtrule; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/index.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/index.cjs new file mode 100644 index 0000000..143f21f --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/index.cjs @@ -0,0 +1,27 @@ +'use strict'; + +const container = require('./container.cjs'); +const fontFace = require('./font-face.cjs'); +const _import = require('./import.cjs'); +const layer = require('./layer.cjs'); +const media = require('./media.cjs'); +const nest = require('./nest.cjs'); +const page = require('./page.cjs'); +const scope = require('./scope.cjs'); +const startingStyle = require('./starting-style.cjs'); +const supports = require('./supports.cjs'); + +const atrule = { + container, + 'font-face': fontFace, + import: _import, + layer, + media, + nest, + page, + scope, + 'starting-style': startingStyle, + supports +}; + +module.exports = atrule; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/layer.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/layer.cjs new file mode 100644 index 0000000..5a9ac26 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/layer.cjs @@ -0,0 +1,16 @@ +'use strict'; + +const layer = { + parse: { + prelude() { + return this.createSingleNodeList( + this.LayerList() + ); + }, + block() { + return this.Block(false); + } + } +}; + +module.exports = layer; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/media.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/media.cjs new file mode 100644 index 0000000..5db3439 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/media.cjs @@ -0,0 +1,16 @@ +'use strict'; + +const media = { + parse: { + prelude() { + return this.createSingleNodeList( + this.MediaQueryList() + ); + }, + block(nested = false) { + return this.Block(nested); + } + } +}; + +module.exports = media; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/nest.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/nest.cjs new file mode 100644 index 0000000..5cd6672 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/nest.cjs @@ -0,0 +1,16 @@ +'use strict'; + +const nest = { + parse: { + prelude() { + return this.createSingleNodeList( + this.SelectorList() + ); + }, + block() { + return this.Block(true); + } + } +}; + +module.exports = nest; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/page.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/page.cjs new file mode 100644 index 0000000..ffef0d1 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/page.cjs @@ -0,0 +1,16 @@ +'use strict'; + +const page = { + parse: { + prelude() { + return this.createSingleNodeList( + this.SelectorList() + ); + }, + block() { + return this.Block(true); + } + } +}; + +module.exports = page; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/scope.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/scope.cjs new file mode 100644 index 0000000..e5ffba2 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/scope.cjs @@ -0,0 +1,16 @@ +'use strict'; + +const scope = { + parse: { + prelude() { + return this.createSingleNodeList( + this.Scope() + ); + }, + block(nested = false) { + return this.Block(nested); + } + } +}; + +module.exports = scope; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/starting-style.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/starting-style.cjs new file mode 100644 index 0000000..8c9814d --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/starting-style.cjs @@ -0,0 +1,12 @@ +'use strict'; + +const startingStyle = { + parse: { + prelude: null, + block(nested = false) { + return this.Block(nested); + } + } +}; + +module.exports = startingStyle; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/atrule/supports.cjs b/vanilla/node_modules/css-tree/cjs/syntax/atrule/supports.cjs new file mode 100644 index 0000000..b03d864 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/atrule/supports.cjs @@ -0,0 +1,16 @@ +'use strict'; + +const supports = { + parse: { + prelude() { + return this.createSingleNodeList( + this.Condition('supports') + ); + }, + block(nested = false) { + return this.Block(nested); + } + } +}; + +module.exports = supports; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/config/generator.cjs b/vanilla/node_modules/css-tree/cjs/syntax/config/generator.cjs new file mode 100644 index 0000000..c092458 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/config/generator.cjs @@ -0,0 +1,9 @@ +'use strict'; + +const indexGenerate = require('../node/index-generate.cjs'); + +const config = { + node: indexGenerate +}; + +module.exports = config; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/config/lexer.cjs b/vanilla/node_modules/css-tree/cjs/syntax/config/lexer.cjs new file mode 100644 index 0000000..9889262 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/config/lexer.cjs @@ -0,0 +1,14 @@ +'use strict'; + +const genericConst = require('../../lexer/generic-const.cjs'); +const data = require('../../data.cjs'); +const index = require('../node/index.cjs'); + +const lexerConfig = { + generic: true, + cssWideKeywords: genericConst.cssWideKeywords, + ...data, + node: index +}; + +module.exports = lexerConfig; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/config/mix.cjs b/vanilla/node_modules/css-tree/cjs/syntax/config/mix.cjs new file mode 100644 index 0000000..5ecf1bb --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/config/mix.cjs @@ -0,0 +1,127 @@ +'use strict'; + +function appendOrSet(a, b) { + if (typeof b === 'string' && /^\s*\|/.test(b)) { + return typeof a === 'string' + ? a + b + : b.replace(/^\s*\|\s*/, ''); + } + + return b || null; +} + +function sliceProps(obj, props) { + const result = Object.create(null); + + for (const [key, value] of Object.entries(obj)) { + if (value) { + result[key] = {}; + for (const prop of Object.keys(value)) { + if (props.includes(prop)) { + result[key][prop] = value[prop]; + } + } + } + } + + return result; +} + +function mix(dest, src) { + const result = { ...dest }; + + for (const [prop, value] of Object.entries(src)) { + switch (prop) { + case 'generic': + result[prop] = Boolean(value); + break; + + case 'cssWideKeywords': + result[prop] = dest[prop] + ? [...dest[prop], ...value] + : value || []; + break; + + case 'units': + result[prop] = { ...dest[prop] }; + for (const [name, patch] of Object.entries(value)) { + result[prop][name] = Array.isArray(patch) ? patch : []; + } + break; + + case 'atrules': + result[prop] = { ...dest[prop] }; + + for (const [name, atrule] of Object.entries(value)) { + const exists = result[prop][name] || {}; + const current = result[prop][name] = { + prelude: exists.prelude || null, + descriptors: { + ...exists.descriptors + } + }; + + if (!atrule) { + continue; + } + + current.prelude = atrule.prelude + ? appendOrSet(current.prelude, atrule.prelude) + : current.prelude || null; + + for (const [descriptorName, descriptorValue] of Object.entries(atrule.descriptors || {})) { + current.descriptors[descriptorName] = descriptorValue + ? appendOrSet(current.descriptors[descriptorName], descriptorValue) + : null; + } + + if (!Object.keys(current.descriptors).length) { + current.descriptors = null; + } + } + break; + + case 'types': + case 'properties': + result[prop] = { ...dest[prop] }; + for (const [name, syntax] of Object.entries(value)) { + result[prop][name] = appendOrSet(result[prop][name], syntax); + } + break; + + case 'scope': + case 'features': + result[prop] = { ...dest[prop] }; + for (const [name, props] of Object.entries(value)) { + result[prop][name] = { ...result[prop][name], ...props }; + } + break; + + case 'parseContext': + result[prop] = { + ...dest[prop], + ...value + }; + break; + + case 'atrule': + case 'pseudo': + result[prop] = { + ...dest[prop], + ...sliceProps(value, ['parse']) + }; + break; + + case 'node': + result[prop] = { + ...dest[prop], + ...sliceProps(value, ['name', 'structure', 'parse', 'generate', 'walkContext']) + }; + break; + } + } + + return result; +} + +module.exports = mix; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/config/parser-selector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/config/parser-selector.cjs new file mode 100644 index 0000000..03b1683 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/config/parser-selector.cjs @@ -0,0 +1,19 @@ +'use strict'; + +const index = require('../pseudo/index.cjs'); +const indexParseSelector = require('../node/index-parse-selector.cjs'); +const selector = require('../scope/selector.cjs'); + +const config = { + parseContext: { + default: 'SelectorList', + selectorList: 'SelectorList', + selector: 'Selector' + }, + scope: { Selector: selector }, + atrule: {}, + pseudo: index, + node: indexParseSelector +}; + +module.exports = config; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/config/parser.cjs b/vanilla/node_modules/css-tree/cjs/syntax/config/parser.cjs new file mode 100644 index 0000000..cd7114a --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/config/parser.cjs @@ -0,0 +1,49 @@ +'use strict'; + +const index = require('../scope/index.cjs'); +const index$1 = require('../atrule/index.cjs'); +const index$2 = require('../pseudo/index.cjs'); +const indexParse = require('../node/index-parse.cjs'); + +const config = { + parseContext: { + default: 'StyleSheet', + stylesheet: 'StyleSheet', + atrule: 'Atrule', + atrulePrelude(options) { + return this.AtrulePrelude(options.atrule ? String(options.atrule) : null); + }, + mediaQueryList: 'MediaQueryList', + mediaQuery: 'MediaQuery', + condition(options) { + return this.Condition(options.kind); + }, + rule: 'Rule', + selectorList: 'SelectorList', + selector: 'Selector', + block() { + return this.Block(true); + }, + declarationList: 'DeclarationList', + declaration: 'Declaration', + value: 'Value' + }, + features: { + supports: { + selector() { + return this.Selector(); + } + }, + container: { + style() { + return this.Declaration(); + } + } + }, + scope: index, + atrule: index$1, + pseudo: index$2, + node: indexParse +}; + +module.exports = config; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/config/walker.cjs b/vanilla/node_modules/css-tree/cjs/syntax/config/walker.cjs new file mode 100644 index 0000000..95c8f7d --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/config/walker.cjs @@ -0,0 +1,9 @@ +'use strict'; + +const index = require('../node/index.cjs'); + +const config = { + node: index +}; + +module.exports = config; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/create.cjs b/vanilla/node_modules/css-tree/cjs/syntax/create.cjs new file mode 100644 index 0000000..6ed51ea --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/create.cjs @@ -0,0 +1,58 @@ +'use strict'; + +const index = require('../tokenizer/index.cjs'); +const create = require('../parser/create.cjs'); +const create$2 = require('../generator/create.cjs'); +const create$3 = require('../convertor/create.cjs'); +const create$1 = require('../walker/create.cjs'); +const Lexer = require('../lexer/Lexer.cjs'); +const mix = require('./config/mix.cjs'); + +function createSyntax(config) { + const parse = create.createParser(config); + const walk = create$1.createWalker(config); + const generate = create$2.createGenerator(config); + const { fromPlainObject, toPlainObject } = create$3.createConvertor(walk); + + const syntax = { + lexer: null, + createLexer: config => new Lexer.Lexer(config, syntax, syntax.lexer.structure), + + tokenize: index.tokenize, + parse, + generate, + + walk, + find: walk.find, + findLast: walk.findLast, + findAll: walk.findAll, + + fromPlainObject, + toPlainObject, + + fork(extension) { + const base = mix({}, config); // copy of config + + return createSyntax( + typeof extension === 'function' + ? extension(base) // TODO: remove Object.assign as second parameter + : mix(base, extension) + ); + } + }; + + syntax.lexer = new Lexer.Lexer({ + generic: config.generic, + cssWideKeywords: config.cssWideKeywords, + units: config.units, + types: config.types, + atrules: config.atrules, + properties: config.properties, + node: config.node + }, syntax); + + return syntax; +} +const createSyntax$1 = config => createSyntax(mix({}, config)); + +module.exports = createSyntax$1; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/function/expression.cjs b/vanilla/node_modules/css-tree/cjs/syntax/function/expression.cjs new file mode 100644 index 0000000..5a8967c --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/function/expression.cjs @@ -0,0 +1,11 @@ +'use strict'; + +// legacy IE function +// expression( <any-value> ) +function expressionFn() { + return this.createSingleNodeList( + this.Raw(null, false) + ); +} + +module.exports = expressionFn; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/function/var.cjs b/vanilla/node_modules/css-tree/cjs/syntax/function/var.cjs new file mode 100644 index 0000000..f688eab --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/function/var.cjs @@ -0,0 +1,43 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +// var( <ident> , <value>? ) +function varFn() { + const children = this.createList(); + + this.skipSC(); + + // NOTE: Don't check more than a first argument is an ident, rest checks are for lexer + children.push(this.Identifier()); + + this.skipSC(); + + if (this.tokenType === types.Comma) { + children.push(this.Operator()); + + const startIndex = this.tokenIndex; + const value = this.parseCustomProperty + ? this.Value(null) + : this.Raw(this.consumeUntilExclamationMarkOrSemicolon, false); + + if (value.type === 'Value' && value.children.isEmpty) { + for (let offset = startIndex - this.tokenIndex; offset <= 0; offset++) { + if (this.lookupType(offset) === types.WhiteSpace) { + value.children.appendData({ + type: 'WhiteSpace', + loc: null, + value: ' ' + }); + break; + } + } + } + + children.push(value); + } + + return children; +} + +module.exports = varFn; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/index.cjs b/vanilla/node_modules/css-tree/cjs/syntax/index.cjs new file mode 100644 index 0000000..24de495 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/index.cjs @@ -0,0 +1,14 @@ +'use strict'; + +const create = require('./create.cjs'); +const lexer = require('./config/lexer.cjs'); +const parser = require('./config/parser.cjs'); +const walker = require('./config/walker.cjs'); + +const syntax = create({ + ...lexer, + ...parser, + ...walker +}); + +module.exports = syntax; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/AnPlusB.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/AnPlusB.cjs new file mode 100644 index 0000000..cd59927 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/AnPlusB.cjs @@ -0,0 +1,293 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); +const charCodeDefinitions = require('../../tokenizer/char-code-definitions.cjs'); + +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); + + if (code === PLUSSIGN || code === HYPHENMINUS) { + if (disallowSign) { + this.error('Number sign is not allowed'); + } + pos++; + } + + for (; pos < this.tokenEnd; pos++) { + if (!charCodeDefinitions.isDigit(this.charCodeAt(pos))) { + this.error('Integer is expected', pos); + } + } +} + +function checkTokenIsInteger(disallowSign) { + return checkInteger.call(this, 0, disallowSign); +} + +function expectCharCode(offset, code) { + 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); + } +} + +// ... <signed-integer> +// ... ['+' | '-'] <signless-integer> +function consumeB() { + let offset = 0; + let sign = 0; + let type = this.tokenType; + + while (type === types.WhiteSpace || type === types.Comment) { + type = this.lookupType(++offset); + } + + if (type !== types.Number) { + if (this.isDelim(PLUSSIGN, offset) || + this.isDelim(HYPHENMINUS, offset)) { + sign = this.isDelim(PLUSSIGN, offset) ? PLUSSIGN : HYPHENMINUS; + + do { + type = this.lookupType(++offset); + } while (type === types.WhiteSpace || type === types.Comment); + + if (type !== types.Number) { + this.skip(offset); + checkTokenIsInteger.call(this, DISALLOW_SIGN); + } + } else { + return null; + } + } + + 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(types.Number) : this.consume(types.Number); +} + +// An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb +const name = 'AnPlusB'; +const structure = { + a: [String, null], + b: [String, null] +}; + +function parse() { + /* eslint-disable brace-style*/ + const start = this.tokenStart; + let a = null; + let b = null; + + // <integer> + if (this.tokenType === types.Number) { + checkTokenIsInteger.call(this, ALLOW_SIGN); + b = this.consume(types.Number); + } + + // -n + // -n <signed-integer> + // -n ['+' | '-'] <signless-integer> + // -n- <signless-integer> + // <dashndashdigit-ident> + else if (this.tokenType === types.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(types.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 === types.Ident || (this.isDelim(PLUSSIGN) && this.lookupType(1) === types.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(types.Number); + break; + + // '+'? <ndashdigit-ident> + default: + expectCharCode.call(this, 1, HYPHENMINUS); + checkInteger.call(this, 2, DISALLOW_SIGN); + this.next(); + + b = this.substrToCursor(start + sign + 1); + } + } + + // <ndashdigit-dimension> + // <ndash-dimension> <signless-integer> + // <n-dimension> + // <n-dimension> <signed-integer> + // <n-dimension> ['+' | '-'] <signless-integer> + else if (this.tokenType === types.Dimension) { + const code = this.charCodeAt(this.tokenStart); + const sign = code === PLUSSIGN || code === HYPHENMINUS; + let i = this.tokenStart + sign; + + for (; i < this.tokenEnd; i++) { + if (!charCodeDefinitions.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(types.Number); + } + // <ndashdigit-dimension> + else { + checkInteger.call(this, i - this.tokenStart + 2, DISALLOW_SIGN); + this.next(); + b = this.substrToCursor(i + 1); + } + } + } else { + this.error(); + } + + if (a !== null && a.charCodeAt(0) === PLUSSIGN) { + a = a.substr(1); + } + + if (b !== null && b.charCodeAt(0) === PLUSSIGN) { + b = b.substr(1); + } + + return { + type: 'AnPlusB', + loc: this.getLocation(start, this.tokenStart), + a, + b + }; +} + +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.b) { + const b = node.b[0] === '-' || node.b[0] === '+' + ? node.b + : '+' + node.b; + this.tokenize(a + b); + } else { + this.tokenize(a); + } + } else { + this.tokenize(node.b); + } +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Atrule.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Atrule.cjs new file mode 100644 index 0000000..b2e0598 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Atrule.cjs @@ -0,0 +1,103 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +function consumeRaw() { + return this.Raw(this.consumeUntilLeftCurlyBracketOrSemicolon, true); +} + +function isDeclarationBlockAtrule() { + for (let offset = 1, type; type = this.lookupType(offset); offset++) { + if (type === types.RightCurlyBracket) { + return true; + } + + if (type === types.LeftCurlyBracket || + type === types.AtKeyword) { + return false; + } + } + + return false; +} + + +const name = 'Atrule'; +const walkContext = 'atrule'; +const structure = { + name: String, + prelude: ['AtrulePrelude', 'Raw', null], + block: ['Block', null] +}; + +function parse(isDeclaration = false) { + const start = this.tokenStart; + let name; + let nameLowerCase; + let prelude = null; + let block = null; + + this.eat(types.AtKeyword); + + name = this.substrToCursor(start + 1); + nameLowerCase = name.toLowerCase(); + this.skipSC(); + + // parse prelude + if (this.eof === false && + this.tokenType !== types.LeftCurlyBracket && + this.tokenType !== types.Semicolon) { + if (this.parseAtrulePrelude) { + prelude = this.parseWithFallback(this.AtrulePrelude.bind(this, name, isDeclaration), consumeRaw); + } else { + prelude = consumeRaw.call(this, this.tokenIndex); + } + + this.skipSC(); + } + + switch (this.tokenType) { + case types.Semicolon: + this.next(); + break; + + case types.LeftCurlyBracket: + if (hasOwnProperty.call(this.atrule, nameLowerCase) && + typeof this.atrule[nameLowerCase].block === 'function') { + block = this.atrule[nameLowerCase].block.call(this, isDeclaration); + } 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 + }; +} + +function generate(node) { + this.token(types.AtKeyword, '@' + node.name); + + if (node.prelude !== null) { + this.node(node.prelude); + } + + if (node.block) { + this.node(node.block); + } else { + this.token(types.Semicolon, ';'); + } +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/AtrulePrelude.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/AtrulePrelude.cjs new file mode 100644 index 0000000..0db69b6 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/AtrulePrelude.cjs @@ -0,0 +1,52 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'AtrulePrelude'; +const walkContext = 'atrulePrelude'; +const structure = { + children: [[]] +}; + +function parse(name) { + let children = null; + + if (name !== null) { + name = name.toLowerCase(); + } + + 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); + } + + this.skipSC(); + + if (this.eof !== true && + this.tokenType !== types.LeftCurlyBracket && + this.tokenType !== types.Semicolon) { + this.error('Semicolon or block is expected'); + } + + return { + type: 'AtrulePrelude', + loc: this.getLocationFromList(children), + children + }; +} + +function generate(node) { + this.children(node); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/AttributeSelector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/AttributeSelector.cjs new file mode 100644 index 0000000..757d4eb --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/AttributeSelector.cjs @@ -0,0 +1,148 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +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'); + } + + const start = this.tokenStart; + let expectIdent = false; + + if (this.isDelim(ASTERISK)) { + expectIdent = true; + this.next(); + } else if (!this.isDelim(VERTICALLINE)) { + this.eat(types.Ident); + } + + if (this.isDelim(VERTICALLINE)) { + if (this.charCodeAt(this.tokenStart + 1) !== EQUALSSIGN) { + this.next(); + this.eat(types.Ident); + } else if (expectIdent) { + 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) + }; +} + +function getOperator() { + 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'); + } + + this.next(); + + if (code !== EQUALSSIGN) { + if (!this.isDelim(EQUALSSIGN)) { + this.error('Equal sign is expected'); + } + + this.next(); + } + + return this.substrToCursor(start); +} + +// '[' <wq-name> ']' +// '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']' +const name = 'AttributeSelector'; +const structure = { + name: 'Identifier', + matcher: [String, null], + value: ['String', 'Identifier', null], + flags: [String, null] +}; + +function parse() { + const start = this.tokenStart; + let name; + let matcher = null; + let value = null; + let flags = null; + + this.eat(types.LeftSquareBracket); + this.skipSC(); + + name = getAttributeName.call(this); + this.skipSC(); + + if (this.tokenType !== types.RightSquareBracket) { + // avoid case `[name i]` + if (this.tokenType !== types.Ident) { + matcher = getOperator.call(this); + + this.skipSC(); + + value = this.tokenType === types.String + ? this.String() + : this.Identifier(); + + this.skipSC(); + } + + // attribute flags + if (this.tokenType === types.Ident) { + flags = this.consume(types.Ident); + + this.skipSC(); + } + } + + this.eat(types.RightSquareBracket); + + return { + type: 'AttributeSelector', + loc: this.getLocation(start, this.tokenStart), + name, + matcher, + value, + flags + }; +} + +function generate(node) { + this.token(types.Delim, '['); + this.node(node.name); + + if (node.matcher !== null) { + this.tokenize(node.matcher); + this.node(node.value); + } + + if (node.flags !== null) { + this.token(types.Ident, node.flags); + } + + this.token(types.Delim, ']'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Block.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Block.cjs new file mode 100644 index 0000000..0e334f6 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Block.cjs @@ -0,0 +1,96 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&) + +function consumeRaw() { + return this.Raw(null, true); +} +function consumeRule() { + return this.parseWithFallback(this.Rule, consumeRaw); +} +function consumeRawDeclaration() { + return this.Raw(this.consumeUntilSemicolonIncluded, true); +} +function consumeDeclaration() { + if (this.tokenType === types.Semicolon) { + return consumeRawDeclaration.call(this, this.tokenIndex); + } + + const node = this.parseWithFallback(this.Declaration, consumeRawDeclaration); + + if (this.tokenType === types.Semicolon) { + this.next(); + } + + return node; +} + +const name = 'Block'; +const walkContext = 'block'; +const structure = { + children: [[ + 'Atrule', + 'Rule', + 'Declaration' + ]] +}; + +function parse(isStyleBlock) { + const consumer = isStyleBlock ? consumeDeclaration : consumeRule; + const start = this.tokenStart; + let children = this.createList(); + + this.eat(types.LeftCurlyBracket); + + scan: + while (!this.eof) { + switch (this.tokenType) { + case types.RightCurlyBracket: + break scan; + + case types.WhiteSpace: + case types.Comment: + this.next(); + break; + + case types.AtKeyword: + children.push(this.parseWithFallback(this.Atrule.bind(this, isStyleBlock), consumeRaw)); + break; + + default: + if (isStyleBlock && this.isDelim(AMPERSAND)) { + children.push(consumeRule.call(this)); + } else { + children.push(consumer.call(this)); + } + } + } + + if (!this.eof) { + this.eat(types.RightCurlyBracket); + } + + return { + type: 'Block', + loc: this.getLocation(start, this.tokenStart), + children + }; +} + +function generate(node) { + this.token(types.LeftCurlyBracket, '{'); + this.children(node, prev => { + if (prev.type === 'Declaration') { + this.token(types.Semicolon, ';'); + } + }); + this.token(types.RightCurlyBracket, '}'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Brackets.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Brackets.cjs new file mode 100644 index 0000000..eb18131 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Brackets.cjs @@ -0,0 +1,38 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Brackets'; +const structure = { + children: [[]] +}; + +function parse(readSequence, recognizer) { + const start = this.tokenStart; + let children = null; + + this.eat(types.LeftSquareBracket); + + children = readSequence.call(this, recognizer); + + if (!this.eof) { + this.eat(types.RightSquareBracket); + } + + return { + type: 'Brackets', + loc: this.getLocation(start, this.tokenStart), + children + }; +} + +function generate(node) { + this.token(types.Delim, '['); + this.children(node); + this.token(types.Delim, ']'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/CDC.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/CDC.cjs new file mode 100644 index 0000000..aadf3ad --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/CDC.cjs @@ -0,0 +1,26 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'CDC'; +const structure = []; + +function parse() { + const start = this.tokenStart; + + this.eat(types.CDC); // --> + + return { + type: 'CDC', + loc: this.getLocation(start, this.tokenStart) + }; +} + +function generate() { + this.token(types.CDC, '-->'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/CDO.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/CDO.cjs new file mode 100644 index 0000000..0e98217 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/CDO.cjs @@ -0,0 +1,26 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'CDO'; +const structure = []; + +function parse() { + const start = this.tokenStart; + + this.eat(types.CDO); // <!-- + + return { + type: 'CDO', + loc: this.getLocation(start, this.tokenStart) + }; +} + +function generate() { + this.token(types.CDO, '<!--'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/ClassSelector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/ClassSelector.cjs new file mode 100644 index 0000000..ff3de5c --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/ClassSelector.cjs @@ -0,0 +1,31 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const FULLSTOP = 0x002E; // U+002E FULL STOP (.) + +// '.' ident +const name = 'ClassSelector'; +const structure = { + name: String +}; + +function parse() { + this.eatDelim(FULLSTOP); + + return { + type: 'ClassSelector', + loc: this.getLocation(this.tokenStart - 1, this.tokenEnd), + name: this.consume(types.Ident) + }; +} + +function generate(node) { + this.token(types.Delim, '.'); + this.token(types.Ident, node.name); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Combinator.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Combinator.cjs new file mode 100644 index 0000000..1a24278 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Combinator.cjs @@ -0,0 +1,61 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +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 name = 'Combinator'; +const structure = { + name: String +}; + +// + | > | ~ | /deep/ +function parse() { + const start = this.tokenStart; + let name; + + switch (this.tokenType) { + case types.WhiteSpace: + name = ' '; + break; + + case types.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; + + default: + this.error('Combinator is expected'); + } + + name = this.substrToCursor(start); + break; + } + + return { + type: 'Combinator', + loc: this.getLocation(start, this.tokenStart), + name + }; +} + +function generate(node) { + this.tokenize(node.name); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Comment.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Comment.cjs new file mode 100644 index 0000000..083e950 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Comment.cjs @@ -0,0 +1,40 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const ASTERISK = 0x002A; // U+002A ASTERISK (*) +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) + + +const name = 'Comment'; +const structure = { + value: String +}; + +function parse() { + const start = this.tokenStart; + let end = this.tokenEnd; + + this.eat(types.Comment); + + 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) + }; +} + +function generate(node) { + this.token(types.Comment, '/*' + node.value + '*/'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Condition.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Condition.cjs new file mode 100644 index 0000000..af6a2ec --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Condition.cjs @@ -0,0 +1,120 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const likelyFeatureToken = new Set([types.Colon, types.RightParenthesis, types.EOF]); + +const name = 'Condition'; +const structure = { + kind: String, + children: [[ + 'Identifier', + 'Feature', + 'FeatureFunction', + 'FeatureRange', + 'SupportsDeclaration' + ]] +}; + +function featureOrRange(kind) { + if (this.lookupTypeNonSC(1) === types.Ident && + likelyFeatureToken.has(this.lookupTypeNonSC(2))) { + return this.Feature(kind); + } + + return this.FeatureRange(kind); +} + +const parentheses = { + media: featureOrRange, + container: featureOrRange, + supports() { + return this.SupportsDeclaration(); + } +}; + +function parse(kind = 'media') { + const children = this.createList(); + + scan: while (!this.eof) { + switch (this.tokenType) { + case types.Comment: + case types.WhiteSpace: + this.next(); + continue; + + case types.Ident: + children.push(this.Identifier()); + break; + + case types.LeftParenthesis: { + let term = this.parseWithFallback( + () => parentheses[kind].call(this, kind), + () => null + ); + + if (!term) { + term = this.parseWithFallback( + () => { + this.eat(types.LeftParenthesis); + const res = this.Condition(kind); + this.eat(types.RightParenthesis); + return res; + }, + () => { + return this.GeneralEnclosed(kind); + } + ); + } + + children.push(term); + break; + } + + case types.Function: { + let term = this.parseWithFallback( + () => this.FeatureFunction(kind), + () => null + ); + + if (!term) { + term = this.GeneralEnclosed(kind); + } + + children.push(term); + break; + } + + default: + break scan; + } + } + + if (children.isEmpty) { + this.error('Condition is expected'); + } + + return { + type: 'Condition', + loc: this.getLocationFromList(children), + kind, + children + }; +} + +function generate(node) { + node.children.forEach(child => { + if (child.type === 'Condition') { + this.token(types.LeftParenthesis, '('); + this.node(child); + this.token(types.RightParenthesis, ')'); + } else { + this.node(child); + } + }); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Declaration.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Declaration.cjs new file mode 100644 index 0000000..7cf13b1 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Declaration.cjs @@ -0,0 +1,166 @@ +'use strict'; + +const names = require('../../utils/names.cjs'); +const types = require('../../tokenizer/types.cjs'); + +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 (/) + +function consumeValueRaw() { + return this.Raw(this.consumeUntilExclamationMarkOrSemicolon, true); +} + +function consumeCustomPropertyRaw() { + return this.Raw(this.consumeUntilExclamationMarkOrSemicolon, false); +} + +function consumeValue() { + const startValueToken = this.tokenIndex; + const value = this.Value(); + + if (value.type !== 'Raw' && + this.eof === false && + this.tokenType !== types.Semicolon && + this.isDelim(EXCLAMATIONMARK) === false && + this.isBalanceEdge(startValueToken) === false) { + this.error(); + } + + return value; +} + +const name = 'Declaration'; +const walkContext = 'declaration'; +const structure = { + important: [Boolean, String], + property: String, + value: ['Value', 'Raw'] +}; + +function parse() { + const start = this.tokenStart; + const startToken = this.tokenIndex; + const property = readProperty.call(this); + const customProperty = names.isCustomProperty(property); + const parseValue = customProperty ? this.parseCustomProperty : this.parseValue; + const consumeRaw = customProperty ? consumeCustomPropertyRaw : consumeValueRaw; + let important = false; + let value; + + this.skipSC(); + this.eat(types.Colon); + + const valueStart = this.tokenIndex; + + if (!customProperty) { + this.skipSC(); + } + + if (parseValue) { + value = this.parseWithFallback(consumeValue, consumeRaw); + } else { + value = consumeRaw.call(this, this.tokenIndex); + } + + if (customProperty && value.type === 'Value' && value.children.isEmpty) { + for (let offset = valueStart - this.tokenIndex; offset <= 0; offset++) { + if (this.lookupType(offset) === types.WhiteSpace) { + value.children.appendData({ + type: 'WhiteSpace', + loc: null, + value: ' ' + }); + break; + } + } + } + + if (this.isDelim(EXCLAMATIONMARK)) { + important = getImportant.call(this); + this.skipSC(); + } + + // Do not include semicolon to range per spec + // https://drafts.csswg.org/css-syntax/#declaration-diagram + + if (this.eof === false && + this.tokenType !== types.Semicolon && + this.isBalanceEdge(startToken) === false) { + this.error(); + } + + return { + type: 'Declaration', + loc: this.getLocation(start, this.tokenStart), + important, + property, + value + }; +} + +function generate(node) { + this.token(types.Ident, node.property); + this.token(types.Colon, ':'); + this.node(node.value); + + if (node.important) { + this.token(types.Delim, '!'); + this.token(types.Ident, node.important === true ? 'important' : node.important); + } +} + +function readProperty() { + const start = this.tokenStart; + + // hacks + if (this.tokenType === types.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; + } + } + + if (this.tokenType === types.Hash) { + this.eat(types.Hash); + } else { + this.eat(types.Ident); + } + + return this.substrToCursor(start); +} + +// ! ws* important +function getImportant() { + this.eat(types.Delim); + this.skipSC(); + + const important = this.consume(types.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; +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/DeclarationList.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/DeclarationList.cjs new file mode 100644 index 0000000..d3cffad --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/DeclarationList.cjs @@ -0,0 +1,62 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&) + +function consumeRaw() { + return this.Raw(this.consumeUntilSemicolonIncluded, true); +} + +const name = 'DeclarationList'; +const structure = { + children: [[ + 'Declaration', + 'Atrule', + 'Rule' + ]] +}; + +function parse() { + const children = this.createList(); + + while (!this.eof) { + switch (this.tokenType) { + case types.WhiteSpace: + case types.Comment: + case types.Semicolon: + this.next(); + break; + + case types.AtKeyword: + children.push(this.parseWithFallback(this.Atrule.bind(this, true), consumeRaw)); + break; + + default: + if (this.isDelim(AMPERSAND)) { + children.push(this.parseWithFallback(this.Rule, consumeRaw)); + } else { + children.push(this.parseWithFallback(this.Declaration, consumeRaw)); + } + } + } + + return { + type: 'DeclarationList', + loc: this.getLocationFromList(children), + children + }; +} + +function generate(node) { + this.children(node, prev => { + if (prev.type === 'Declaration') { + this.token(types.Semicolon, ';'); + } + }); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Dimension.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Dimension.cjs new file mode 100644 index 0000000..227184c --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Dimension.cjs @@ -0,0 +1,30 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Dimension'; +const structure = { + value: String, + unit: String +}; + +function parse() { + const start = this.tokenStart; + const value = this.consumeNumber(types.Dimension); + + return { + type: 'Dimension', + loc: this.getLocation(start, this.tokenStart), + value, + unit: this.substring(start + value.length, this.tokenStart) + }; +} + +function generate(node) { + this.token(types.Dimension, node.value + node.unit); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Feature.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Feature.cjs new file mode 100644 index 0000000..a55019b --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Feature.cjs @@ -0,0 +1,101 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) + +const name = 'Feature'; +const structure = { + kind: String, + name: String, + value: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function', null] +}; + +function parse(kind) { + const start = this.tokenStart; + let name; + let value = null; + + this.eat(types.LeftParenthesis); + this.skipSC(); + + name = this.consume(types.Ident); + this.skipSC(); + + if (this.tokenType !== types.RightParenthesis) { + this.eat(types.Colon); + this.skipSC(); + + switch (this.tokenType) { + case types.Number: + if (this.lookupNonWSType(1) === types.Delim) { + value = this.Ratio(); + } else { + value = this.Number(); + } + + break; + + case types.Dimension: + value = this.Dimension(); + break; + + case types.Ident: + value = this.Identifier(); + break; + + case types.Function: + value = this.parseWithFallback( + () => { + const res = this.Function(this.readSequence, this.scope.Value); + + this.skipSC(); + + if (this.isDelim(SOLIDUS)) { + this.error(); + } + + return res; + }, + () => { + return this.Ratio(); + } + ); + break; + + default: + this.error('Number, dimension, ratio or identifier is expected'); + } + + this.skipSC(); + } + + if (!this.eof) { + this.eat(types.RightParenthesis); + } + + return { + type: 'Feature', + loc: this.getLocation(start, this.tokenStart), + kind, + name, + value + }; +} + +function generate(node) { + this.token(types.LeftParenthesis, '('); + this.token(types.Ident, node.name); + + if (node.value !== null) { + this.token(types.Colon, ':'); + this.node(node.value); + } + + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/FeatureFunction.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/FeatureFunction.cjs new file mode 100644 index 0000000..1986947 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/FeatureFunction.cjs @@ -0,0 +1,67 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'FeatureFunction'; +const structure = { + kind: String, + feature: String, + value: ['Declaration', 'Selector'] +}; + +function getFeatureParser(kind, name) { + const featuresOfKind = this.features[kind] || {}; + const parser = featuresOfKind[name]; + + if (typeof parser !== 'function') { + this.error(`Unknown feature ${name}()`); + } + + return parser; +} + +function parse(kind = 'unknown') { + const start = this.tokenStart; + const functionName = this.consumeFunctionName(); + const valueParser = getFeatureParser.call(this, kind, functionName.toLowerCase()); + + this.skipSC(); + + const value = this.parseWithFallback( + () => { + const startValueToken = this.tokenIndex; + const value = valueParser.call(this); + + if (this.eof === false && + this.isBalanceEdge(startValueToken) === false) { + this.error(); + } + + return value; + }, + () => this.Raw(null, false) + ); + + if (!this.eof) { + this.eat(types.RightParenthesis); + } + + return { + type: 'FeatureFunction', + loc: this.getLocation(start, this.tokenStart), + kind, + feature: functionName, + value + }; +} + +function generate(node) { + this.token(types.Function, node.feature + '('); + this.node(node.value); + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/FeatureRange.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/FeatureRange.cjs new file mode 100644 index 0000000..f6730c2 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/FeatureRange.cjs @@ -0,0 +1,133 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) +const LESSTHANSIGN = 0x003C; // U+003C LESS-THAN SIGN (<) +const EQUALSSIGN = 0x003D; // U+003D EQUALS SIGN (=) +const GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>) + +const name = 'FeatureRange'; +const structure = { + kind: String, + left: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function'], + leftComparison: String, + middle: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function'], + rightComparison: [String, null], + right: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function', null] +}; + +function readTerm() { + this.skipSC(); + + switch (this.tokenType) { + case types.Number: + if (this.isDelim(SOLIDUS, this.lookupOffsetNonSC(1))) { + return this.Ratio(); + } else { + return this.Number(); + } + + case types.Dimension: + return this.Dimension(); + + case types.Ident: + return this.Identifier(); + + case types.Function: + return this.parseWithFallback( + () => { + const res = this.Function(this.readSequence, this.scope.Value); + + this.skipSC(); + + if (this.isDelim(SOLIDUS)) { + this.error(); + } + + return res; + }, + () => { + return this.Ratio(); + } + ); + + default: + this.error('Number, dimension, ratio or identifier is expected'); + } +} + +function readComparison(expectColon) { + this.skipSC(); + + if (this.isDelim(LESSTHANSIGN) || + this.isDelim(GREATERTHANSIGN)) { + const value = this.source[this.tokenStart]; + + this.next(); + + if (this.isDelim(EQUALSSIGN)) { + this.next(); + return value + '='; + } + + return value; + } + + if (this.isDelim(EQUALSSIGN)) { + return '='; + } + + this.error(`Expected ${expectColon ? '":", ' : ''}"<", ">", "=" or ")"`); +} + +function parse(kind = 'unknown') { + const start = this.tokenStart; + + this.skipSC(); + this.eat(types.LeftParenthesis); + + const left = readTerm.call(this); + const leftComparison = readComparison.call(this, left.type === 'Identifier'); + const middle = readTerm.call(this); + let rightComparison = null; + let right = null; + + if (this.lookupNonWSType(0) !== types.RightParenthesis) { + rightComparison = readComparison.call(this); + right = readTerm.call(this); + } + + this.skipSC(); + this.eat(types.RightParenthesis); + + return { + type: 'FeatureRange', + loc: this.getLocation(start, this.tokenStart), + kind, + left, + leftComparison, + middle, + rightComparison, + right + }; +} + +function generate(node) { + this.token(types.LeftParenthesis, '('); + this.node(node.left); + this.tokenize(node.leftComparison); + this.node(node.middle); + + if (node.right) { + this.tokenize(node.rightComparison); + this.node(node.right); + } + + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Function.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Function.cjs new file mode 100644 index 0000000..b5e3b57 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Function.cjs @@ -0,0 +1,45 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Function'; +const walkContext = 'function'; +const structure = { + name: String, + children: [[]] +}; + +// <function-token> <sequence> ) +function parse(readSequence, recognizer) { + 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); + + if (!this.eof) { + this.eat(types.RightParenthesis); + } + + return { + type: 'Function', + loc: this.getLocation(start, this.tokenStart), + name, + children + }; +} + +function generate(node) { + this.token(types.Function, node.name + '('); + this.children(node); + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/GeneralEnclosed.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/GeneralEnclosed.cjs new file mode 100644 index 0000000..2a442d0 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/GeneralEnclosed.cjs @@ -0,0 +1,68 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'GeneralEnclosed'; +const structure = { + kind: String, + function: [String, null], + children: [[]] +}; + +// <function-token> <any-value> ) +// ( <any-value> ) +function parse(kind) { + const start = this.tokenStart; + let functionName = null; + + if (this.tokenType === types.Function) { + functionName = this.consumeFunctionName(); + } else { + this.eat(types.LeftParenthesis); + } + + const children = this.parseWithFallback( + () => { + const startValueToken = this.tokenIndex; + const children = this.readSequence(this.scope.Value); + + if (this.eof === false && + this.isBalanceEdge(startValueToken) === false) { + this.error(); + } + + return children; + }, + () => this.createSingleNodeList( + this.Raw(null, false) + ) + ); + + if (!this.eof) { + this.eat(types.RightParenthesis); + } + + return { + type: 'GeneralEnclosed', + loc: this.getLocation(start, this.tokenStart), + kind, + function: functionName, + children + }; +} + +function generate(node) { + if (node.function) { + this.token(types.Function, node.function + '('); + } else { + this.token(types.LeftParenthesis, '('); + } + + this.children(node); + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Hash.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Hash.cjs new file mode 100644 index 0000000..8b5f375 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Hash.cjs @@ -0,0 +1,30 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +// '#' ident +const xxx = 'XXX'; +const name = 'Hash'; +const structure = { + value: String +}; +function parse() { + const start = this.tokenStart; + + this.eat(types.Hash); + + return { + type: 'Hash', + loc: this.getLocation(start, this.tokenStart), + value: this.substrToCursor(start + 1) + }; +} +function generate(node) { + this.token(types.Hash, '#' + node.value); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.xxx = xxx; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/IdSelector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/IdSelector.cjs new file mode 100644 index 0000000..264525d --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/IdSelector.cjs @@ -0,0 +1,33 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'IdSelector'; +const structure = { + name: String +}; + +function parse() { + const start = this.tokenStart; + + // TODO: check value is an ident + this.eat(types.Hash); + + return { + type: 'IdSelector', + loc: this.getLocation(start, this.tokenStart), + name: this.substrToCursor(start + 1) + }; +} + +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(types.Delim, '#' + node.name); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Identifier.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Identifier.cjs new file mode 100644 index 0000000..8928cf8 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Identifier.cjs @@ -0,0 +1,25 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Identifier'; +const structure = { + name: String +}; + +function parse() { + return { + type: 'Identifier', + loc: this.getLocation(this.tokenStart, this.tokenEnd), + name: this.consume(types.Ident) + }; +} + +function generate(node) { + this.token(types.Ident, node.name); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Layer.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Layer.cjs new file mode 100644 index 0000000..a748046 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Layer.cjs @@ -0,0 +1,35 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const FULLSTOP = 0x002E; // U+002E FULL STOP (.) + +const name = 'Layer'; +const structure = { + name: String +}; + +function parse() { + let tokenStart = this.tokenStart; + let name = this.consume(types.Ident); + + while (this.isDelim(FULLSTOP)) { + this.eat(types.Delim); + name += '.' + this.consume(types.Ident); + } + + return { + type: 'Layer', + loc: this.getLocation(tokenStart, this.tokenStart), + name + }; +} + +function generate(node) { + this.tokenize(node.name); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/LayerList.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/LayerList.cjs new file mode 100644 index 0000000..0ce29f5 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/LayerList.cjs @@ -0,0 +1,43 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'LayerList'; +const structure = { + children: [[ + 'Layer' + ]] +}; + +function parse() { + const children = this.createList(); + + this.skipSC(); + + while (!this.eof) { + children.push(this.Layer()); + + if (this.lookupTypeNonSC(0) !== types.Comma) { + break; + } + + this.skipSC(); + this.next(); + this.skipSC(); + } + + return { + type: 'LayerList', + loc: this.getLocationFromList(children), + children + }; +} + +function generate(node) { + this.children(node, () => this.token(types.Comma, ',')); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/LayerName.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/LayerName.cjs new file mode 100644 index 0000000..97ac9b7 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/LayerName.cjs @@ -0,0 +1,34 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const FULLSTOP = 0x002E; // U+002E FULL STOP (.) + +const name = 'LayerName'; +const structure = { + name: String +}; + +function parse() { + let name = this.consume(types.Ident); + + while (this.isDelim(FULLSTOP)) { + this.eat(types.Delim); + name += '.' + this.consume(types.Ident); + } + + return { + type: 'LayerName', + loc: this.getLocation(this.tokenStart, this.tokenEnd), + name + }; +} + +function generate(node) { + this.tokenize(node.name); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/LayerNameList.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/LayerNameList.cjs new file mode 100644 index 0000000..e35140d --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/LayerNameList.cjs @@ -0,0 +1,42 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'LayerNameList'; +const structure = { + children: [[ + 'MediaQuery' + ]] +}; + +function parse() { + const children = this.createList(); + + this.skipSC(); + + while (!this.eof) { + children.push(this.LayerName()); + + if (this.tokenType !== types.Comma) { + break; + } + + this.next(); + this.skipSC(); + } + + return { + type: 'LayerNameList', + loc: this.getLocationFromList(children), + children + }; +} + +function generate(node) { + this.children(node, () => this.token(types.Comma, ',')); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/MediaCondition.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaCondition.cjs new file mode 100644 index 0000000..c98fdc8 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaCondition.cjs @@ -0,0 +1,70 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const MediaFeatureToken = new Set([types.Colon, types.RightParenthesis, types.EOF]); + +const name = 'MediaCondition'; +const structure = { + children: [[ + 'Identifier', + 'MediaFeature', + 'MediaFeatureRange' + ]] +}; + +function parse() { + const children = this.createList(); + + scan: while (!this.eof) { + switch (this.tokenType) { + case types.Comment: + case types.WhiteSpace: + this.next(); + continue; + + case types.Ident: + children.push(this.Identifier()); + break; + + case types.LeftParenthesis: + if (this.lookupTypeNonSC(1) === types.Ident && MediaFeatureToken.has(this.lookupTypeNonSC(2))) { + children.push(this.MediaFeature()); + } else if (this.lookupTypeNonSC(1) === types.LeftParenthesis || this.lookupTypeNonSC(2) === types.LeftParenthesis) { + this.next(); + children.push(this.MediaCondition()); + this.eat(types.RightParenthesis); + } else { + children.push(this.MediaFeatureRange()); + } + + break; + + default: + break scan; + } + } + + return { + type: 'MediaCondition', + loc: this.getLocationFromList(children), + children + }; +} + +function generate(node) { + node.children.forEach(child => { + if (child.type === 'MediaCondition') { + this.token(types.LeftParenthesis, '('); + this.node(child); + this.token(types.RightParenthesis, ')'); + } else { + this.node(child); + } + }); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/MediaFeature.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaFeature.cjs new file mode 100644 index 0000000..90e8d5a --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaFeature.cjs @@ -0,0 +1,76 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'MediaFeature'; +const structure = { + name: String, + value: ['Identifier', 'Number', 'Dimension', 'Ratio', null] +}; + +function parse() { + const start = this.tokenStart; + let name; + let value = null; + + this.eat(types.LeftParenthesis); + this.skipSC(); + + name = this.consume(types.Ident); + this.skipSC(); + + if (this.tokenType !== types.RightParenthesis) { + this.eat(types.Colon); + this.skipSC(); + + switch (this.tokenType) { + case types.Number: + if (this.lookupNonWSType(1) === types.Delim) { + value = this.Ratio(); + } else { + value = this.Number(); + } + + break; + + case types.Dimension: + value = this.Dimension(); + break; + + case types.Ident: + value = this.Identifier(); + break; + + default: + this.error('Number, dimension, ratio or identifier is expected'); + } + + this.skipSC(); + } + + this.eat(types.RightParenthesis); + + return { + type: 'MediaFeature', + loc: this.getLocation(start, this.tokenStart), + name, + value + }; +} + +function generate(node) { + this.token(types.LeftParenthesis, '('); + this.token(types.Ident, node.name); + + if (node.value !== null) { + this.token(types.Colon, ':'); + this.node(node.value); + } + + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/MediaFeatureRange.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaFeatureRange.cjs new file mode 100644 index 0000000..8be899f --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaFeatureRange.cjs @@ -0,0 +1,11 @@ +'use strict'; + +const featureRange = require('./common/feature-range.cjs'); + +const name = 'MediaFeatureRange'; +const parse = featureRange.createParse(name); + +exports.generate = featureRange.generate; +exports.structure = featureRange.structure; +exports.name = name; +exports.parse = parse; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/MediaQuery.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaQuery.cjs new file mode 100644 index 0000000..776efdd --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaQuery.cjs @@ -0,0 +1,100 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'MediaQuery'; +const structure = { + modifier: [String, null], + mediaType: [String, null], + condition: ['Condition', null] +}; + +function parse() { + const start = this.tokenStart; + let modifier = null; + let mediaType = null; + let condition = null; + + this.skipSC(); + + if (this.tokenType === types.Ident && this.lookupTypeNonSC(1) !== types.LeftParenthesis) { + // [ not | only ]? <media-type> + const ident = this.consume(types.Ident); + const identLowerCase = ident.toLowerCase(); + + if (identLowerCase === 'not' || identLowerCase === 'only') { + this.skipSC(); + modifier = identLowerCase; + mediaType = this.consume(types.Ident); + } else { + mediaType = ident; + } + + switch (this.lookupTypeNonSC(0)) { + case types.Ident: { + // and <media-condition-without-or> + this.skipSC(); + this.eatIdent('and'); + condition = this.Condition('media'); + break; + } + + case types.LeftCurlyBracket: + case types.Semicolon: + case types.Comma: + case types.EOF: + break; + + default: + this.error('Identifier or parenthesis is expected'); + } + } else { + switch (this.tokenType) { + case types.Ident: + case types.LeftParenthesis: + case types.Function: { + // <media-condition> + condition = this.Condition('media'); + break; + } + + case types.LeftCurlyBracket: + case types.Semicolon: + case types.EOF: + break; + + default: + this.error('Identifier or parenthesis is expected'); + } + } + + return { + type: 'MediaQuery', + loc: this.getLocation(start, this.tokenStart), + modifier, + mediaType, + condition + }; +} + +function generate(node) { + if (node.mediaType) { + if (node.modifier) { + this.token(types.Ident, node.modifier); + } + + this.token(types.Ident, node.mediaType); + + if (node.condition) { + this.token(types.Ident, 'and'); + this.node(node.condition); + } + } else if (node.condition) { + this.node(node.condition); + } +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/MediaQueryList.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaQueryList.cjs new file mode 100644 index 0000000..3877947 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/MediaQueryList.cjs @@ -0,0 +1,41 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'MediaQueryList'; +const structure = { + children: [[ + 'MediaQuery' + ]] +}; + +function parse() { + const children = this.createList(); + + this.skipSC(); + + while (!this.eof) { + children.push(this.MediaQuery()); + + if (this.tokenType !== types.Comma) { + break; + } + + this.next(); + } + + return { + type: 'MediaQueryList', + loc: this.getLocationFromList(children), + children + }; +} + +function generate(node) { + this.children(node, () => this.token(types.Comma, ',')); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/NestingSelector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/NestingSelector.cjs new file mode 100644 index 0000000..9850a9c --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/NestingSelector.cjs @@ -0,0 +1,29 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&) + +const name = 'NestingSelector'; +const structure = { +}; + +function parse() { + const start = this.tokenStart; + + this.eatDelim(AMPERSAND); + + return { + type: 'NestingSelector', + loc: this.getLocation(start, this.tokenStart) + }; +} + +function generate() { + this.token(types.Delim, '&'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Nth.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Nth.cjs new file mode 100644 index 0000000..709312f --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Nth.cjs @@ -0,0 +1,54 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Nth'; +const structure = { + nth: ['AnPlusB', 'Identifier'], + selector: ['SelectorList', null] +}; + +function parse() { + this.skipSC(); + + 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(); + } + + 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 + }; +} + +function generate(node) { + this.node(node.nth); + if (node.selector !== null) { + this.token(types.Ident, 'of'); + this.node(node.selector); + } +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Number.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Number.cjs new file mode 100644 index 0000000..8abd9ae --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Number.cjs @@ -0,0 +1,25 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Number'; +const structure = { + value: String +}; + +function parse() { + return { + type: 'Number', + loc: this.getLocation(this.tokenStart, this.tokenEnd), + value: this.consume(types.Number) + }; +} + +function generate(node) { + this.token(types.Number, node.value); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Operator.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Operator.cjs new file mode 100644 index 0000000..c5a513b --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Operator.cjs @@ -0,0 +1,28 @@ +'use strict'; + +// '/' | '*' | ',' | ':' | '+' | '-' +const name = 'Operator'; +const structure = { + value: String +}; + +function parse() { + const start = this.tokenStart; + + this.next(); + + return { + type: 'Operator', + loc: this.getLocation(start, this.tokenStart), + value: this.substrToCursor(start) + }; +} + +function generate(node) { + this.tokenize(node.value); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Parentheses.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Parentheses.cjs new file mode 100644 index 0000000..7c14bc6 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Parentheses.cjs @@ -0,0 +1,38 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Parentheses'; +const structure = { + children: [[]] +}; + +function parse(readSequence, recognizer) { + const start = this.tokenStart; + let children = null; + + this.eat(types.LeftParenthesis); + + children = readSequence.call(this, recognizer); + + if (!this.eof) { + this.eat(types.RightParenthesis); + } + + return { + type: 'Parentheses', + loc: this.getLocation(start, this.tokenStart), + children + }; +} + +function generate(node) { + this.token(types.LeftParenthesis, '('); + this.children(node); + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Percentage.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Percentage.cjs new file mode 100644 index 0000000..38cc1d5 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Percentage.cjs @@ -0,0 +1,25 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Percentage'; +const structure = { + value: String +}; + +function parse() { + return { + type: 'Percentage', + loc: this.getLocation(this.tokenStart, this.tokenEnd), + value: this.consumeNumber(types.Percentage) + }; +} + +function generate(node) { + this.token(types.Percentage, node.value + '%'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/PseudoClassSelector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/PseudoClassSelector.cjs new file mode 100644 index 0000000..f5fa0da --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/PseudoClassSelector.cjs @@ -0,0 +1,67 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'PseudoClassSelector'; +const walkContext = 'function'; +const structure = { + name: String, + children: [['Raw'], null] +}; + +// : [ <ident> | <function-token> <any-value>? ) ] +function parse() { + const start = this.tokenStart; + let children = null; + let name; + let nameLowerCase; + + this.eat(types.Colon); + + if (this.tokenType === types.Function) { + name = this.consumeFunctionName(); + nameLowerCase = name.toLowerCase(); + + if (this.lookupNonWSType(0) == types.RightParenthesis) { + children = this.createList(); + } else if (hasOwnProperty.call(this.pseudo, nameLowerCase)) { + this.skipSC(); + children = this.pseudo[nameLowerCase].call(this); + this.skipSC(); + } else { + children = this.createList(); + children.push( + this.Raw(null, false) + ); + } + + this.eat(types.RightParenthesis); + } else { + name = this.consume(types.Ident); + } + + return { + type: 'PseudoClassSelector', + loc: this.getLocation(start, this.tokenStart), + name, + children + }; +} + +function generate(node) { + this.token(types.Colon, ':'); + + if (node.children === null) { + this.token(types.Ident, node.name); + } else { + this.token(types.Function, node.name + '('); + this.children(node); + this.token(types.RightParenthesis, ')'); + } +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/PseudoElementSelector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/PseudoElementSelector.cjs new file mode 100644 index 0000000..f998968 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/PseudoElementSelector.cjs @@ -0,0 +1,69 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'PseudoElementSelector'; +const walkContext = 'function'; +const structure = { + name: String, + children: [['Raw'], null] +}; + +// :: [ <ident> | <function-token> <any-value>? ) ] +function parse() { + const start = this.tokenStart; + let children = null; + let name; + let nameLowerCase; + + this.eat(types.Colon); + this.eat(types.Colon); + + if (this.tokenType === types.Function) { + name = this.consumeFunctionName(); + nameLowerCase = name.toLowerCase(); + + if (this.lookupNonWSType(0) == types.RightParenthesis) { + children = this.createList(); + } else if (hasOwnProperty.call(this.pseudo, nameLowerCase)) { + this.skipSC(); + children = this.pseudo[nameLowerCase].call(this); + this.skipSC(); + } else { + children = this.createList(); + children.push( + this.Raw(null, false) + ); + } + + this.eat(types.RightParenthesis); + } else { + name = this.consume(types.Ident); + } + + return { + type: 'PseudoElementSelector', + loc: this.getLocation(start, this.tokenStart), + name, + children + }; +} + +function generate(node) { + this.token(types.Colon, ':'); + this.token(types.Colon, ':'); + + if (node.children === null) { + this.token(types.Ident, node.name); + } else { + this.token(types.Function, node.name + '('); + this.children(node); + this.token(types.RightParenthesis, ')'); + } +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Ratio.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Ratio.cjs new file mode 100644 index 0000000..69b71ea --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Ratio.cjs @@ -0,0 +1,71 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const SOLIDUS = 0x002F; // U+002F SOLIDUS (/) + +// Media Queries Level 3 defines terms of <ratio> as a positive (not zero or negative) +// integers (see https://drafts.csswg.org/mediaqueries-3/#values) +// However, Media Queries Level 4 removes any definition of values +// (see https://drafts.csswg.org/mediaqueries-4/#values) and refers to +// CSS Values and Units for detail. In CSS Values and Units Level 4 a <ratio> +// definition was added (see https://drafts.csswg.org/css-values-4/#ratios) which +// defines ratio as "<number [0,∞]> [ / <number [0,∞]> ]?" and based on it +// any constrains on terms were removed. Parser also doesn't test numbers +// in any way to make possible for linting and fixing them by the tools using CSSTree. +// An additional syntax examination may be applied by a lexer. +function consumeTerm() { + this.skipSC(); + + switch (this.tokenType) { + case types.Number: + return this.Number(); + + case types.Function: + return this.Function(this.readSequence, this.scope.Value); + + default: + this.error('Number of function is expected'); + } +} + +const name = 'Ratio'; +const structure = { + left: ['Number', 'Function'], + right: ['Number', 'Function', null] +}; + +// <number [0,∞]> [ / <number [0,∞]> ]? +function parse() { + const start = this.tokenStart; + const left = consumeTerm.call(this); + let right = null; + + this.skipSC(); + if (this.isDelim(SOLIDUS)) { + this.eatDelim(SOLIDUS); + right = consumeTerm.call(this); + } + + return { + type: 'Ratio', + loc: this.getLocation(start, this.tokenStart), + left, + right + }; +} + +function generate(node) { + this.node(node.left); + this.token(types.Delim, '/'); + if (node.right) { + this.node(node.right); + } else { + this.node(types.Number, 1); + } +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Raw.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Raw.cjs new file mode 100644 index 0000000..5b92f74 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Raw.cjs @@ -0,0 +1,48 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +function getOffsetExcludeWS() { + if (this.tokenIndex > 0) { + if (this.lookupType(-1) === types.WhiteSpace) { + return this.tokenIndex > 1 + ? this.getTokenStart(this.tokenIndex - 1) + : this.firstCharOffset; + } + } + + return this.tokenStart; +} + +const name = 'Raw'; +const structure = { + value: String +}; + +function parse(consumeUntil, excludeWhiteSpace) { + const startOffset = this.getTokenStart(this.tokenIndex); + let endOffset; + + this.skipUntilBalanced(this.tokenIndex, consumeUntil || this.consumeUntilBalanceEnd); + + 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) + }; +} + +function generate(node) { + this.tokenize(node.value); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Rule.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Rule.cjs new file mode 100644 index 0000000..e03dbe0 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Rule.cjs @@ -0,0 +1,58 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +function consumeRaw() { + return this.Raw(this.consumeUntilLeftCurlyBracket, true); +} + +function consumePrelude() { + const prelude = this.SelectorList(); + + if (prelude.type !== 'Raw' && + this.eof === false && + this.tokenType !== types.LeftCurlyBracket) { + this.error(); + } + + return prelude; +} + +const name = 'Rule'; +const walkContext = 'rule'; +const structure = { + prelude: ['SelectorList', 'Raw'], + block: ['Block'] +}; + +function parse() { + 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); + } + + block = this.Block(true); + + return { + type: 'Rule', + loc: this.getLocation(startOffset, this.tokenStart), + prelude, + block + }; +} +function generate(node) { + this.node(node.prelude); + this.node(node.block); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Scope.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Scope.cjs new file mode 100644 index 0000000..1320b04 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Scope.cjs @@ -0,0 +1,69 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'Scope'; +const structure = { + root: ['SelectorList', 'Raw', null], + limit: ['SelectorList', 'Raw', null] +}; + +function parse() { + let root = null; + let limit = null; + + this.skipSC(); + + const startOffset = this.tokenStart; + if (this.tokenType === types.LeftParenthesis) { + this.next(); + this.skipSC(); + root = this.parseWithFallback( + this.SelectorList, + () => this.Raw(false, true) + ); + this.skipSC(); + this.eat(types.RightParenthesis); + } + + if (this.lookupNonWSType(0) === types.Ident) { + this.skipSC(); + this.eatIdent('to'); + this.skipSC(); + this.eat(types.LeftParenthesis); + this.skipSC(); + limit = this.parseWithFallback( + this.SelectorList, + () => this.Raw(false, true) + ); + this.skipSC(); + this.eat(types.RightParenthesis); + } + + return { + type: 'Scope', + loc: this.getLocation(startOffset, this.tokenStart), + root, + limit + }; +} + +function generate(node) { + if (node.root) { + this.token(types.LeftParenthesis, '('); + this.node(node.root); + this.token(types.RightParenthesis, ')'); + } + + if (node.limit) { + this.token(types.Ident, 'to'); + this.token(types.LeftParenthesis, '('); + this.node(node.limit); + this.token(types.RightParenthesis, ')'); + } +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Selector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Selector.cjs new file mode 100644 index 0000000..f836975 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Selector.cjs @@ -0,0 +1,38 @@ +'use strict'; + +const name = 'Selector'; +const structure = { + children: [[ + 'TypeSelector', + 'IdSelector', + 'ClassSelector', + 'AttributeSelector', + 'PseudoClassSelector', + 'PseudoElementSelector', + 'Combinator' + ]] +}; + +function parse() { + const children = this.readSequence(this.scope.Selector); + + // nothing were consumed + if (this.getFirstListNode(children) === null) { + this.error('Selector is expected'); + } + + return { + type: 'Selector', + loc: this.getLocationFromList(children), + children + }; +} + +function generate(node) { + this.children(node); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/SelectorList.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/SelectorList.cjs new file mode 100644 index 0000000..7ecf09b --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/SelectorList.cjs @@ -0,0 +1,43 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'SelectorList'; +const walkContext = 'selector'; +const structure = { + children: [[ + 'Selector', + 'Raw' + ]] +}; + +function parse() { + const children = this.createList(); + + while (!this.eof) { + children.push(this.Selector()); + + if (this.tokenType === types.Comma) { + this.next(); + continue; + } + + break; + } + + return { + type: 'SelectorList', + loc: this.getLocationFromList(children), + children + }; +} + +function generate(node) { + this.children(node, () => this.token(types.Comma, ',')); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/String.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/String.cjs new file mode 100644 index 0000000..8a7801e --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/String.cjs @@ -0,0 +1,26 @@ +'use strict'; + +const string = require('../../utils/string.cjs'); +const types = require('../../tokenizer/types.cjs'); + +const name = 'String'; +const structure = { + value: String +}; + +function parse() { + return { + type: 'String', + loc: this.getLocation(this.tokenStart, this.tokenEnd), + value: string.decode(this.consume(types.String)) + }; +} + +function generate(node) { + this.token(types.String, string.encode(node.value)); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/StyleSheet.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/StyleSheet.cjs new file mode 100644 index 0000000..6e48f05 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/StyleSheet.cjs @@ -0,0 +1,83 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!) + +function consumeRaw() { + return this.Raw(null, false); +} + +const name = 'StyleSheet'; +const walkContext = 'stylesheet'; +const structure = { + children: [[ + 'Comment', + 'CDO', + 'CDC', + 'Atrule', + 'Rule', + 'Raw' + ]] +}; + +function parse() { + const start = this.tokenStart; + const children = this.createList(); + let child; + + while (!this.eof) { + switch (this.tokenType) { + case types.WhiteSpace: + this.next(); + continue; + + case types.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 types.CDO: // <!-- + child = this.CDO(); + break; + + case types.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 types.AtKeyword: + child = this.parseWithFallback(this.Atrule, consumeRaw); + break; + + // Anything else starts a qualified rule ... + default: + child = this.parseWithFallback(this.Rule, consumeRaw); + } + + children.push(child); + } + + return { + type: 'StyleSheet', + loc: this.getLocation(start, this.tokenStart), + children + }; +} + +function generate(node) { + this.children(node); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; +exports.walkContext = walkContext; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/SupportsDeclaration.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/SupportsDeclaration.cjs new file mode 100644 index 0000000..fcac089 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/SupportsDeclaration.cjs @@ -0,0 +1,38 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'SupportsDeclaration'; +const structure = { + declaration: 'Declaration' +}; + +function parse() { + const start = this.tokenStart; + + this.eat(types.LeftParenthesis); + this.skipSC(); + + const declaration = this.Declaration(); + + if (!this.eof) { + this.eat(types.RightParenthesis); + } + + return { + type: 'SupportsDeclaration', + loc: this.getLocation(start, this.tokenStart), + declaration + }; +} + +function generate(node) { + this.token(types.LeftParenthesis, '('); + this.node(node.declaration); + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/SupportsFeature.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/SupportsFeature.cjs new file mode 100644 index 0000000..e569a5c --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/SupportsFeature.cjs @@ -0,0 +1,69 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const name = 'SupportsDeclaration'; +const structure = { + feature: String, + value: 'Declaration' +}; + +function parse() { + const start = this.tokenStart; + let featureName = 'declaration'; + let valueParser = this.Declaration; + + if (this.tokenType === types.Function) { + featureName = this.consumeFunctionName(); + valueParser = this.supportsFeature[featureName.toLowerCase()]; + if (!valueParser) { + this.error(`Unknown supports feature ${featureName.toLowerCase()}()`); + } + } else { + this.eat(types.LeftParenthesis); + } + + this.skipSC(); + + const value = this.parseWithFallback( + () => { + const startValueToken = this.tokenIndex; + const value = valueParser.call(this); + + if (this.eof === false && + this.isBalanceEdge(startValueToken) === false) { + this.error(); + } + + return value; + }, + (startToken) => this.Raw(startToken, null, false) + ); + + if (!this.eof) { + this.eat(types.RightParenthesis); + } + + return { + type: 'SupportsDeclaration', + loc: this.getLocation(start, this.tokenStart), + feature: featureName, + value + }; +} + +function generate(node) { + if (node.feature !== 'declaration') { + this.token(types.Function, node.feature + '('); + } else { + this.token(types.LeftParenthesis, '('); + } + + this.node(node.value); + this.token(types.RightParenthesis, ')'); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/TypeSelector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/TypeSelector.cjs new file mode 100644 index 0000000..1d15270 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/TypeSelector.cjs @@ -0,0 +1,59 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const ASTERISK = 0x002A; // U+002A ASTERISK (*) +const VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|) + +function eatIdentifierOrAsterisk() { + if (this.tokenType !== types.Ident && + this.isDelim(ASTERISK) === false) { + this.error('Identifier or asterisk is expected'); + } + + this.next(); +} + +const name = 'TypeSelector'; +const structure = { + name: String +}; + +// ident +// ident|ident +// ident|* +// * +// *|ident +// *|* +// |ident +// |* +function parse() { + 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); + } + } + + return { + type: 'TypeSelector', + loc: this.getLocation(start, this.tokenStart), + name: this.substrToCursor(start) + }; +} + +function generate(node) { + this.tokenize(node.name); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/UnicodeRange.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/UnicodeRange.cjs new file mode 100644 index 0000000..5585e8f --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/UnicodeRange.cjs @@ -0,0 +1,158 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); +const charCodeDefinitions = require('../../tokenizer/char-code-definitions.cjs'); + +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; + + 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 (!charCodeDefinitions.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; + + 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'); + } +} + +// https://drafts.csswg.org/css-syntax/#urange +// Informally, the <urange> production has three forms: +// U+0001 +// Defines a range consisting of a single code point, in this case the code point "1". +// U+0001-00ff +// Defines a range of codepoints between the first and the second value, in this case +// the range between "1" and "ff" (255 in decimal) inclusive. +// U+00?? +// Defines a range of codepoints where the "?" characters range over all hex digits, +// in this case defining the same as the value U+0000-00ff. +// In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit). +// +// <urange> = +// u '+' <ident-token> '?'* | +// u <dimension-token> '?'* | +// u <number-token> '?'* | +// u <number-token> <dimension-token> | +// u <number-token> <number-token> | +// u '+' '?'+ +function scanUnicodeRange() { + let hexLength = 0; + + switch (this.tokenType) { + case types.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.tokenType === types.Dimension || + this.tokenType === types.Number) { + startsWith.call(this, HYPHENMINUS); + eatHexSequence.call(this, 1, false); + break; + } + + break; + + case types.Dimension: + // u <dimension-token> '?'* + hexLength = eatHexSequence.call(this, 1, true); + + if (hexLength > 0) { + eatQuestionMarkSequence.call(this, 6 - hexLength); + } + + break; + + default: + // u '+' <ident-token> '?'* + // u '+' '?'+ + this.eatDelim(PLUSSIGN); + + if (this.tokenType === types.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; + } + + this.error('Hex digit or question mark is expected'); + } +} + +const name = 'UnicodeRange'; +const structure = { + value: String +}; + +function parse() { + const start = this.tokenStart; + + // U or u + this.eatIdent('u'); + scanUnicodeRange.call(this); + + return { + type: 'UnicodeRange', + loc: this.getLocation(start, this.tokenStart), + value: this.substrToCursor(start) + }; +} + +function generate(node) { + this.tokenize(node.value); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Url.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Url.cjs new file mode 100644 index 0000000..6a39457 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Url.cjs @@ -0,0 +1,54 @@ +'use strict'; + +const url = require('../../utils/url.cjs'); +const string = require('../../utils/string.cjs'); +const types = require('../../tokenizer/types.cjs'); + +const name = 'Url'; +const structure = { + value: String +}; + +// <url-token> | <function-token> <string> ) +function parse() { + const start = this.tokenStart; + let value; + + switch (this.tokenType) { + case types.Url: + value = url.decode(this.consume(types.Url)); + break; + + case types.Function: + if (!this.cmpStr(this.tokenStart, this.tokenEnd, 'url(')) { + this.error('Function name must be `url`'); + } + + this.eat(types.Function); + this.skipSC(); + value = string.decode(this.consume(types.String)); + this.skipSC(); + if (!this.eof) { + this.eat(types.RightParenthesis); + } + break; + + default: + this.error('Url or Function is expected'); + } + + return { + type: 'Url', + loc: this.getLocation(start, this.tokenStart), + value + }; +} + +function generate(node) { + this.token(types.Url, url.encode(node.value)); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/Value.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/Value.cjs new file mode 100644 index 0000000..bdb322e --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/Value.cjs @@ -0,0 +1,26 @@ +'use strict'; + +const name = 'Value'; +const structure = { + children: [[]] +}; + +function parse() { + const start = this.tokenStart; + const children = this.readSequence(this.scope.Value); + + return { + type: 'Value', + loc: this.getLocation(start, this.tokenStart), + children + }; +} + +function generate(node) { + this.children(node); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/WhiteSpace.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/WhiteSpace.cjs new file mode 100644 index 0000000..50c1982 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/WhiteSpace.cjs @@ -0,0 +1,34 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const SPACE = Object.freeze({ + type: 'WhiteSpace', + loc: null, + value: ' ' +}); + +const name = 'WhiteSpace'; +const structure = { + value: String +}; + +function parse() { + this.eat(types.WhiteSpace); + return SPACE; + + // return { + // type: 'WhiteSpace', + // loc: this.getLocation(this.tokenStart, this.tokenEnd), + // value: this.consume(WHITESPACE) + // }; +} + +function generate(node) { + this.token(types.WhiteSpace, node.value); +} + +exports.generate = generate; +exports.name = name; +exports.parse = parse; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/common/feature-range.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/common/feature-range.cjs new file mode 100644 index 0000000..7589b56 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/common/feature-range.cjs @@ -0,0 +1,112 @@ +'use strict'; + +const types = require('../../../tokenizer/types.cjs'); + +const LESSTHANSIGN = 60; // < +const EQUALSIGN = 61; // = +const GREATERTHANSIGN = 62; // > + +const structure = { + left: ['Identifier', 'Number', 'Dimension', 'Ratio'], + leftComparison: String, + middle: ['Identifier', 'Number', 'Dimension', 'Ratio'], + rightComparison: [String, null], + right: ['Identifier', 'Number', 'Dimension', 'Ratio', null] +}; + +function readTerm() { + this.skipSC(); + + switch (this.tokenType) { + case types.Number: + if (this.lookupNonWSType(1) === types.Delim) { + return this.Ratio(); + } else { + return this.Number(); + } + + case types.Dimension: + return this.Dimension(); + + case types.Ident: + return this.Identifier(); + + default: + this.error('Number, dimension, ratio or identifier is expected'); + } +} + +function readComparison(expectColon) { + this.skipSC(); + + if (this.isDelim(LESSTHANSIGN) || + this.isDelim(GREATERTHANSIGN)) { + const value = this.source[this.tokenStart]; + + this.next(); + + if (this.isDelim(EQUALSIGN)) { + this.next(); + return value + '='; + } + + return value; + } + + if (this.isDelim(EQUALSIGN)) { + return '='; + } + + this.error(`Expected ${expectColon ? '":", ' : ''}"<", ">", "=" or ")"`); +} + +function createParse(type) { + return function parse() { + const start = this.tokenStart; + + this.skipSC(); + this.eat(types.LeftParenthesis); + + const left = readTerm.call(this); + const leftComparison = readComparison.call(this, left.type === 'Identifier'); + const middle = readTerm.call(this); + let rightComparison = null; + let right = null; + + if (this.lookupNonWSType(0) !== types.RightParenthesis) { + rightComparison = readComparison.call(this); + right = readTerm.call(this); + } + + this.skipSC(); + this.eat(types.RightParenthesis); + + return { + type, + loc: this.getLocation(start, this.tokenStart), + left, + leftComparison, + middle, + rightComparison, + right + }; + }; +} + +function generate(node) { + this.token(types.LeftParenthesis, '('); + this.node(node.left); + this.tokenize(node.leftComparison); + this.node(node.middle); + + if (node.right) { + this.tokenize(node.rightComparison); + this.node(node.right); + } + + this.token(types.RightParenthesis, ')'); +} + +exports.createParse = createParse; +exports.generate = generate; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/common/feature.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/common/feature.cjs new file mode 100644 index 0000000..fa5de4e --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/common/feature.cjs @@ -0,0 +1,76 @@ +'use strict'; + +const types = require('../../../tokenizer/types.cjs'); + +const structure = { + name: String, + value: ['Identifier', 'Number', 'Dimension', 'Ratio', null] +}; + +function createParse(type) { + return function parse() { + const start = this.tokenStart; + let name; + let value = null; + + this.eat(types.LeftParenthesis); + this.skipSC(); + + name = this.consume(types.Ident); + this.skipSC(); + + if (this.tokenType !== types.RightParenthesis) { + this.eat(types.Colon); + this.skipSC(); + + switch (this.tokenType) { + case types.Number: + if (this.lookupNonWSType(1) === types.Delim) { + value = this.Ratio(); + } else { + value = this.Number(); + } + + break; + + case types.Dimension: + value = this.Dimension(); + break; + + case types.Ident: + value = this.Identifier(); + break; + + default: + this.error('Number, dimension, ratio or identifier is expected'); + } + + this.skipSC(); + } + + this.eat(types.RightParenthesis); + + return { + type, + loc: this.getLocation(start, this.tokenStart), + name, + value + }; + }; +} + +function generate(node) { + this.token(types.LeftParenthesis, '('); + this.token(types.Ident, node.name); + + if (node.value !== null) { + this.token(types.Colon, ':'); + this.node(node.value); + } + + this.token(types.RightParenthesis, ')'); +} + +exports.createParse = createParse; +exports.generate = generate; +exports.structure = structure; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/index-generate.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/index-generate.cjs new file mode 100644 index 0000000..41a4ef1 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/index-generate.cjs @@ -0,0 +1,103 @@ +'use strict'; + +const AnPlusB = require('./AnPlusB.cjs'); +const Atrule = require('./Atrule.cjs'); +const AtrulePrelude = require('./AtrulePrelude.cjs'); +const AttributeSelector = require('./AttributeSelector.cjs'); +const Block = require('./Block.cjs'); +const Brackets = require('./Brackets.cjs'); +const CDC = require('./CDC.cjs'); +const CDO = require('./CDO.cjs'); +const ClassSelector = require('./ClassSelector.cjs'); +const Combinator = require('./Combinator.cjs'); +const Comment = require('./Comment.cjs'); +const Condition = require('./Condition.cjs'); +const Declaration = require('./Declaration.cjs'); +const DeclarationList = require('./DeclarationList.cjs'); +const Dimension = require('./Dimension.cjs'); +const Feature = require('./Feature.cjs'); +const FeatureFunction = require('./FeatureFunction.cjs'); +const FeatureRange = require('./FeatureRange.cjs'); +const Function = require('./Function.cjs'); +const GeneralEnclosed = require('./GeneralEnclosed.cjs'); +const Hash = require('./Hash.cjs'); +const Identifier = require('./Identifier.cjs'); +const IdSelector = require('./IdSelector.cjs'); +const Layer = require('./Layer.cjs'); +const LayerList = require('./LayerList.cjs'); +const MediaQuery = require('./MediaQuery.cjs'); +const MediaQueryList = require('./MediaQueryList.cjs'); +const NestingSelector = require('./NestingSelector.cjs'); +const Nth = require('./Nth.cjs'); +const Number = require('./Number.cjs'); +const Operator = require('./Operator.cjs'); +const Parentheses = require('./Parentheses.cjs'); +const Percentage = require('./Percentage.cjs'); +const PseudoClassSelector = require('./PseudoClassSelector.cjs'); +const PseudoElementSelector = require('./PseudoElementSelector.cjs'); +const Ratio = require('./Ratio.cjs'); +const Raw = require('./Raw.cjs'); +const Rule = require('./Rule.cjs'); +const Scope = require('./Scope.cjs'); +const Selector = require('./Selector.cjs'); +const SelectorList = require('./SelectorList.cjs'); +const String = require('./String.cjs'); +const StyleSheet = require('./StyleSheet.cjs'); +const SupportsDeclaration = require('./SupportsDeclaration.cjs'); +const TypeSelector = require('./TypeSelector.cjs'); +const UnicodeRange = require('./UnicodeRange.cjs'); +const Url = require('./Url.cjs'); +const Value = require('./Value.cjs'); +const WhiteSpace = require('./WhiteSpace.cjs'); + + + +exports.AnPlusB = AnPlusB.generate; +exports.Atrule = Atrule.generate; +exports.AtrulePrelude = AtrulePrelude.generate; +exports.AttributeSelector = AttributeSelector.generate; +exports.Block = Block.generate; +exports.Brackets = Brackets.generate; +exports.CDC = CDC.generate; +exports.CDO = CDO.generate; +exports.ClassSelector = ClassSelector.generate; +exports.Combinator = Combinator.generate; +exports.Comment = Comment.generate; +exports.Condition = Condition.generate; +exports.Declaration = Declaration.generate; +exports.DeclarationList = DeclarationList.generate; +exports.Dimension = Dimension.generate; +exports.Feature = Feature.generate; +exports.FeatureFunction = FeatureFunction.generate; +exports.FeatureRange = FeatureRange.generate; +exports.Function = Function.generate; +exports.GeneralEnclosed = GeneralEnclosed.generate; +exports.Hash = Hash.generate; +exports.Identifier = Identifier.generate; +exports.IdSelector = IdSelector.generate; +exports.Layer = Layer.generate; +exports.LayerList = LayerList.generate; +exports.MediaQuery = MediaQuery.generate; +exports.MediaQueryList = MediaQueryList.generate; +exports.NestingSelector = NestingSelector.generate; +exports.Nth = Nth.generate; +exports.Number = Number.generate; +exports.Operator = Operator.generate; +exports.Parentheses = Parentheses.generate; +exports.Percentage = Percentage.generate; +exports.PseudoClassSelector = PseudoClassSelector.generate; +exports.PseudoElementSelector = PseudoElementSelector.generate; +exports.Ratio = Ratio.generate; +exports.Raw = Raw.generate; +exports.Rule = Rule.generate; +exports.Scope = Scope.generate; +exports.Selector = Selector.generate; +exports.SelectorList = SelectorList.generate; +exports.String = String.generate; +exports.StyleSheet = StyleSheet.generate; +exports.SupportsDeclaration = SupportsDeclaration.generate; +exports.TypeSelector = TypeSelector.generate; +exports.UnicodeRange = UnicodeRange.generate; +exports.Url = Url.generate; +exports.Value = Value.generate; +exports.WhiteSpace = WhiteSpace.generate; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/index-parse-selector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/index-parse-selector.cjs new file mode 100644 index 0000000..79caf05 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/index-parse-selector.cjs @@ -0,0 +1,39 @@ +'use strict'; + +const AnPlusB = require('./AnPlusB.cjs'); +const AttributeSelector = require('./AttributeSelector.cjs'); +const ClassSelector = require('./ClassSelector.cjs'); +const Combinator = require('./Combinator.cjs'); +const Identifier = require('./Identifier.cjs'); +const IdSelector = require('./IdSelector.cjs'); +const NestingSelector = require('./NestingSelector.cjs'); +const Nth = require('./Nth.cjs'); +const Operator = require('./Operator.cjs'); +const Percentage = require('./Percentage.cjs'); +const PseudoClassSelector = require('./PseudoClassSelector.cjs'); +const PseudoElementSelector = require('./PseudoElementSelector.cjs'); +const Raw = require('./Raw.cjs'); +const Selector = require('./Selector.cjs'); +const SelectorList = require('./SelectorList.cjs'); +const String = require('./String.cjs'); +const TypeSelector = require('./TypeSelector.cjs'); + + + +exports.AnPlusB = AnPlusB.parse; +exports.AttributeSelector = AttributeSelector.parse; +exports.ClassSelector = ClassSelector.parse; +exports.Combinator = Combinator.parse; +exports.Identifier = Identifier.parse; +exports.IdSelector = IdSelector.parse; +exports.NestingSelector = NestingSelector.parse; +exports.Nth = Nth.parse; +exports.Operator = Operator.parse; +exports.Percentage = Percentage.parse; +exports.PseudoClassSelector = PseudoClassSelector.parse; +exports.PseudoElementSelector = PseudoElementSelector.parse; +exports.Raw = Raw.parse; +exports.Selector = Selector.parse; +exports.SelectorList = SelectorList.parse; +exports.String = String.parse; +exports.TypeSelector = TypeSelector.parse; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/index-parse.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/index-parse.cjs new file mode 100644 index 0000000..050bd17 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/index-parse.cjs @@ -0,0 +1,103 @@ +'use strict'; + +const AnPlusB = require('./AnPlusB.cjs'); +const Atrule = require('./Atrule.cjs'); +const AtrulePrelude = require('./AtrulePrelude.cjs'); +const AttributeSelector = require('./AttributeSelector.cjs'); +const Block = require('./Block.cjs'); +const Brackets = require('./Brackets.cjs'); +const CDC = require('./CDC.cjs'); +const CDO = require('./CDO.cjs'); +const ClassSelector = require('./ClassSelector.cjs'); +const Combinator = require('./Combinator.cjs'); +const Comment = require('./Comment.cjs'); +const Condition = require('./Condition.cjs'); +const Declaration = require('./Declaration.cjs'); +const DeclarationList = require('./DeclarationList.cjs'); +const Dimension = require('./Dimension.cjs'); +const Feature = require('./Feature.cjs'); +const FeatureFunction = require('./FeatureFunction.cjs'); +const FeatureRange = require('./FeatureRange.cjs'); +const Function = require('./Function.cjs'); +const GeneralEnclosed = require('./GeneralEnclosed.cjs'); +const Hash = require('./Hash.cjs'); +const Identifier = require('./Identifier.cjs'); +const IdSelector = require('./IdSelector.cjs'); +const Layer = require('./Layer.cjs'); +const LayerList = require('./LayerList.cjs'); +const MediaQuery = require('./MediaQuery.cjs'); +const MediaQueryList = require('./MediaQueryList.cjs'); +const NestingSelector = require('./NestingSelector.cjs'); +const Nth = require('./Nth.cjs'); +const Number = require('./Number.cjs'); +const Operator = require('./Operator.cjs'); +const Parentheses = require('./Parentheses.cjs'); +const Percentage = require('./Percentage.cjs'); +const PseudoClassSelector = require('./PseudoClassSelector.cjs'); +const PseudoElementSelector = require('./PseudoElementSelector.cjs'); +const Ratio = require('./Ratio.cjs'); +const Raw = require('./Raw.cjs'); +const Rule = require('./Rule.cjs'); +const Scope = require('./Scope.cjs'); +const Selector = require('./Selector.cjs'); +const SelectorList = require('./SelectorList.cjs'); +const String = require('./String.cjs'); +const StyleSheet = require('./StyleSheet.cjs'); +const SupportsDeclaration = require('./SupportsDeclaration.cjs'); +const TypeSelector = require('./TypeSelector.cjs'); +const UnicodeRange = require('./UnicodeRange.cjs'); +const Url = require('./Url.cjs'); +const Value = require('./Value.cjs'); +const WhiteSpace = require('./WhiteSpace.cjs'); + + + +exports.AnPlusB = AnPlusB.parse; +exports.Atrule = Atrule.parse; +exports.AtrulePrelude = AtrulePrelude.parse; +exports.AttributeSelector = AttributeSelector.parse; +exports.Block = Block.parse; +exports.Brackets = Brackets.parse; +exports.CDC = CDC.parse; +exports.CDO = CDO.parse; +exports.ClassSelector = ClassSelector.parse; +exports.Combinator = Combinator.parse; +exports.Comment = Comment.parse; +exports.Condition = Condition.parse; +exports.Declaration = Declaration.parse; +exports.DeclarationList = DeclarationList.parse; +exports.Dimension = Dimension.parse; +exports.Feature = Feature.parse; +exports.FeatureFunction = FeatureFunction.parse; +exports.FeatureRange = FeatureRange.parse; +exports.Function = Function.parse; +exports.GeneralEnclosed = GeneralEnclosed.parse; +exports.Hash = Hash.parse; +exports.Identifier = Identifier.parse; +exports.IdSelector = IdSelector.parse; +exports.Layer = Layer.parse; +exports.LayerList = LayerList.parse; +exports.MediaQuery = MediaQuery.parse; +exports.MediaQueryList = MediaQueryList.parse; +exports.NestingSelector = NestingSelector.parse; +exports.Nth = Nth.parse; +exports.Number = Number.parse; +exports.Operator = Operator.parse; +exports.Parentheses = Parentheses.parse; +exports.Percentage = Percentage.parse; +exports.PseudoClassSelector = PseudoClassSelector.parse; +exports.PseudoElementSelector = PseudoElementSelector.parse; +exports.Ratio = Ratio.parse; +exports.Raw = Raw.parse; +exports.Rule = Rule.parse; +exports.Scope = Scope.parse; +exports.Selector = Selector.parse; +exports.SelectorList = SelectorList.parse; +exports.String = String.parse; +exports.StyleSheet = StyleSheet.parse; +exports.SupportsDeclaration = SupportsDeclaration.parse; +exports.TypeSelector = TypeSelector.parse; +exports.UnicodeRange = UnicodeRange.parse; +exports.Url = Url.parse; +exports.Value = Value.parse; +exports.WhiteSpace = WhiteSpace.parse; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/node/index.cjs b/vanilla/node_modules/css-tree/cjs/syntax/node/index.cjs new file mode 100644 index 0000000..57451f0 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/node/index.cjs @@ -0,0 +1,103 @@ +'use strict'; + +const AnPlusB = require('./AnPlusB.cjs'); +const Atrule = require('./Atrule.cjs'); +const AtrulePrelude = require('./AtrulePrelude.cjs'); +const AttributeSelector = require('./AttributeSelector.cjs'); +const Block = require('./Block.cjs'); +const Brackets = require('./Brackets.cjs'); +const CDC = require('./CDC.cjs'); +const CDO = require('./CDO.cjs'); +const ClassSelector = require('./ClassSelector.cjs'); +const Combinator = require('./Combinator.cjs'); +const Comment = require('./Comment.cjs'); +const Condition = require('./Condition.cjs'); +const Declaration = require('./Declaration.cjs'); +const DeclarationList = require('./DeclarationList.cjs'); +const Dimension = require('./Dimension.cjs'); +const Feature = require('./Feature.cjs'); +const FeatureFunction = require('./FeatureFunction.cjs'); +const FeatureRange = require('./FeatureRange.cjs'); +const Function = require('./Function.cjs'); +const GeneralEnclosed = require('./GeneralEnclosed.cjs'); +const Hash = require('./Hash.cjs'); +const Identifier = require('./Identifier.cjs'); +const IdSelector = require('./IdSelector.cjs'); +const Layer = require('./Layer.cjs'); +const LayerList = require('./LayerList.cjs'); +const MediaQuery = require('./MediaQuery.cjs'); +const MediaQueryList = require('./MediaQueryList.cjs'); +const NestingSelector = require('./NestingSelector.cjs'); +const Nth = require('./Nth.cjs'); +const Number$1 = require('./Number.cjs'); +const Operator = require('./Operator.cjs'); +const Parentheses = require('./Parentheses.cjs'); +const Percentage = require('./Percentage.cjs'); +const PseudoClassSelector = require('./PseudoClassSelector.cjs'); +const PseudoElementSelector = require('./PseudoElementSelector.cjs'); +const Ratio = require('./Ratio.cjs'); +const Raw = require('./Raw.cjs'); +const Rule = require('./Rule.cjs'); +const Scope = require('./Scope.cjs'); +const Selector = require('./Selector.cjs'); +const SelectorList = require('./SelectorList.cjs'); +const String$1 = require('./String.cjs'); +const StyleSheet = require('./StyleSheet.cjs'); +const SupportsDeclaration = require('./SupportsDeclaration.cjs'); +const TypeSelector = require('./TypeSelector.cjs'); +const UnicodeRange = require('./UnicodeRange.cjs'); +const Url = require('./Url.cjs'); +const Value = require('./Value.cjs'); +const WhiteSpace = require('./WhiteSpace.cjs'); + + + +exports.AnPlusB = AnPlusB; +exports.Atrule = Atrule; +exports.AtrulePrelude = AtrulePrelude; +exports.AttributeSelector = AttributeSelector; +exports.Block = Block; +exports.Brackets = Brackets; +exports.CDC = CDC; +exports.CDO = CDO; +exports.ClassSelector = ClassSelector; +exports.Combinator = Combinator; +exports.Comment = Comment; +exports.Condition = Condition; +exports.Declaration = Declaration; +exports.DeclarationList = DeclarationList; +exports.Dimension = Dimension; +exports.Feature = Feature; +exports.FeatureFunction = FeatureFunction; +exports.FeatureRange = FeatureRange; +exports.Function = Function; +exports.GeneralEnclosed = GeneralEnclosed; +exports.Hash = Hash; +exports.Identifier = Identifier; +exports.IdSelector = IdSelector; +exports.Layer = Layer; +exports.LayerList = LayerList; +exports.MediaQuery = MediaQuery; +exports.MediaQueryList = MediaQueryList; +exports.NestingSelector = NestingSelector; +exports.Nth = Nth; +exports.Number = Number$1; +exports.Operator = Operator; +exports.Parentheses = Parentheses; +exports.Percentage = Percentage; +exports.PseudoClassSelector = PseudoClassSelector; +exports.PseudoElementSelector = PseudoElementSelector; +exports.Ratio = Ratio; +exports.Raw = Raw; +exports.Rule = Rule; +exports.Scope = Scope; +exports.Selector = Selector; +exports.SelectorList = SelectorList; +exports.String = String$1; +exports.StyleSheet = StyleSheet; +exports.SupportsDeclaration = SupportsDeclaration; +exports.TypeSelector = TypeSelector; +exports.UnicodeRange = UnicodeRange; +exports.Url = Url; +exports.Value = Value; +exports.WhiteSpace = WhiteSpace; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/pseudo/index.cjs b/vanilla/node_modules/css-tree/cjs/syntax/pseudo/index.cjs new file mode 100644 index 0000000..37ad6b8 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/pseudo/index.cjs @@ -0,0 +1,60 @@ +'use strict'; + +const lang = require('./lang.cjs'); + +const selectorList = { + parse() { + return this.createSingleNodeList( + this.SelectorList() + ); + } +}; + +const selector = { + parse() { + return this.createSingleNodeList( + this.Selector() + ); + } +}; + +const identList = { + parse() { + return this.createSingleNodeList( + this.Identifier() + ); + } +}; + +const langList = { + parse: lang.parseLanguageRangeList +}; + +const nth = { + parse() { + return this.createSingleNodeList( + this.Nth() + ); + } +}; + +const pseudo = { + 'dir': identList, + 'has': selectorList, + 'lang': langList, + '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, + 'host': selector, + 'host-context': selector +}; + +module.exports = pseudo; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/pseudo/lang.cjs b/vanilla/node_modules/css-tree/cjs/syntax/pseudo/lang.cjs new file mode 100644 index 0000000..6b80ee1 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/pseudo/lang.cjs @@ -0,0 +1,37 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +function parseLanguageRangeList() { + const children = this.createList(); + + this.skipSC(); + + loop: while (!this.eof) { + switch (this.tokenType) { + case types.Ident: + children.push(this.Identifier()); + break; + + case types.String: + children.push(this.String()); + break; + + case types.Comma: + children.push(this.Operator()); + break; + + case types.RightParenthesis: + break loop; + + default: + this.error('Identifier, string or comma is expected'); + } + + this.skipSC(); + } + + return children; +} + +exports.parseLanguageRangeList = parseLanguageRangeList; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/scope/atrulePrelude.cjs b/vanilla/node_modules/css-tree/cjs/syntax/scope/atrulePrelude.cjs new file mode 100644 index 0000000..65a1544 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/scope/atrulePrelude.cjs @@ -0,0 +1,9 @@ +'use strict'; + +const _default = require('./default.cjs'); + +const atrulePrelude = { + getNode: _default +}; + +module.exports = atrulePrelude; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/scope/default.cjs b/vanilla/node_modules/css-tree/cjs/syntax/scope/default.cjs new file mode 100644 index 0000000..43b5c18 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/scope/default.cjs @@ -0,0 +1,76 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +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) + +function defaultRecognizer(context) { + switch (this.tokenType) { + case types.Hash: + return this.Hash(); + + case types.Comma: + return this.Operator(); + + case types.LeftParenthesis: + return this.Parentheses(this.readSequence, context.recognizer); + + case types.LeftSquareBracket: + return this.Brackets(this.readSequence, context.recognizer); + + case types.String: + return this.String(); + + case types.Dimension: + return this.Dimension(); + + case types.Percentage: + return this.Percentage(); + + case types.Number: + return this.Number(); + + case types.Function: + return this.cmpStr(this.tokenStart, this.tokenEnd, 'url(') + ? this.Url() + : this.Function(this.readSequence, context.recognizer); + + case types.Url: + return this.Url(); + + case types.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 types.Delim: { + const code = this.charCodeAt(this.tokenStart); + + if (code === SOLIDUS || + code === ASTERISK || + code === PLUSSIGN || + code === HYPHENMINUS) { + return this.Operator(); // TODO: replace with Delim + } + + // TODO: produce a node with Delim node type + + if (code === NUMBERSIGN) { + this.error('Hex or identifier is expected', this.tokenStart + 1); + } + + break; + } + } +} + +module.exports = defaultRecognizer; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/scope/index.cjs b/vanilla/node_modules/css-tree/cjs/syntax/scope/index.cjs new file mode 100644 index 0000000..7839128 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/scope/index.cjs @@ -0,0 +1,11 @@ +'use strict'; + +const atrulePrelude = require('./atrulePrelude.cjs'); +const selector = require('./selector.cjs'); +const value = require('./value.cjs'); + + + +exports.AtrulePrelude = atrulePrelude; +exports.Selector = selector; +exports.Value = value; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/scope/selector.cjs b/vanilla/node_modules/css-tree/cjs/syntax/scope/selector.cjs new file mode 100644 index 0000000..6b915ae --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/scope/selector.cjs @@ -0,0 +1,88 @@ +'use strict'; + +const types = require('../../tokenizer/types.cjs'); + +const NUMBERSIGN = 0x0023; // U+0023 NUMBER 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 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: ' ' + }); + } +} + +function getNode() { + switch (this.tokenType) { + case types.LeftSquareBracket: + return this.AttributeSelector(); + + case types.Hash: + return this.IdSelector(); + + case types.Colon: + if (this.lookupType(1) === types.Colon) { + return this.PseudoElementSelector(); + } else { + return this.PseudoClassSelector(); + } + + case types.Ident: + return this.TypeSelector(); + + case types.Number: + case types.Percentage: + return this.Percentage(); + + case types.Dimension: + // throws when .123ident + if (this.charCodeAt(this.tokenStart) === FULLSTOP) { + this.error('Identifier is expected', this.tokenStart + 1); + } + break; + + case types.Delim: { + const code = this.charCodeAt(this.tokenStart); + + switch (code) { + case PLUSSIGN: + case GREATERTHANSIGN: + case TILDE: + case SOLIDUS: // /deep/ + return this.Combinator(); + + case FULLSTOP: + return this.ClassSelector(); + + case ASTERISK: + case VERTICALLINE: + return this.TypeSelector(); + + case NUMBERSIGN: + return this.IdSelector(); + + case AMPERSAND: + return this.NestingSelector(); + } + + break; + } + } +} +const Selector = { + onWhiteSpace, + getNode +}; + +module.exports = Selector; diff --git a/vanilla/node_modules/css-tree/cjs/syntax/scope/value.cjs b/vanilla/node_modules/css-tree/cjs/syntax/scope/value.cjs new file mode 100644 index 0000000..a9900a1 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/syntax/scope/value.cjs @@ -0,0 +1,29 @@ +'use strict'; + +const _default = require('./default.cjs'); +const expression = require('../function/expression.cjs'); +const _var = require('../function/var.cjs'); + +function isPlusMinusOperator(node) { + return ( + node !== null && + node.type === 'Operator' && + (node.value[node.value.length - 1] === '-' || node.value[node.value.length - 1] === '+') + ); +} + +const value = { + getNode: _default, + onWhiteSpace(next, children) { + if (isPlusMinusOperator(next)) { + next.value = ' ' + next.value; + } + if (isPlusMinusOperator(children.last)) { + children.last.value += ' '; + } + }, + 'expression': expression, + 'var': _var +}; + +module.exports = value; |
