From 76cb9c2a39d477a64824a985ade40507e3bbade1 Mon Sep 17 00:00:00 2001 From: Adam Mathes Date: Fri, 13 Feb 2026 21:34:48 -0800 Subject: feat(vanilla): add testing infrastructure and tests (NK-wjnczv) --- .../node_modules/css-tree/cjs/convertor/create.cjs | 32 ++ .../node_modules/css-tree/cjs/convertor/index.cjs | 8 + vanilla/node_modules/css-tree/cjs/data-patch.cjs | 7 + vanilla/node_modules/css-tree/cjs/data.cjs | 120 ++++ .../css-tree/cjs/definition-syntax/SyntaxError.cjs | 16 + .../css-tree/cjs/definition-syntax/generate.cjs | 139 +++++ .../css-tree/cjs/definition-syntax/index.cjs | 13 + .../css-tree/cjs/definition-syntax/parse.cjs | 556 ++++++++++++++++++ .../css-tree/cjs/definition-syntax/scanner.cjs | 113 ++++ .../css-tree/cjs/definition-syntax/tokenizer.cjs | 59 ++ .../css-tree/cjs/definition-syntax/walk.cjs | 57 ++ .../node_modules/css-tree/cjs/generator/create.cjs | 102 ++++ .../node_modules/css-tree/cjs/generator/index.cjs | 8 + .../css-tree/cjs/generator/sourceMap.cjs | 96 ++++ .../css-tree/cjs/generator/token-before.cjs | 170 ++++++ vanilla/node_modules/css-tree/cjs/index.cjs | 65 +++ vanilla/node_modules/css-tree/cjs/lexer/Lexer.cjs | 517 +++++++++++++++++ vanilla/node_modules/css-tree/cjs/lexer/error.cjs | 128 +++++ .../css-tree/cjs/lexer/generic-an-plus-b.cjs | 235 ++++++++ .../css-tree/cjs/lexer/generic-const.cjs | 12 + .../css-tree/cjs/lexer/generic-urange.cjs | 149 +++++ .../node_modules/css-tree/cjs/lexer/generic.cjs | 589 +++++++++++++++++++ vanilla/node_modules/css-tree/cjs/lexer/index.cjs | 7 + .../css-tree/cjs/lexer/match-graph.cjs | 530 +++++++++++++++++ vanilla/node_modules/css-tree/cjs/lexer/match.cjs | 632 +++++++++++++++++++++ .../css-tree/cjs/lexer/prepare-tokens.cjs | 54 ++ vanilla/node_modules/css-tree/cjs/lexer/search.cjs | 65 +++ .../node_modules/css-tree/cjs/lexer/structure.cjs | 173 ++++++ vanilla/node_modules/css-tree/cjs/lexer/trace.cjs | 73 +++ vanilla/node_modules/css-tree/cjs/lexer/units.cjs | 38 ++ .../css-tree/cjs/parser/SyntaxError.cjs | 74 +++ .../node_modules/css-tree/cjs/parser/create.cjs | 340 +++++++++++ vanilla/node_modules/css-tree/cjs/parser/index.cjs | 8 + .../css-tree/cjs/parser/parse-selector.cjs | 8 + .../node_modules/css-tree/cjs/parser/sequence.cjs | 47 ++ .../css-tree/cjs/syntax/atrule/container.cjs | 32 ++ .../css-tree/cjs/syntax/atrule/font-face.cjs | 12 + .../css-tree/cjs/syntax/atrule/import.cjs | 101 ++++ .../css-tree/cjs/syntax/atrule/index.cjs | 27 + .../css-tree/cjs/syntax/atrule/layer.cjs | 16 + .../css-tree/cjs/syntax/atrule/media.cjs | 16 + .../css-tree/cjs/syntax/atrule/nest.cjs | 16 + .../css-tree/cjs/syntax/atrule/page.cjs | 16 + .../css-tree/cjs/syntax/atrule/scope.cjs | 16 + .../css-tree/cjs/syntax/atrule/starting-style.cjs | 12 + .../css-tree/cjs/syntax/atrule/supports.cjs | 16 + .../css-tree/cjs/syntax/config/generator.cjs | 9 + .../css-tree/cjs/syntax/config/lexer.cjs | 14 + .../css-tree/cjs/syntax/config/mix.cjs | 127 +++++ .../css-tree/cjs/syntax/config/parser-selector.cjs | 19 + .../css-tree/cjs/syntax/config/parser.cjs | 49 ++ .../css-tree/cjs/syntax/config/walker.cjs | 9 + .../node_modules/css-tree/cjs/syntax/create.cjs | 58 ++ .../css-tree/cjs/syntax/function/expression.cjs | 11 + .../css-tree/cjs/syntax/function/var.cjs | 43 ++ vanilla/node_modules/css-tree/cjs/syntax/index.cjs | 14 + .../css-tree/cjs/syntax/node/AnPlusB.cjs | 293 ++++++++++ .../css-tree/cjs/syntax/node/Atrule.cjs | 103 ++++ .../css-tree/cjs/syntax/node/AtrulePrelude.cjs | 52 ++ .../css-tree/cjs/syntax/node/AttributeSelector.cjs | 148 +++++ .../css-tree/cjs/syntax/node/Block.cjs | 96 ++++ .../css-tree/cjs/syntax/node/Brackets.cjs | 38 ++ .../node_modules/css-tree/cjs/syntax/node/CDC.cjs | 26 + .../node_modules/css-tree/cjs/syntax/node/CDO.cjs | 26 + .../css-tree/cjs/syntax/node/ClassSelector.cjs | 31 + .../css-tree/cjs/syntax/node/Combinator.cjs | 61 ++ .../css-tree/cjs/syntax/node/Comment.cjs | 40 ++ .../css-tree/cjs/syntax/node/Condition.cjs | 120 ++++ .../css-tree/cjs/syntax/node/Declaration.cjs | 166 ++++++ .../css-tree/cjs/syntax/node/DeclarationList.cjs | 62 ++ .../css-tree/cjs/syntax/node/Dimension.cjs | 30 + .../css-tree/cjs/syntax/node/Feature.cjs | 101 ++++ .../css-tree/cjs/syntax/node/FeatureFunction.cjs | 67 +++ .../css-tree/cjs/syntax/node/FeatureRange.cjs | 133 +++++ .../css-tree/cjs/syntax/node/Function.cjs | 45 ++ .../css-tree/cjs/syntax/node/GeneralEnclosed.cjs | 68 +++ .../node_modules/css-tree/cjs/syntax/node/Hash.cjs | 30 + .../css-tree/cjs/syntax/node/IdSelector.cjs | 33 ++ .../css-tree/cjs/syntax/node/Identifier.cjs | 25 + .../css-tree/cjs/syntax/node/Layer.cjs | 35 ++ .../css-tree/cjs/syntax/node/LayerList.cjs | 43 ++ .../css-tree/cjs/syntax/node/LayerName.cjs | 34 ++ .../css-tree/cjs/syntax/node/LayerNameList.cjs | 42 ++ .../css-tree/cjs/syntax/node/MediaCondition.cjs | 70 +++ .../css-tree/cjs/syntax/node/MediaFeature.cjs | 76 +++ .../css-tree/cjs/syntax/node/MediaFeatureRange.cjs | 11 + .../css-tree/cjs/syntax/node/MediaQuery.cjs | 100 ++++ .../css-tree/cjs/syntax/node/MediaQueryList.cjs | 41 ++ .../css-tree/cjs/syntax/node/NestingSelector.cjs | 29 + .../node_modules/css-tree/cjs/syntax/node/Nth.cjs | 54 ++ .../css-tree/cjs/syntax/node/Number.cjs | 25 + .../css-tree/cjs/syntax/node/Operator.cjs | 28 + .../css-tree/cjs/syntax/node/Parentheses.cjs | 38 ++ .../css-tree/cjs/syntax/node/Percentage.cjs | 25 + .../cjs/syntax/node/PseudoClassSelector.cjs | 67 +++ .../cjs/syntax/node/PseudoElementSelector.cjs | 69 +++ .../css-tree/cjs/syntax/node/Ratio.cjs | 71 +++ .../node_modules/css-tree/cjs/syntax/node/Raw.cjs | 48 ++ .../node_modules/css-tree/cjs/syntax/node/Rule.cjs | 58 ++ .../css-tree/cjs/syntax/node/Scope.cjs | 69 +++ .../css-tree/cjs/syntax/node/Selector.cjs | 38 ++ .../css-tree/cjs/syntax/node/SelectorList.cjs | 43 ++ .../css-tree/cjs/syntax/node/String.cjs | 26 + .../css-tree/cjs/syntax/node/StyleSheet.cjs | 83 +++ .../cjs/syntax/node/SupportsDeclaration.cjs | 38 ++ .../css-tree/cjs/syntax/node/SupportsFeature.cjs | 69 +++ .../css-tree/cjs/syntax/node/TypeSelector.cjs | 59 ++ .../css-tree/cjs/syntax/node/UnicodeRange.cjs | 158 ++++++ .../node_modules/css-tree/cjs/syntax/node/Url.cjs | 54 ++ .../css-tree/cjs/syntax/node/Value.cjs | 26 + .../css-tree/cjs/syntax/node/WhiteSpace.cjs | 34 ++ .../cjs/syntax/node/common/feature-range.cjs | 112 ++++ .../css-tree/cjs/syntax/node/common/feature.cjs | 76 +++ .../css-tree/cjs/syntax/node/index-generate.cjs | 103 ++++ .../cjs/syntax/node/index-parse-selector.cjs | 39 ++ .../css-tree/cjs/syntax/node/index-parse.cjs | 103 ++++ .../css-tree/cjs/syntax/node/index.cjs | 103 ++++ .../css-tree/cjs/syntax/pseudo/index.cjs | 60 ++ .../css-tree/cjs/syntax/pseudo/lang.cjs | 37 ++ .../css-tree/cjs/syntax/scope/atrulePrelude.cjs | 9 + .../css-tree/cjs/syntax/scope/default.cjs | 76 +++ .../css-tree/cjs/syntax/scope/index.cjs | 11 + .../css-tree/cjs/syntax/scope/selector.cjs | 88 +++ .../css-tree/cjs/syntax/scope/value.cjs | 29 + .../css-tree/cjs/tokenizer/OffsetToLocation.cjs | 91 +++ .../css-tree/cjs/tokenizer/TokenStream.cjs | 308 ++++++++++ .../css-tree/cjs/tokenizer/adopt-buffer.cjs | 13 + .../cjs/tokenizer/char-code-definitions.cjs | 236 ++++++++ .../node_modules/css-tree/cjs/tokenizer/index.cjs | 554 ++++++++++++++++++ .../node_modules/css-tree/cjs/tokenizer/names.cjs | 32 ++ .../node_modules/css-tree/cjs/tokenizer/types.cjs | 57 ++ .../node_modules/css-tree/cjs/tokenizer/utils.cjs | 261 +++++++++ vanilla/node_modules/css-tree/cjs/utils/List.cjs | 473 +++++++++++++++ vanilla/node_modules/css-tree/cjs/utils/clone.cjs | 25 + .../css-tree/cjs/utils/create-custom-error.cjs | 18 + vanilla/node_modules/css-tree/cjs/utils/ident.cjs | 102 ++++ vanilla/node_modules/css-tree/cjs/utils/index.cjs | 20 + vanilla/node_modules/css-tree/cjs/utils/names.cjs | 113 ++++ vanilla/node_modules/css-tree/cjs/utils/string.cjs | 99 ++++ vanilla/node_modules/css-tree/cjs/utils/url.cjs | 108 ++++ vanilla/node_modules/css-tree/cjs/version.cjs | 5 + .../node_modules/css-tree/cjs/walker/create.cjs | 291 ++++++++++ vanilla/node_modules/css-tree/cjs/walker/index.cjs | 8 + 143 files changed, 12988 insertions(+) create mode 100644 vanilla/node_modules/css-tree/cjs/convertor/create.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/convertor/index.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/data-patch.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/data.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/definition-syntax/SyntaxError.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/definition-syntax/generate.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/definition-syntax/index.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/definition-syntax/parse.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/definition-syntax/scanner.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/definition-syntax/tokenizer.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/definition-syntax/walk.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/generator/create.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/generator/index.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/generator/sourceMap.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/generator/token-before.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/index.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/lexer/Lexer.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/lexer/error.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/lexer/generic-an-plus-b.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/lexer/generic-const.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/lexer/generic-urange.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/lexer/generic.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/lexer/index.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/lexer/match-graph.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/lexer/match.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/lexer/prepare-tokens.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/lexer/search.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/lexer/structure.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/lexer/trace.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/lexer/units.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/parser/SyntaxError.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/parser/create.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/parser/index.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/parser/parse-selector.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/parser/sequence.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/atrule/container.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/atrule/font-face.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/atrule/import.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/atrule/index.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/atrule/layer.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/atrule/media.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/atrule/nest.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/atrule/page.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/atrule/scope.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/atrule/starting-style.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/atrule/supports.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/config/generator.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/config/lexer.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/config/mix.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/config/parser-selector.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/config/parser.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/config/walker.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/create.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/function/expression.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/function/var.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/index.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/AnPlusB.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Atrule.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/AtrulePrelude.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/AttributeSelector.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Block.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Brackets.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/CDC.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/CDO.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/ClassSelector.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Combinator.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Comment.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Condition.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Declaration.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/DeclarationList.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Dimension.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Feature.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/FeatureFunction.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/FeatureRange.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Function.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/GeneralEnclosed.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Hash.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/IdSelector.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Identifier.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Layer.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/LayerList.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/LayerName.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/LayerNameList.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/MediaCondition.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/MediaFeature.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/MediaFeatureRange.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/MediaQuery.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/MediaQueryList.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/NestingSelector.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Nth.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Number.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Operator.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Parentheses.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Percentage.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/PseudoClassSelector.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/PseudoElementSelector.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Ratio.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Raw.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Rule.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Scope.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Selector.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/SelectorList.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/String.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/StyleSheet.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/SupportsDeclaration.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/SupportsFeature.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/TypeSelector.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/UnicodeRange.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Url.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/Value.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/WhiteSpace.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/common/feature-range.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/common/feature.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/index-generate.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/index-parse-selector.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/index-parse.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/node/index.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/pseudo/index.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/pseudo/lang.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/scope/atrulePrelude.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/scope/default.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/scope/index.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/scope/selector.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/syntax/scope/value.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/tokenizer/OffsetToLocation.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/tokenizer/TokenStream.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/tokenizer/adopt-buffer.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/tokenizer/char-code-definitions.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/tokenizer/index.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/tokenizer/names.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/tokenizer/types.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/tokenizer/utils.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/utils/List.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/utils/clone.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/utils/create-custom-error.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/utils/ident.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/utils/index.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/utils/names.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/utils/string.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/utils/url.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/version.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/walker/create.cjs create mode 100644 vanilla/node_modules/css-tree/cjs/walker/index.cjs (limited to 'vanilla/node_modules/css-tree/cjs') diff --git a/vanilla/node_modules/css-tree/cjs/convertor/create.cjs b/vanilla/node_modules/css-tree/cjs/convertor/create.cjs new file mode 100644 index 0000000..55c655b --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/convertor/create.cjs @@ -0,0 +1,32 @@ +'use strict'; + +const List = require('../utils/List.cjs'); + +function createConvertor(walk) { + return { + fromPlainObject(ast) { + walk(ast, { + enter(node) { + if (node.children && node.children instanceof List.List === false) { + node.children = new List.List().fromArray(node.children); + } + } + }); + + return ast; + }, + toPlainObject(ast) { + walk(ast, { + leave(node) { + if (node.children && node.children instanceof List.List) { + node.children = node.children.toArray(); + } + } + }); + + return ast; + } + }; +} + +exports.createConvertor = createConvertor; diff --git a/vanilla/node_modules/css-tree/cjs/convertor/index.cjs b/vanilla/node_modules/css-tree/cjs/convertor/index.cjs new file mode 100644 index 0000000..6654278 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/convertor/index.cjs @@ -0,0 +1,8 @@ +'use strict'; + +const create = require('./create.cjs'); +const index$1 = require('../walker/index.cjs'); + +const index = create.createConvertor(index$1); + +module.exports = index; diff --git a/vanilla/node_modules/css-tree/cjs/data-patch.cjs b/vanilla/node_modules/css-tree/cjs/data-patch.cjs new file mode 100644 index 0000000..9103ea4 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/data-patch.cjs @@ -0,0 +1,7 @@ +'use strict'; + +const patch = require('../data/patch.json'); + +const patch$1 = patch; + +module.exports = patch$1; diff --git a/vanilla/node_modules/css-tree/cjs/data.cjs b/vanilla/node_modules/css-tree/cjs/data.cjs new file mode 100644 index 0000000..258ac6a --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/data.cjs @@ -0,0 +1,120 @@ +'use strict'; + +const dataPatch = require('./data-patch.cjs'); + +const mdnAtrules = require('mdn-data/css/at-rules.json'); +const mdnProperties = require('mdn-data/css/properties.json'); +const mdnSyntaxes = require('mdn-data/css/syntaxes.json'); + +const hasOwn = Object.hasOwn || ((object, property) => Object.prototype.hasOwnProperty.call(object, property)); +const extendSyntax = /^\s*\|\s*/; + +function preprocessAtrules(dict) { + const result = Object.create(null); + + for (const [atruleName, atrule] of Object.entries(dict)) { + let descriptors = null; + + if (atrule.descriptors) { + descriptors = Object.create(null); + + for (const [name, descriptor] of Object.entries(atrule.descriptors)) { + descriptors[name] = descriptor.syntax; + } + } + + result[atruleName.substr(1)] = { + prelude: atrule.syntax.trim().replace(/\{(.|\s)+\}/, '').match(/^@\S+\s+([^;\{]*)/)[1].trim() || null, + descriptors + }; + } + + return result; +} + +function patchDictionary(dict, patchDict) { + const result = Object.create(null); + + // copy all syntaxes for an original dict + for (const [key, value] of Object.entries(dict)) { + if (value) { + result[key] = value.syntax || value; + } + } + + // apply a patch + for (const key of Object.keys(patchDict)) { + if (hasOwn(dict, key)) { + if (patchDict[key].syntax) { + result[key] = extendSyntax.test(patchDict[key].syntax) + ? result[key] + ' ' + patchDict[key].syntax.trim() + : patchDict[key].syntax; + } else { + delete result[key]; + } + } else { + if (patchDict[key].syntax) { + result[key] = patchDict[key].syntax.replace(extendSyntax, ''); + } + } + } + + return result; +} + +function preprocessPatchAtrulesDescritors(declarations) { + const result = {}; + + for (const [key, value] of Object.entries(declarations || {})) { + result[key] = typeof value === 'string' + ? { syntax: value } + : value; + } + + return result; +} + +function patchAtrules(dict, patchDict) { + const result = {}; + + // copy all syntaxes for an original dict + for (const key in dict) { + if (patchDict[key] === null) { + continue; + } + + const atrulePatch = patchDict[key] || {}; + + result[key] = { + prelude: key in patchDict && 'prelude' in atrulePatch + ? atrulePatch.prelude + : dict[key].prelude || null, + descriptors: patchDictionary( + dict[key].descriptors || {}, + preprocessPatchAtrulesDescritors(atrulePatch.descriptors) + ) + }; + } + + // apply a patch + for (const [key, atrulePatch] of Object.entries(patchDict)) { + if (atrulePatch && !hasOwn(dict, key)) { + result[key] = { + prelude: atrulePatch.prelude || null, + descriptors: atrulePatch.descriptors + ? patchDictionary({}, preprocessPatchAtrulesDescritors(atrulePatch.descriptors)) + : null + }; + } + } + + return result; +} + +const definitions = { + types: patchDictionary(mdnSyntaxes, dataPatch.types), + atrules: patchAtrules(preprocessAtrules(mdnAtrules), dataPatch.atrules), + properties: patchDictionary(mdnProperties, dataPatch.properties) +}; + +module.exports = definitions; diff --git a/vanilla/node_modules/css-tree/cjs/definition-syntax/SyntaxError.cjs b/vanilla/node_modules/css-tree/cjs/definition-syntax/SyntaxError.cjs new file mode 100644 index 0000000..d24e7ce --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/definition-syntax/SyntaxError.cjs @@ -0,0 +1,16 @@ +'use strict'; + +const createCustomError = require('../utils/create-custom-error.cjs'); + +function SyntaxError(message, input, offset) { + return Object.assign(createCustomError.createCustomError('SyntaxError', message), { + input, + offset, + rawMessage: message, + message: message + '\n' + + ' ' + input + '\n' + + '--' + new Array((offset || input.length) + 1).join('-') + '^' + }); +} + +exports.SyntaxError = SyntaxError; diff --git a/vanilla/node_modules/css-tree/cjs/definition-syntax/generate.cjs b/vanilla/node_modules/css-tree/cjs/definition-syntax/generate.cjs new file mode 100644 index 0000000..ff9f0ad --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/definition-syntax/generate.cjs @@ -0,0 +1,139 @@ +'use strict'; + +function noop(value) { + return value; +} + +function generateMultiplier(multiplier) { + const { min, max, comma } = multiplier; + + if (min === 0 && max === 0) { + return comma ? '#?' : '*'; + } + + if (min === 0 && max === 1) { + return '?'; + } + + if (min === 1 && max === 0) { + return comma ? '#' : '+'; + } + + if (min === 1 && max === 1) { + return ''; + } + + return ( + (comma ? '#' : '') + + (min === max + ? '{' + min + '}' + : '{' + min + ',' + (max !== 0 ? max : '') + '}' + ) + ); +} + +function generateTypeOpts(node) { + switch (node.type) { + case 'Range': + return ( + ' [' + + (node.min === null ? '-∞' : node.min) + + ',' + + (node.max === null ? '∞' : node.max) + + ']' + ); + + default: + throw new Error('Unknown node type `' + node.type + '`'); + } +} + +function generateSequence(node, decorate, forceBraces, compact) { + const combinator = node.combinator === ' ' || compact ? node.combinator : ' ' + node.combinator + ' '; + const result = node.terms + .map(term => internalGenerate(term, decorate, forceBraces, compact)) + .join(combinator); + + if (node.explicit || forceBraces) { + return (compact || result[0] === ',' ? '[' : '[ ') + result + (compact ? ']' : ' ]'); + } + + return result; +} + +function internalGenerate(node, decorate, forceBraces, compact) { + let result; + + switch (node.type) { + case 'Group': + result = + generateSequence(node, decorate, forceBraces, compact) + + (node.disallowEmpty ? '!' : ''); + break; + + case 'Multiplier': + // return since node is a composition + return ( + internalGenerate(node.term, decorate, forceBraces, compact) + + decorate(generateMultiplier(node), node) + ); + + case 'Boolean': + result = ''; + break; + + case 'Type': + result = '<' + node.name + (node.opts ? decorate(generateTypeOpts(node.opts), node.opts) : '') + '>'; + break; + + case 'Property': + result = '<\'' + node.name + '\'>'; + break; + + case 'Keyword': + result = node.name; + break; + + case 'AtKeyword': + result = '@' + node.name; + break; + + case 'Function': + result = node.name + '('; + break; + + case 'String': + case 'Token': + result = node.value; + break; + + case 'Comma': + result = ','; + break; + + default: + throw new Error('Unknown node type `' + node.type + '`'); + } + + return decorate(result, node); +} + +function generate(node, options) { + let decorate = noop; + let forceBraces = false; + let compact = false; + + if (typeof options === 'function') { + decorate = options; + } else if (options) { + forceBraces = Boolean(options.forceBraces); + compact = Boolean(options.compact); + if (typeof options.decorate === 'function') { + decorate = options.decorate; + } + } + + return internalGenerate(node, decorate, forceBraces, compact); +} + +exports.generate = generate; diff --git a/vanilla/node_modules/css-tree/cjs/definition-syntax/index.cjs b/vanilla/node_modules/css-tree/cjs/definition-syntax/index.cjs new file mode 100644 index 0000000..0afb505 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/definition-syntax/index.cjs @@ -0,0 +1,13 @@ +'use strict'; + +const SyntaxError = require('./SyntaxError.cjs'); +const generate = require('./generate.cjs'); +const parse = require('./parse.cjs'); +const walk = require('./walk.cjs'); + + + +exports.SyntaxError = SyntaxError.SyntaxError; +exports.generate = generate.generate; +exports.parse = parse.parse; +exports.walk = walk.walk; diff --git a/vanilla/node_modules/css-tree/cjs/definition-syntax/parse.cjs b/vanilla/node_modules/css-tree/cjs/definition-syntax/parse.cjs new file mode 100644 index 0000000..b17b267 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/definition-syntax/parse.cjs @@ -0,0 +1,556 @@ +'use strict'; + +const scanner = require('./scanner.cjs'); + +const TAB = 9; +const N = 10; +const F = 12; +const R = 13; +const SPACE = 32; +const EXCLAMATIONMARK = 33; // ! +const NUMBERSIGN = 35; // # +const AMPERSAND = 38; // & +const APOSTROPHE = 39; // ' +const LEFTPARENTHESIS = 40; // ( +const RIGHTPARENTHESIS = 41; // ) +const ASTERISK = 42; // * +const PLUSSIGN = 43; // + +const COMMA = 44; // , +const HYPERMINUS = 45; // - +const LESSTHANSIGN = 60; // < +const GREATERTHANSIGN = 62; // > +const QUESTIONMARK = 63; // ? +const COMMERCIALAT = 64; // @ +const LEFTSQUAREBRACKET = 91; // [ +const RIGHTSQUAREBRACKET = 93; // ] +const LEFTCURLYBRACKET = 123; // { +const VERTICALLINE = 124; // | +const RIGHTCURLYBRACKET = 125; // } +const INFINITY = 8734; // ∞ +const COMBINATOR_PRECEDENCE = { + ' ': 1, + '&&': 2, + '||': 3, + '|': 4 +}; + +function readMultiplierRange(scanner) { + let min = null; + let max = null; + + scanner.eat(LEFTCURLYBRACKET); + scanner.skipWs(); + + min = scanner.scanNumber(scanner); + scanner.skipWs(); + + if (scanner.charCode() === COMMA) { + scanner.pos++; + scanner.skipWs(); + + if (scanner.charCode() !== RIGHTCURLYBRACKET) { + max = scanner.scanNumber(scanner); + scanner.skipWs(); + } + } else { + max = min; + } + + scanner.eat(RIGHTCURLYBRACKET); + + return { + min: Number(min), + max: max ? Number(max) : 0 + }; +} + +function readMultiplier(scanner) { + let range = null; + let comma = false; + + switch (scanner.charCode()) { + case ASTERISK: + scanner.pos++; + + range = { + min: 0, + max: 0 + }; + + break; + + case PLUSSIGN: + scanner.pos++; + + range = { + min: 1, + max: 0 + }; + + break; + + case QUESTIONMARK: + scanner.pos++; + + range = { + min: 0, + max: 1 + }; + + break; + + case NUMBERSIGN: + scanner.pos++; + + comma = true; + + if (scanner.charCode() === LEFTCURLYBRACKET) { + range = readMultiplierRange(scanner); + } else if (scanner.charCode() === QUESTIONMARK) { + // https://www.w3.org/TR/css-values-4/#component-multipliers + // > the # and ? multipliers may be stacked as #? + // In this case just treat "#?" as a single multiplier + // { min: 0, max: 0, comma: true } + scanner.pos++; + range = { + min: 0, + max: 0 + }; + } else { + range = { + min: 1, + max: 0 + }; + } + + break; + + case LEFTCURLYBRACKET: + range = readMultiplierRange(scanner); + break; + + default: + return null; + } + + return { + type: 'Multiplier', + comma, + min: range.min, + max: range.max, + term: null + }; +} + +function maybeMultiplied(scanner, node) { + const multiplier = readMultiplier(scanner); + + if (multiplier !== null) { + multiplier.term = node; + + // https://www.w3.org/TR/css-values-4/#component-multipliers + // > The + and # multipliers may be stacked as +#; + // Represent "+#" as nested multipliers: + // { ..., + // term: { + // ..., + // term: node + // } + // } + if (scanner.charCode() === NUMBERSIGN && + scanner.charCodeAt(scanner.pos - 1) === PLUSSIGN) { + return maybeMultiplied(scanner, multiplier); + } + + return multiplier; + } + + return node; +} + +function maybeToken(scanner) { + const ch = scanner.peek(); + + if (ch === '') { + return null; + } + + return maybeMultiplied(scanner, { + type: 'Token', + value: ch + }); +} + +function readProperty(scanner) { + let name; + + scanner.eat(LESSTHANSIGN); + scanner.eat(APOSTROPHE); + + name = scanner.scanWord(); + + scanner.eat(APOSTROPHE); + scanner.eat(GREATERTHANSIGN); + + return maybeMultiplied(scanner, { + type: 'Property', + name + }); +} + +// https://drafts.csswg.org/css-values-3/#numeric-ranges +// 4.1. Range Restrictions and Range Definition Notation +// +// Range restrictions can be annotated in the numeric type notation using CSS bracketed +// range notation—[min,max]—within the angle brackets, after the identifying keyword, +// indicating a closed range between (and including) min and max. +// For example, indicates an integer between 0 and 10, inclusive. +function readTypeRange(scanner) { + // use null for Infinity to make AST format JSON serializable/deserializable + let min = null; // -Infinity + let max = null; // Infinity + let sign = 1; + + scanner.eat(LEFTSQUAREBRACKET); + + if (scanner.charCode() === HYPERMINUS) { + scanner.peek(); + sign = -1; + } + + if (sign == -1 && scanner.charCode() === INFINITY) { + scanner.peek(); + } else { + min = sign * Number(scanner.scanNumber(scanner)); + + if (scanner.isNameCharCode()) { + min += scanner.scanWord(); + } + } + + scanner.skipWs(); + scanner.eat(COMMA); + scanner.skipWs(); + + if (scanner.charCode() === INFINITY) { + scanner.peek(); + } else { + sign = 1; + + if (scanner.charCode() === HYPERMINUS) { + scanner.peek(); + sign = -1; + } + + max = sign * Number(scanner.scanNumber(scanner)); + + if (scanner.isNameCharCode()) { + max += scanner.scanWord(); + } + } + + scanner.eat(RIGHTSQUAREBRACKET); + + return { + type: 'Range', + min, + max + }; +} + +function readType(scanner) { + let name; + let opts = null; + + scanner.eat(LESSTHANSIGN); + name = scanner.scanWord(); + + // https://drafts.csswg.org/css-values-5/#boolean + if (name === 'boolean-expr') { + scanner.eat(LEFTSQUAREBRACKET); + + const implicitGroup = readImplicitGroup(scanner, RIGHTSQUAREBRACKET); + + scanner.eat(RIGHTSQUAREBRACKET); + scanner.eat(GREATERTHANSIGN); + + return maybeMultiplied(scanner, { + type: 'Boolean', + term: implicitGroup.terms.length === 1 + ? implicitGroup.terms[0] + : implicitGroup + }); + } + + if (scanner.charCode() === LEFTPARENTHESIS && + scanner.nextCharCode() === RIGHTPARENTHESIS) { + scanner.pos += 2; + name += '()'; + } + + if (scanner.charCodeAt(scanner.findWsEnd(scanner.pos)) === LEFTSQUAREBRACKET) { + scanner.skipWs(); + opts = readTypeRange(scanner); + } + + scanner.eat(GREATERTHANSIGN); + + return maybeMultiplied(scanner, { + type: 'Type', + name, + opts + }); +} + +function readKeywordOrFunction(scanner) { + const name = scanner.scanWord(); + + if (scanner.charCode() === LEFTPARENTHESIS) { + scanner.pos++; + + return { + type: 'Function', + name + }; + } + + return maybeMultiplied(scanner, { + type: 'Keyword', + name + }); +} + +function regroupTerms(terms, combinators) { + function createGroup(terms, combinator) { + return { + type: 'Group', + terms, + combinator, + disallowEmpty: false, + explicit: false + }; + } + + let combinator; + + combinators = Object.keys(combinators) + .sort((a, b) => COMBINATOR_PRECEDENCE[a] - COMBINATOR_PRECEDENCE[b]); + + while (combinators.length > 0) { + combinator = combinators.shift(); + + let i = 0; + let subgroupStart = 0; + + for (; i < terms.length; i++) { + const term = terms[i]; + + if (term.type === 'Combinator') { + if (term.value === combinator) { + if (subgroupStart === -1) { + subgroupStart = i - 1; + } + terms.splice(i, 1); + i--; + } else { + if (subgroupStart !== -1 && i - subgroupStart > 1) { + terms.splice( + subgroupStart, + i - subgroupStart, + createGroup(terms.slice(subgroupStart, i), combinator) + ); + i = subgroupStart + 1; + } + subgroupStart = -1; + } + } + } + + if (subgroupStart !== -1 && combinators.length) { + terms.splice( + subgroupStart, + i - subgroupStart, + createGroup(terms.slice(subgroupStart, i), combinator) + ); + } + } + + return combinator; +} + +function readImplicitGroup(scanner, stopCharCode) { + const combinators = Object.create(null); + const terms = []; + let token; + let prevToken = null; + let prevTokenPos = scanner.pos; + + while (scanner.charCode() !== stopCharCode && (token = peek(scanner, stopCharCode))) { + if (token.type !== 'Spaces') { + if (token.type === 'Combinator') { + // check for combinator in group beginning and double combinator sequence + if (prevToken === null || prevToken.type === 'Combinator') { + scanner.pos = prevTokenPos; + scanner.error('Unexpected combinator'); + } + + combinators[token.value] = true; + } else if (prevToken !== null && prevToken.type !== 'Combinator') { + combinators[' '] = true; // a b + terms.push({ + type: 'Combinator', + value: ' ' + }); + } + + terms.push(token); + prevToken = token; + prevTokenPos = scanner.pos; + } + } + + // check for combinator in group ending + if (prevToken !== null && prevToken.type === 'Combinator') { + scanner.pos -= prevTokenPos; + scanner.error('Unexpected combinator'); + } + + return { + type: 'Group', + terms, + combinator: regroupTerms(terms, combinators) || ' ', + disallowEmpty: false, + explicit: false + }; +} + +function readGroup(scanner, stopCharCode) { + let result; + + scanner.eat(LEFTSQUAREBRACKET); + result = readImplicitGroup(scanner, stopCharCode); + scanner.eat(RIGHTSQUAREBRACKET); + + result.explicit = true; + + if (scanner.charCode() === EXCLAMATIONMARK) { + scanner.pos++; + result.disallowEmpty = true; + } + + return result; +} + +function peek(scanner, stopCharCode) { + let code = scanner.charCode(); + + switch (code) { + case RIGHTSQUAREBRACKET: + // don't eat, stop scan a group + break; + + case LEFTSQUAREBRACKET: + return maybeMultiplied(scanner, readGroup(scanner, stopCharCode)); + + case LESSTHANSIGN: + return scanner.nextCharCode() === APOSTROPHE + ? readProperty(scanner) + : readType(scanner); + + case VERTICALLINE: + return { + type: 'Combinator', + value: scanner.substringToPos( + scanner.pos + (scanner.nextCharCode() === VERTICALLINE ? 2 : 1) + ) + }; + + case AMPERSAND: + scanner.pos++; + scanner.eat(AMPERSAND); + + return { + type: 'Combinator', + value: '&&' + }; + + case COMMA: + scanner.pos++; + return { + type: 'Comma' + }; + + case APOSTROPHE: + return maybeMultiplied(scanner, { + type: 'String', + value: scanner.scanString() + }); + + case SPACE: + case TAB: + case N: + case R: + case F: + return { + type: 'Spaces', + value: scanner.scanSpaces() + }; + + case COMMERCIALAT: + code = scanner.nextCharCode(); + + if (scanner.isNameCharCode(code)) { + scanner.pos++; + return { + type: 'AtKeyword', + name: scanner.scanWord() + }; + } + + return maybeToken(scanner); + + case ASTERISK: + case PLUSSIGN: + case QUESTIONMARK: + case NUMBERSIGN: + case EXCLAMATIONMARK: + // prohibited tokens (used as a multiplier start) + break; + + case LEFTCURLYBRACKET: + // LEFTCURLYBRACKET is allowed since mdn/data uses it w/o quoting + // check next char isn't a number, because it's likely a disjoined multiplier + code = scanner.nextCharCode(); + + if (code < 48 || code > 57) { + return maybeToken(scanner); + } + + break; + + default: + if (scanner.isNameCharCode(code)) { + return readKeywordOrFunction(scanner); + } + + return maybeToken(scanner); + } +} + +function parse(source) { + const scanner$1 = new scanner.Scanner(source); + const result = readImplicitGroup(scanner$1); + + if (scanner$1.pos !== source.length) { + scanner$1.error('Unexpected input'); + } + + // reduce redundant groups with single group term + if (result.terms.length === 1 && result.terms[0].type === 'Group') { + return result.terms[0]; + } + + return result; +} + +exports.parse = parse; diff --git a/vanilla/node_modules/css-tree/cjs/definition-syntax/scanner.cjs b/vanilla/node_modules/css-tree/cjs/definition-syntax/scanner.cjs new file mode 100644 index 0000000..0bad36a --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/definition-syntax/scanner.cjs @@ -0,0 +1,113 @@ +'use strict'; + +const SyntaxError = require('./SyntaxError.cjs'); + +const TAB = 9; +const N = 10; +const F = 12; +const R = 13; +const SPACE = 32; +const NAME_CHAR = new Uint8Array(128).map((_, idx) => + /[a-zA-Z0-9\-]/.test(String.fromCharCode(idx)) ? 1 : 0 +); + +class Scanner { + constructor(str) { + this.str = str; + this.pos = 0; + } + + charCodeAt(pos) { + return pos < this.str.length ? this.str.charCodeAt(pos) : 0; + } + charCode() { + return this.charCodeAt(this.pos); + } + isNameCharCode(code = this.charCode()) { + return code < 128 && NAME_CHAR[code] === 1; + } + nextCharCode() { + return this.charCodeAt(this.pos + 1); + } + nextNonWsCode(pos) { + return this.charCodeAt(this.findWsEnd(pos)); + } + skipWs() { + this.pos = this.findWsEnd(this.pos); + } + findWsEnd(pos) { + for (; pos < this.str.length; pos++) { + const code = this.str.charCodeAt(pos); + if (code !== R && code !== N && code !== F && code !== SPACE && code !== TAB) { + break; + } + } + + return pos; + } + substringToPos(end) { + return this.str.substring(this.pos, this.pos = end); + } + eat(code) { + if (this.charCode() !== code) { + this.error('Expect `' + String.fromCharCode(code) + '`'); + } + + this.pos++; + } + peek() { + return this.pos < this.str.length ? this.str.charAt(this.pos++) : ''; + } + error(message) { + throw new SyntaxError.SyntaxError(message, this.str, this.pos); + } + + scanSpaces() { + return this.substringToPos(this.findWsEnd(this.pos)); + } + scanWord() { + let end = this.pos; + + for (; end < this.str.length; end++) { + const code = this.str.charCodeAt(end); + if (code >= 128 || NAME_CHAR[code] === 0) { + break; + } + } + + if (this.pos === end) { + this.error('Expect a keyword'); + } + + return this.substringToPos(end); + } + scanNumber() { + let end = this.pos; + + for (; end < this.str.length; end++) { + const code = this.str.charCodeAt(end); + + if (code < 48 || code > 57) { + break; + } + } + + if (this.pos === end) { + this.error('Expect a number'); + } + + return this.substringToPos(end); + } + scanString() { + const end = this.str.indexOf('\'', this.pos + 1); + + if (end === -1) { + this.pos = this.str.length; + this.error('Expect an apostrophe'); + } + + return this.substringToPos(end + 1); + } +} + +exports.Scanner = Scanner; diff --git a/vanilla/node_modules/css-tree/cjs/definition-syntax/tokenizer.cjs b/vanilla/node_modules/css-tree/cjs/definition-syntax/tokenizer.cjs new file mode 100644 index 0000000..2b934bd --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/definition-syntax/tokenizer.cjs @@ -0,0 +1,59 @@ +'use strict'; + +const SyntaxError = require('./SyntaxError.cjs'); + +const TAB = 9; +const N = 10; +const F = 12; +const R = 13; +const SPACE = 32; + +class Tokenizer { + constructor(str) { + this.str = str; + this.pos = 0; + } + charCodeAt(pos) { + return pos < this.str.length ? this.str.charCodeAt(pos) : 0; + } + charCode() { + return this.charCodeAt(this.pos); + } + nextCharCode() { + return this.charCodeAt(this.pos + 1); + } + nextNonWsCode(pos) { + return this.charCodeAt(this.findWsEnd(pos)); + } + skipWs() { + this.pos = this.findWsEnd(this.pos); + } + findWsEnd(pos) { + for (; pos < this.str.length; pos++) { + const code = this.str.charCodeAt(pos); + if (code !== R && code !== N && code !== F && code !== SPACE && code !== TAB) { + break; + } + } + + return pos; + } + substringToPos(end) { + return this.str.substring(this.pos, this.pos = end); + } + eat(code) { + if (this.charCode() !== code) { + this.error('Expect `' + String.fromCharCode(code) + '`'); + } + + this.pos++; + } + peek() { + return this.pos < this.str.length ? this.str.charAt(this.pos++) : ''; + } + error(message) { + throw new SyntaxError.SyntaxError(message, this.str, this.pos); + } +} + +exports.Tokenizer = Tokenizer; diff --git a/vanilla/node_modules/css-tree/cjs/definition-syntax/walk.cjs b/vanilla/node_modules/css-tree/cjs/definition-syntax/walk.cjs new file mode 100644 index 0000000..fdba065 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/definition-syntax/walk.cjs @@ -0,0 +1,57 @@ +'use strict'; + +const noop = function() {}; + +function ensureFunction(value) { + return typeof value === 'function' ? value : noop; +} + +function walk(node, options, context) { + function walk(node) { + enter.call(context, node); + + switch (node.type) { + case 'Group': + node.terms.forEach(walk); + break; + + case 'Multiplier': + case 'Boolean': + walk(node.term); + break; + + case 'Type': + case 'Property': + case 'Keyword': + case 'AtKeyword': + case 'Function': + case 'String': + case 'Token': + case 'Comma': + break; + + default: + throw new Error('Unknown type: ' + node.type); + } + + leave.call(context, node); + } + + let enter = noop; + let leave = noop; + + if (typeof options === 'function') { + enter = options; + } else if (options) { + enter = ensureFunction(options.enter); + leave = ensureFunction(options.leave); + } + + if (enter === noop && leave === noop) { + throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function'); + } + + walk(node); +} + +exports.walk = walk; diff --git a/vanilla/node_modules/css-tree/cjs/generator/create.cjs b/vanilla/node_modules/css-tree/cjs/generator/create.cjs new file mode 100644 index 0000000..87a54b2 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/generator/create.cjs @@ -0,0 +1,102 @@ +'use strict'; + +const index = require('../tokenizer/index.cjs'); +const sourceMap = require('./sourceMap.cjs'); +const tokenBefore = require('./token-before.cjs'); +const types = require('../tokenizer/types.cjs'); + +const REVERSESOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\) + +function processChildren(node, delimeter) { + if (typeof delimeter === 'function') { + let prev = null; + + node.children.forEach(node => { + if (prev !== null) { + delimeter.call(this, prev); + } + + this.node(node); + prev = node; + }); + + return; + } + + node.children.forEach(this.node, this); +} + +function processChunk(chunk) { + index.tokenize(chunk, (type, start, end) => { + this.token(type, chunk.slice(start, end)); + }); +} + +function createGenerator(config) { + const types$1 = new Map(); + + for (let [name, item] of Object.entries(config.node)) { + const fn = item.generate || item; + + if (typeof fn === 'function') { + types$1.set(name, item.generate || item); + } + } + + return function(node, options) { + let buffer = ''; + let prevCode = 0; + let handlers = { + node(node) { + if (types$1.has(node.type)) { + types$1.get(node.type).call(publicApi, node); + } else { + throw new Error('Unknown node type: ' + node.type); + } + }, + tokenBefore: tokenBefore.safe, + token(type, value) { + prevCode = this.tokenBefore(prevCode, type, value); + + this.emit(value, type, false); + + if (type === types.Delim && value.charCodeAt(0) === REVERSESOLIDUS) { + this.emit('\n', types.WhiteSpace, true); + } + }, + emit(value) { + buffer += value; + }, + result() { + return buffer; + } + }; + + if (options) { + if (typeof options.decorator === 'function') { + handlers = options.decorator(handlers); + } + + if (options.sourceMap) { + handlers = sourceMap.generateSourceMap(handlers); + } + + if (options.mode in tokenBefore) { + handlers.tokenBefore = tokenBefore[options.mode]; + } + } + + const publicApi = { + node: (node) => handlers.node(node), + children: processChildren, + token: (type, value) => handlers.token(type, value), + tokenize: processChunk + }; + + handlers.node(node); + + return handlers.result(); + }; +} + +exports.createGenerator = createGenerator; diff --git a/vanilla/node_modules/css-tree/cjs/generator/index.cjs b/vanilla/node_modules/css-tree/cjs/generator/index.cjs new file mode 100644 index 0000000..5c87cd3 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/generator/index.cjs @@ -0,0 +1,8 @@ +'use strict'; + +const create = require('./create.cjs'); +const generator = require('../syntax/config/generator.cjs'); + +const index = create.createGenerator(generator); + +module.exports = index; diff --git a/vanilla/node_modules/css-tree/cjs/generator/sourceMap.cjs b/vanilla/node_modules/css-tree/cjs/generator/sourceMap.cjs new file mode 100644 index 0000000..efbc5b9 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/generator/sourceMap.cjs @@ -0,0 +1,96 @@ +'use strict'; + +const sourceMapGenerator_js = require('source-map-js/lib/source-map-generator.js'); + +const trackNodes = new Set(['Atrule', 'Selector', 'Declaration']); + +function generateSourceMap(handlers) { + const map = new sourceMapGenerator_js.SourceMapGenerator(); + const generated = { + line: 1, + column: 0 + }; + const original = { + line: 0, // should be zero to add first mapping + column: 0 + }; + const activatedGenerated = { + line: 1, + column: 0 + }; + const activatedMapping = { + generated: activatedGenerated + }; + let line = 1; + let column = 0; + let sourceMappingActive = false; + + const origHandlersNode = handlers.node; + handlers.node = function(node) { + if (node.loc && node.loc.start && trackNodes.has(node.type)) { + const nodeLine = node.loc.start.line; + const nodeColumn = node.loc.start.column - 1; + + if (original.line !== nodeLine || + original.column !== nodeColumn) { + original.line = nodeLine; + original.column = nodeColumn; + + generated.line = line; + generated.column = column; + + if (sourceMappingActive) { + sourceMappingActive = false; + if (generated.line !== activatedGenerated.line || + generated.column !== activatedGenerated.column) { + map.addMapping(activatedMapping); + } + } + + sourceMappingActive = true; + map.addMapping({ + source: node.loc.source, + original, + generated + }); + } + } + + origHandlersNode.call(this, node); + + if (sourceMappingActive && trackNodes.has(node.type)) { + activatedGenerated.line = line; + activatedGenerated.column = column; + } + }; + + const origHandlersEmit = handlers.emit; + handlers.emit = function(value, type, auto) { + for (let i = 0; i < value.length; i++) { + if (value.charCodeAt(i) === 10) { // \n + line++; + column = 0; + } else { + column++; + } + } + + origHandlersEmit(value, type, auto); + }; + + const origHandlersResult = handlers.result; + handlers.result = function() { + if (sourceMappingActive) { + map.addMapping(activatedMapping); + } + + return { + css: origHandlersResult(), + map + }; + }; + + return handlers; +} + +exports.generateSourceMap = generateSourceMap; diff --git a/vanilla/node_modules/css-tree/cjs/generator/token-before.cjs b/vanilla/node_modules/css-tree/cjs/generator/token-before.cjs new file mode 100644 index 0000000..87bf4a3 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/generator/token-before.cjs @@ -0,0 +1,170 @@ +'use strict'; + +const types = require('../tokenizer/types.cjs'); + +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-) + +const code = (type, value) => { + if (type === types.Delim) { + type = value; + } + + if (typeof type === 'string') { + const charCode = type.charCodeAt(0); + return charCode > 0x7F ? 0x8000 : charCode << 8; + } + + return type; +}; + +// https://www.w3.org/TR/css-syntax-3/#serialization +// The only requirement for serialization is that it must "round-trip" with parsing, +// that is, parsing the stylesheet must produce the same data structures as parsing, +// serializing, and parsing again, except for consecutive s, +// which may be collapsed into a single token. + +const specPairs = [ + [types.Ident, types.Ident], + [types.Ident, types.Function], + [types.Ident, types.Url], + [types.Ident, types.BadUrl], + [types.Ident, '-'], + [types.Ident, types.Number], + [types.Ident, types.Percentage], + [types.Ident, types.Dimension], + [types.Ident, types.CDC], + [types.Ident, types.LeftParenthesis], + + [types.AtKeyword, types.Ident], + [types.AtKeyword, types.Function], + [types.AtKeyword, types.Url], + [types.AtKeyword, types.BadUrl], + [types.AtKeyword, '-'], + [types.AtKeyword, types.Number], + [types.AtKeyword, types.Percentage], + [types.AtKeyword, types.Dimension], + [types.AtKeyword, types.CDC], + + [types.Hash, types.Ident], + [types.Hash, types.Function], + [types.Hash, types.Url], + [types.Hash, types.BadUrl], + [types.Hash, '-'], + [types.Hash, types.Number], + [types.Hash, types.Percentage], + [types.Hash, types.Dimension], + [types.Hash, types.CDC], + + [types.Dimension, types.Ident], + [types.Dimension, types.Function], + [types.Dimension, types.Url], + [types.Dimension, types.BadUrl], + [types.Dimension, '-'], + [types.Dimension, types.Number], + [types.Dimension, types.Percentage], + [types.Dimension, types.Dimension], + [types.Dimension, types.CDC], + + ['#', types.Ident], + ['#', types.Function], + ['#', types.Url], + ['#', types.BadUrl], + ['#', '-'], + ['#', types.Number], + ['#', types.Percentage], + ['#', types.Dimension], + ['#', types.CDC], // https://github.com/w3c/csswg-drafts/pull/6874 + + ['-', types.Ident], + ['-', types.Function], + ['-', types.Url], + ['-', types.BadUrl], + ['-', '-'], + ['-', types.Number], + ['-', types.Percentage], + ['-', types.Dimension], + ['-', types.CDC], // https://github.com/w3c/csswg-drafts/pull/6874 + + [types.Number, types.Ident], + [types.Number, types.Function], + [types.Number, types.Url], + [types.Number, types.BadUrl], + [types.Number, types.Number], + [types.Number, types.Percentage], + [types.Number, types.Dimension], + [types.Number, '%'], + [types.Number, types.CDC], // https://github.com/w3c/csswg-drafts/pull/6874 + + ['@', types.Ident], + ['@', types.Function], + ['@', types.Url], + ['@', types.BadUrl], + ['@', '-'], + ['@', types.CDC], // https://github.com/w3c/csswg-drafts/pull/6874 + + ['.', types.Number], + ['.', types.Percentage], + ['.', types.Dimension], + + ['+', types.Number], + ['+', types.Percentage], + ['+', types.Dimension], + + ['/', '*'] +]; +// validate with scripts/generate-safe +const safePairs = specPairs.concat([ + [types.Ident, types.Hash], + + [types.Dimension, types.Hash], + + [types.Hash, types.Hash], + + [types.AtKeyword, types.LeftParenthesis], + [types.AtKeyword, types.String], + [types.AtKeyword, types.Colon], + + [types.Percentage, types.Percentage], + [types.Percentage, types.Dimension], + [types.Percentage, types.Function], + [types.Percentage, '-'], + + [types.RightParenthesis, types.Ident], + [types.RightParenthesis, types.Function], + [types.RightParenthesis, types.Percentage], + [types.RightParenthesis, types.Dimension], + [types.RightParenthesis, types.Hash], + [types.RightParenthesis, '-'] +]); + +function createMap(pairs) { + const isWhiteSpaceRequired = new Set( + pairs.map(([prev, next]) => (code(prev) << 16 | code(next))) + ); + + return function(prevCode, type, value) { + const nextCode = code(type, value); + const nextCharCode = value.charCodeAt(0); + const emitWs = + (nextCharCode === HYPHENMINUS && + type !== types.Ident && + type !== types.Function && + type !== types.CDC) || + (nextCharCode === PLUSSIGN) + ? isWhiteSpaceRequired.has(prevCode << 16 | nextCharCode << 8) + : isWhiteSpaceRequired.has(prevCode << 16 | nextCode); + + if (emitWs) { + this.emit(' ', types.WhiteSpace, true); + } + + return nextCode; + }; +} + +const spec = createMap(specPairs); +const safe = createMap(safePairs); + +exports.safe = safe; +exports.spec = spec; diff --git a/vanilla/node_modules/css-tree/cjs/index.cjs b/vanilla/node_modules/css-tree/cjs/index.cjs new file mode 100644 index 0000000..cc61137 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/index.cjs @@ -0,0 +1,65 @@ +'use strict'; + +const index$1 = require('./syntax/index.cjs'); +const version = require('./version.cjs'); +const create = require('./syntax/create.cjs'); +const List = require('./utils/List.cjs'); +const Lexer = require('./lexer/Lexer.cjs'); +const index = require('./definition-syntax/index.cjs'); +const clone = require('./utils/clone.cjs'); +const names$1 = require('./utils/names.cjs'); +const ident = require('./utils/ident.cjs'); +const string = require('./utils/string.cjs'); +const url = require('./utils/url.cjs'); +const types = require('./tokenizer/types.cjs'); +const names = require('./tokenizer/names.cjs'); +const TokenStream = require('./tokenizer/TokenStream.cjs'); +const OffsetToLocation = require('./tokenizer/OffsetToLocation.cjs'); + +const { + tokenize, + parse, + generate, + lexer, + createLexer, + + walk, + find, + findLast, + findAll, + + toPlainObject, + fromPlainObject, + + fork +} = index$1; + +exports.version = version.version; +exports.createSyntax = create; +exports.List = List.List; +exports.Lexer = Lexer.Lexer; +exports.definitionSyntax = index; +exports.clone = clone.clone; +exports.isCustomProperty = names$1.isCustomProperty; +exports.keyword = names$1.keyword; +exports.property = names$1.property; +exports.vendorPrefix = names$1.vendorPrefix; +exports.ident = ident; +exports.string = string; +exports.url = url; +exports.tokenTypes = types; +exports.tokenNames = names; +exports.TokenStream = TokenStream.TokenStream; +exports.OffsetToLocation = OffsetToLocation.OffsetToLocation; +exports.createLexer = createLexer; +exports.find = find; +exports.findAll = findAll; +exports.findLast = findLast; +exports.fork = fork; +exports.fromPlainObject = fromPlainObject; +exports.generate = generate; +exports.lexer = lexer; +exports.parse = parse; +exports.toPlainObject = toPlainObject; +exports.tokenize = tokenize; +exports.walk = walk; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/Lexer.cjs b/vanilla/node_modules/css-tree/cjs/lexer/Lexer.cjs new file mode 100644 index 0000000..a6d1fcb --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/Lexer.cjs @@ -0,0 +1,517 @@ +'use strict'; + +const error = require('./error.cjs'); +const names = require('../utils/names.cjs'); +const genericConst = require('./generic-const.cjs'); +const generic = require('./generic.cjs'); +const units = require('./units.cjs'); +const prepareTokens = require('./prepare-tokens.cjs'); +const matchGraph = require('./match-graph.cjs'); +const match = require('./match.cjs'); +const trace = require('./trace.cjs'); +const search = require('./search.cjs'); +const structure = require('./structure.cjs'); +const parse = require('../definition-syntax/parse.cjs'); +const generate = require('../definition-syntax/generate.cjs'); +const walk = require('../definition-syntax/walk.cjs'); + +function dumpMapSyntax(map, compact, syntaxAsAst) { + const result = {}; + + for (const name in map) { + if (map[name].syntax) { + result[name] = syntaxAsAst + ? map[name].syntax + : generate.generate(map[name].syntax, { compact }); + } + } + + return result; +} + +function dumpAtruleMapSyntax(map, compact, syntaxAsAst) { + const result = {}; + + for (const [name, atrule] of Object.entries(map)) { + result[name] = { + prelude: atrule.prelude && ( + syntaxAsAst + ? atrule.prelude.syntax + : generate.generate(atrule.prelude.syntax, { compact }) + ), + descriptors: atrule.descriptors && dumpMapSyntax(atrule.descriptors, compact, syntaxAsAst) + }; + } + + return result; +} + +function valueHasVar(tokens) { + for (let i = 0; i < tokens.length; i++) { + if (tokens[i].value.toLowerCase() === 'var(') { + return true; + } + } + + return false; +} + +function syntaxHasTopLevelCommaMultiplier(syntax) { + const singleTerm = syntax.terms[0]; + + return ( + syntax.explicit === false && + syntax.terms.length === 1 && + singleTerm.type === 'Multiplier' && + singleTerm.comma === true + ); +} + +function buildMatchResult(matched, error, iterations) { + return { + matched, + iterations, + error, + ...trace + }; +} + +function matchSyntax(lexer, syntax, value, useCssWideKeywords) { + const tokens = prepareTokens(value, lexer.syntax); + let result; + + if (valueHasVar(tokens)) { + return buildMatchResult(null, new Error('Matching for a tree with var() is not supported')); + } + + if (useCssWideKeywords) { + result = match.matchAsTree(tokens, lexer.cssWideKeywordsSyntax, lexer); + } + + if (!useCssWideKeywords || !result.match) { + result = match.matchAsTree(tokens, syntax.match, lexer); + if (!result.match) { + return buildMatchResult( + null, + new error.SyntaxMatchError(result.reason, syntax.syntax, value, result), + result.iterations + ); + } + } + + return buildMatchResult(result.match, null, result.iterations); +} + +class Lexer { + constructor(config, syntax, structure$1) { + this.cssWideKeywords = genericConst.cssWideKeywords; + this.syntax = syntax; + this.generic = false; + this.units = { ...units }; + this.atrules = Object.create(null); + this.properties = Object.create(null); + this.types = Object.create(null); + this.structure = structure$1 || structure.getStructureFromConfig(config); + + if (config) { + if (config.cssWideKeywords) { + this.cssWideKeywords = config.cssWideKeywords; + } + + if (config.units) { + for (const group of Object.keys(units)) { + if (Array.isArray(config.units[group])) { + this.units[group] = config.units[group]; + } + } + } + + if (config.types) { + for (const [name, type] of Object.entries(config.types)) { + this.addType_(name, type); + } + } + + if (config.generic) { + this.generic = true; + for (const [name, value] of Object.entries(generic.createGenericTypes(this.units))) { + this.addType_(name, value); + } + } + + if (config.atrules) { + for (const [name, atrule] of Object.entries(config.atrules)) { + this.addAtrule_(name, atrule); + } + } + + if (config.properties) { + for (const [name, property] of Object.entries(config.properties)) { + this.addProperty_(name, property); + } + } + } + + this.cssWideKeywordsSyntax = matchGraph.buildMatchGraph(this.cssWideKeywords.join(' | ')); + } + + checkStructure(ast) { + function collectWarning(node, message) { + warns.push({ node, message }); + } + + const structure = this.structure; + const warns = []; + + this.syntax.walk(ast, function(node) { + if (structure.hasOwnProperty(node.type)) { + structure[node.type].check(node, collectWarning); + } else { + collectWarning(node, 'Unknown node type `' + node.type + '`'); + } + }); + + return warns.length ? warns : false; + } + + createDescriptor(syntax, type, name, parent = null) { + const ref = { + type, + name + }; + const descriptor = { + type, + name, + parent, + serializable: typeof syntax === 'string' || (syntax && typeof syntax.type === 'string'), + syntax: null, + match: null, + matchRef: null // used for properties when a syntax referenced as <'property'> in other syntax definitions + }; + + if (typeof syntax === 'function') { + descriptor.match = matchGraph.buildMatchGraph(syntax, ref); + } else { + if (typeof syntax === 'string') { + // lazy parsing on first access + Object.defineProperty(descriptor, 'syntax', { + get() { + Object.defineProperty(descriptor, 'syntax', { + value: parse.parse(syntax) + }); + + return descriptor.syntax; + } + }); + } else { + descriptor.syntax = syntax; + } + + // lazy graph build on first access + Object.defineProperty(descriptor, 'match', { + get() { + Object.defineProperty(descriptor, 'match', { + value: matchGraph.buildMatchGraph(descriptor.syntax, ref) + }); + + return descriptor.match; + } + }); + + if (type === 'Property') { + Object.defineProperty(descriptor, 'matchRef', { + get() { + const syntax = descriptor.syntax; + const value = syntaxHasTopLevelCommaMultiplier(syntax) + ? matchGraph.buildMatchGraph({ + ...syntax, + terms: [syntax.terms[0].term] + }, ref) + : null; + + Object.defineProperty(descriptor, 'matchRef', { + value + }); + + return value; + } + }); + } + } + + return descriptor; + } + addAtrule_(name, syntax) { + if (!syntax) { + return; + } + + this.atrules[name] = { + type: 'Atrule', + name: name, + prelude: syntax.prelude ? this.createDescriptor(syntax.prelude, 'AtrulePrelude', name) : null, + descriptors: syntax.descriptors + ? Object.keys(syntax.descriptors).reduce( + (map, descName) => { + map[descName] = this.createDescriptor(syntax.descriptors[descName], 'AtruleDescriptor', descName, name); + return map; + }, + Object.create(null) + ) + : null + }; + } + addProperty_(name, syntax) { + if (!syntax) { + return; + } + + this.properties[name] = this.createDescriptor(syntax, 'Property', name); + } + addType_(name, syntax) { + if (!syntax) { + return; + } + + this.types[name] = this.createDescriptor(syntax, 'Type', name); + } + + checkAtruleName(atruleName) { + if (!this.getAtrule(atruleName)) { + return new error.SyntaxReferenceError('Unknown at-rule', '@' + atruleName); + } + } + checkAtrulePrelude(atruleName, prelude) { + const error = this.checkAtruleName(atruleName); + + if (error) { + return error; + } + + const atrule = this.getAtrule(atruleName); + + if (!atrule.prelude && prelude) { + return new SyntaxError('At-rule `@' + atruleName + '` should not contain a prelude'); + } + + if (atrule.prelude && !prelude) { + if (!matchSyntax(this, atrule.prelude, '', false).matched) { + return new SyntaxError('At-rule `@' + atruleName + '` should contain a prelude'); + } + } + } + checkAtruleDescriptorName(atruleName, descriptorName) { + const error$1 = this.checkAtruleName(atruleName); + + if (error$1) { + return error$1; + } + + const atrule = this.getAtrule(atruleName); + const descriptor = names.keyword(descriptorName); + + if (!atrule.descriptors) { + return new SyntaxError('At-rule `@' + atruleName + '` has no known descriptors'); + } + + if (!atrule.descriptors[descriptor.name] && + !atrule.descriptors[descriptor.basename]) { + return new error.SyntaxReferenceError('Unknown at-rule descriptor', descriptorName); + } + } + checkPropertyName(propertyName) { + if (!this.getProperty(propertyName)) { + return new error.SyntaxReferenceError('Unknown property', propertyName); + } + } + + matchAtrulePrelude(atruleName, prelude) { + const error = this.checkAtrulePrelude(atruleName, prelude); + + if (error) { + return buildMatchResult(null, error); + } + + const atrule = this.getAtrule(atruleName); + + if (!atrule.prelude) { + return buildMatchResult(null, null); + } + + return matchSyntax(this, atrule.prelude, prelude || '', false); + } + matchAtruleDescriptor(atruleName, descriptorName, value) { + const error = this.checkAtruleDescriptorName(atruleName, descriptorName); + + if (error) { + return buildMatchResult(null, error); + } + + const atrule = this.getAtrule(atruleName); + const descriptor = names.keyword(descriptorName); + + return matchSyntax(this, atrule.descriptors[descriptor.name] || atrule.descriptors[descriptor.basename], value, false); + } + matchDeclaration(node) { + if (node.type !== 'Declaration') { + return buildMatchResult(null, new Error('Not a Declaration node')); + } + + return this.matchProperty(node.property, node.value); + } + matchProperty(propertyName, value) { + // don't match syntax for a custom property at the moment + if (names.property(propertyName).custom) { + return buildMatchResult(null, new Error('Lexer matching doesn\'t applicable for custom properties')); + } + + const error = this.checkPropertyName(propertyName); + + if (error) { + return buildMatchResult(null, error); + } + + return matchSyntax(this, this.getProperty(propertyName), value, true); + } + matchType(typeName, value) { + const typeSyntax = this.getType(typeName); + + if (!typeSyntax) { + return buildMatchResult(null, new error.SyntaxReferenceError('Unknown type', typeName)); + } + + return matchSyntax(this, typeSyntax, value, false); + } + match(syntax, value) { + if (typeof syntax !== 'string' && (!syntax || !syntax.type)) { + return buildMatchResult(null, new error.SyntaxReferenceError('Bad syntax')); + } + + if (typeof syntax === 'string' || !syntax.match) { + syntax = this.createDescriptor(syntax, 'Type', 'anonymous'); + } + + return matchSyntax(this, syntax, value, false); + } + + findValueFragments(propertyName, value, type, name) { + return search.matchFragments(this, value, this.matchProperty(propertyName, value), type, name); + } + findDeclarationValueFragments(declaration, type, name) { + return search.matchFragments(this, declaration.value, this.matchDeclaration(declaration), type, name); + } + findAllFragments(ast, type, name) { + const result = []; + + this.syntax.walk(ast, { + visit: 'Declaration', + enter: (declaration) => { + result.push.apply(result, this.findDeclarationValueFragments(declaration, type, name)); + } + }); + + return result; + } + + getAtrule(atruleName, fallbackBasename = true) { + const atrule = names.keyword(atruleName); + const atruleEntry = atrule.vendor && fallbackBasename + ? this.atrules[atrule.name] || this.atrules[atrule.basename] + : this.atrules[atrule.name]; + + return atruleEntry || null; + } + getAtrulePrelude(atruleName, fallbackBasename = true) { + const atrule = this.getAtrule(atruleName, fallbackBasename); + + return atrule && atrule.prelude || null; + } + getAtruleDescriptor(atruleName, name) { + return this.atrules.hasOwnProperty(atruleName) && this.atrules.declarators + ? this.atrules[atruleName].declarators[name] || null + : null; + } + getProperty(propertyName, fallbackBasename = true) { + const property = names.property(propertyName); + const propertyEntry = property.vendor && fallbackBasename + ? this.properties[property.name] || this.properties[property.basename] + : this.properties[property.name]; + + return propertyEntry || null; + } + getType(name) { + return hasOwnProperty.call(this.types, name) ? this.types[name] : null; + } + + validate() { + function syntaxRef(name, isType) { + return isType ? `<${name}>` : `<'${name}'>`; + } + + function validate(syntax, name, broken, descriptor) { + if (broken.has(name)) { + return broken.get(name); + } + + broken.set(name, false); + if (descriptor.syntax !== null) { + walk.walk(descriptor.syntax, function(node) { + if (node.type !== 'Type' && node.type !== 'Property') { + return; + } + + const map = node.type === 'Type' ? syntax.types : syntax.properties; + const brokenMap = node.type === 'Type' ? brokenTypes : brokenProperties; + + if (!hasOwnProperty.call(map, node.name)) { + errors.push(`${syntaxRef(name, broken === brokenTypes)} used missed syntax definition ${syntaxRef(node.name, node.type === 'Type')}`); + broken.set(name, true); + } else if (validate(syntax, node.name, brokenMap, map[node.name])) { + errors.push(`${syntaxRef(name, broken === brokenTypes)} used broken syntax definition ${syntaxRef(node.name, node.type === 'Type')}`); + broken.set(name, true); + } + }, this); + } + } + + const errors = []; + let brokenTypes = new Map(); + let brokenProperties = new Map(); + + for (const key in this.types) { + validate(this, key, brokenTypes, this.types[key]); + } + + for (const key in this.properties) { + validate(this, key, brokenProperties, this.properties[key]); + } + + const brokenTypesArray = [...brokenTypes.keys()].filter(name => brokenTypes.get(name)); + const brokenPropertiesArray = [...brokenProperties.keys()].filter(name => brokenProperties.get(name)); + + if (brokenTypesArray.length || brokenPropertiesArray.length) { + return { + errors, + types: brokenTypesArray, + properties: brokenPropertiesArray + }; + } + + return null; + } + dump(syntaxAsAst, pretty) { + return { + generic: this.generic, + cssWideKeywords: this.cssWideKeywords, + units: this.units, + types: dumpMapSyntax(this.types, !pretty, syntaxAsAst), + properties: dumpMapSyntax(this.properties, !pretty, syntaxAsAst), + atrules: dumpAtruleMapSyntax(this.atrules, !pretty, syntaxAsAst) + }; + } + toString() { + return JSON.stringify(this.dump()); + } +} + +exports.Lexer = Lexer; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/error.cjs b/vanilla/node_modules/css-tree/cjs/lexer/error.cjs new file mode 100644 index 0000000..8d252ee --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/error.cjs @@ -0,0 +1,128 @@ +'use strict'; + +const createCustomError = require('../utils/create-custom-error.cjs'); +const generate = require('../definition-syntax/generate.cjs'); + +const defaultLoc = { offset: 0, line: 1, column: 1 }; + +function locateMismatch(matchResult, node) { + const tokens = matchResult.tokens; + const longestMatch = matchResult.longestMatch; + const mismatchNode = longestMatch < tokens.length ? tokens[longestMatch].node || null : null; + const badNode = mismatchNode !== node ? mismatchNode : null; + let mismatchOffset = 0; + let mismatchLength = 0; + let entries = 0; + let css = ''; + let start; + let end; + + for (let i = 0; i < tokens.length; i++) { + const token = tokens[i].value; + + if (i === longestMatch) { + mismatchLength = token.length; + mismatchOffset = css.length; + } + + if (badNode !== null && tokens[i].node === badNode) { + if (i <= longestMatch) { + entries++; + } else { + entries = 0; + } + } + + css += token; + } + + if (longestMatch === tokens.length || entries > 1) { // last + start = fromLoc(badNode || node, 'end') || buildLoc(defaultLoc, css); + end = buildLoc(start); + } else { + start = fromLoc(badNode, 'start') || + buildLoc(fromLoc(node, 'start') || defaultLoc, css.slice(0, mismatchOffset)); + end = fromLoc(badNode, 'end') || + buildLoc(start, css.substr(mismatchOffset, mismatchLength)); + } + + return { + css, + mismatchOffset, + mismatchLength, + start, + end + }; +} + +function fromLoc(node, point) { + const value = node && node.loc && node.loc[point]; + + if (value) { + return 'line' in value ? buildLoc(value) : value; + } + + return null; +} + +function buildLoc({ offset, line, column }, extra) { + const loc = { + offset, + line, + column + }; + + if (extra) { + const lines = extra.split(/\n|\r\n?|\f/); + + loc.offset += extra.length; + loc.line += lines.length - 1; + loc.column = lines.length === 1 ? loc.column + extra.length : lines.pop().length + 1; + } + + return loc; +} + +const SyntaxReferenceError = function(type, referenceName) { + const error = createCustomError.createCustomError( + 'SyntaxReferenceError', + type + (referenceName ? ' `' + referenceName + '`' : '') + ); + + error.reference = referenceName; + + return error; +}; + +const SyntaxMatchError = function(message, syntax, node, matchResult) { + const error = createCustomError.createCustomError('SyntaxMatchError', message); + const { + css, + mismatchOffset, + mismatchLength, + start, + end + } = locateMismatch(matchResult, node); + + error.rawMessage = message; + error.syntax = syntax ? generate.generate(syntax) : ''; + error.css = css; + error.mismatchOffset = mismatchOffset; + error.mismatchLength = mismatchLength; + error.message = message + '\n' + + ' syntax: ' + error.syntax + '\n' + + ' value: ' + (css || '') + '\n' + + ' --------' + new Array(error.mismatchOffset + 1).join('-') + '^'; + + Object.assign(error, start); + error.loc = { + source: (node && node.loc && node.loc.source) || '', + start, + end + }; + + return error; +}; + +exports.SyntaxMatchError = SyntaxMatchError; +exports.SyntaxReferenceError = SyntaxReferenceError; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/generic-an-plus-b.cjs b/vanilla/node_modules/css-tree/cjs/lexer/generic-an-plus-b.cjs new file mode 100644 index 0000000..a5dfba3 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/generic-an-plus-b.cjs @@ -0,0 +1,235 @@ +'use strict'; + +const charCodeDefinitions = require('../tokenizer/char-code-definitions.cjs'); +const types = require('../tokenizer/types.cjs'); +const utils = require('../tokenizer/utils.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 isDelim(token, code) { + return token !== null && token.type === types.Delim && token.value.charCodeAt(0) === code; +} + +function skipSC(token, offset, getNextToken) { + while (token !== null && (token.type === types.WhiteSpace || token.type === types.Comment)) { + token = getNextToken(++offset); + } + + return offset; +} + +function checkInteger(token, valueOffset, disallowSign, offset) { + if (!token) { + return 0; + } + + const code = token.value.charCodeAt(valueOffset); + + if (code === PLUSSIGN || code === HYPHENMINUS) { + if (disallowSign) { + // Number sign is not allowed + return 0; + } + valueOffset++; + } + + for (; valueOffset < token.value.length; valueOffset++) { + if (!charCodeDefinitions.isDigit(token.value.charCodeAt(valueOffset))) { + // Integer is expected + return 0; + } + } + + return offset + 1; +} + +// ... +// ... ['+' | '-'] +function consumeB(token, offset_, getNextToken) { + let sign = false; + let offset = skipSC(token, offset_, getNextToken); + + token = getNextToken(offset); + + if (token === null) { + return offset_; + } + + if (token.type !== types.Number) { + if (isDelim(token, PLUSSIGN) || isDelim(token, HYPHENMINUS)) { + sign = true; + offset = skipSC(getNextToken(++offset), offset, getNextToken); + token = getNextToken(offset); + + if (token === null || token.type !== types.Number) { + return 0; + } + } else { + return offset_; + } + } + + if (!sign) { + const code = token.value.charCodeAt(0); + if (code !== PLUSSIGN && code !== HYPHENMINUS) { + // Number sign is expected + return 0; + } + } + + return checkInteger(token, sign ? 0 : 1, sign, offset); +} + +// An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb +function anPlusB(token, getNextToken) { + /* eslint-disable brace-style*/ + let offset = 0; + + if (!token) { + return 0; + } + + // + if (token.type === types.Number) { + return checkInteger(token, 0, ALLOW_SIGN, offset); // b + } + + // -n + // -n + // -n ['+' | '-'] + // -n- + // + else if (token.type === types.Ident && token.value.charCodeAt(0) === HYPHENMINUS) { + // expect 1st char is N + if (!utils.cmpChar(token.value, 1, N)) { + return 0; + } + + switch (token.value.length) { + // -n + // -n + // -n ['+' | '-'] + case 2: + return consumeB(getNextToken(++offset), offset, getNextToken); + + // -n- + case 3: + if (token.value.charCodeAt(2) !== HYPHENMINUS) { + return 0; + } + + offset = skipSC(getNextToken(++offset), offset, getNextToken); + token = getNextToken(offset); + + return checkInteger(token, 0, DISALLOW_SIGN, offset); + + // + default: + if (token.value.charCodeAt(2) !== HYPHENMINUS) { + return 0; + } + + return checkInteger(token, 3, DISALLOW_SIGN, offset); + } + } + + // '+'? n + // '+'? n + // '+'? n ['+' | '-'] + // '+'? n- + // '+'? + else if (token.type === types.Ident || (isDelim(token, PLUSSIGN) && getNextToken(offset + 1).type === types.Ident)) { + // just ignore a plus + if (token.type !== types.Ident) { + token = getNextToken(++offset); + } + + if (token === null || !utils.cmpChar(token.value, 0, N)) { + return 0; + } + + switch (token.value.length) { + // '+'? n + // '+'? n + // '+'? n ['+' | '-'] + case 1: + return consumeB(getNextToken(++offset), offset, getNextToken); + + // '+'? n- + case 2: + if (token.value.charCodeAt(1) !== HYPHENMINUS) { + return 0; + } + + offset = skipSC(getNextToken(++offset), offset, getNextToken); + token = getNextToken(offset); + + return checkInteger(token, 0, DISALLOW_SIGN, offset); + + // '+'? + default: + if (token.value.charCodeAt(1) !== HYPHENMINUS) { + return 0; + } + + return checkInteger(token, 2, DISALLOW_SIGN, offset); + } + } + + // + // + // + // + // ['+' | '-'] + else if (token.type === types.Dimension) { + let code = token.value.charCodeAt(0); + let sign = code === PLUSSIGN || code === HYPHENMINUS ? 1 : 0; + let i = sign; + + for (; i < token.value.length; i++) { + if (!charCodeDefinitions.isDigit(token.value.charCodeAt(i))) { + break; + } + } + + if (i === sign) { + // Integer is expected + return 0; + } + + if (!utils.cmpChar(token.value, i, N)) { + return 0; + } + + // + // + // ['+' | '-'] + if (i + 1 === token.value.length) { + return consumeB(getNextToken(++offset), offset, getNextToken); + } else { + if (token.value.charCodeAt(i + 1) !== HYPHENMINUS) { + return 0; + } + + // + if (i + 2 === token.value.length) { + offset = skipSC(getNextToken(++offset), offset, getNextToken); + token = getNextToken(offset); + + return checkInteger(token, 0, DISALLOW_SIGN, offset); + } + // + else { + return checkInteger(token, i + 2, DISALLOW_SIGN, offset); + } + } + } + + return 0; +} + +module.exports = anPlusB; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/generic-const.cjs b/vanilla/node_modules/css-tree/cjs/lexer/generic-const.cjs new file mode 100644 index 0000000..9b9f615 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/generic-const.cjs @@ -0,0 +1,12 @@ +'use strict'; + +// https://drafts.csswg.org/css-cascade-5/ +const cssWideKeywords = [ + 'initial', + 'inherit', + 'unset', + 'revert', + 'revert-layer' +]; + +exports.cssWideKeywords = cssWideKeywords; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/generic-urange.cjs b/vanilla/node_modules/css-tree/cjs/lexer/generic-urange.cjs new file mode 100644 index 0000000..ce167bb --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/generic-urange.cjs @@ -0,0 +1,149 @@ +'use strict'; + +const charCodeDefinitions = require('../tokenizer/char-code-definitions.cjs'); +const types = require('../tokenizer/types.cjs'); +const utils = require('../tokenizer/utils.cjs'); + +const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) +const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-) +const QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?) +const U = 0x0075; // U+0075 LATIN SMALL LETTER U (u) + +function isDelim(token, code) { + return token !== null && token.type === types.Delim && token.value.charCodeAt(0) === code; +} + +function startsWith(token, code) { + return token.value.charCodeAt(0) === code; +} + +function hexSequence(token, offset, allowDash) { + let hexlen = 0; + + for (let pos = offset; pos < token.value.length; pos++) { + const code = token.value.charCodeAt(pos); + + if (code === HYPHENMINUS && allowDash && hexlen !== 0) { + hexSequence(token, offset + hexlen + 1, false); + return 6; // dissallow following question marks + } + + if (!charCodeDefinitions.isHexDigit(code)) { + return 0; // not a hex digit + } + + if (++hexlen > 6) { + return 0; // too many hex digits + } } + + return hexlen; +} + +function withQuestionMarkSequence(consumed, length, getNextToken) { + if (!consumed) { + return 0; // nothing consumed + } + + while (isDelim(getNextToken(length), QUESTIONMARK)) { + if (++consumed > 6) { + return 0; // too many question marks + } + + length++; + } + + return length; +} + +// https://drafts.csswg.org/css-syntax/#urange +// Informally, the 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). +// +// = +// u '+' '?'* | +// u '?'* | +// u '?'* | +// u | +// u | +// u '+' '?'+ +function urange(token, getNextToken) { + let length = 0; + + // should start with `u` or `U` + if (token === null || token.type !== types.Ident || !utils.cmpChar(token.value, 0, U)) { + return 0; + } + + token = getNextToken(++length); + if (token === null) { + return 0; + } + + // u '+' '?'* + // u '+' '?'+ + if (isDelim(token, PLUSSIGN)) { + token = getNextToken(++length); + if (token === null) { + return 0; + } + + if (token.type === types.Ident) { + // u '+' '?'* + return withQuestionMarkSequence(hexSequence(token, 0, true), ++length, getNextToken); + } + + if (isDelim(token, QUESTIONMARK)) { + // u '+' '?'+ + return withQuestionMarkSequence(1, ++length, getNextToken); + } + + // Hex digit or question mark is expected + return 0; + } + + // u '?'* + // u + // u + if (token.type === types.Number) { + const consumedHexLength = hexSequence(token, 1, true); + if (consumedHexLength === 0) { + return 0; + } + + token = getNextToken(++length); + if (token === null) { + // u + return length; + } + + if (token.type === types.Dimension || token.type === types.Number) { + // u + // u + if (!startsWith(token, HYPHENMINUS) || !hexSequence(token, 1, false)) { + return 0; + } + + return length + 1; + } + + // u '?'* + return withQuestionMarkSequence(consumedHexLength, length, getNextToken); + } + + // u '?'* + if (token.type === types.Dimension) { + return withQuestionMarkSequence(hexSequence(token, 1, true), ++length, getNextToken); + } + + return 0; +} + +module.exports = urange; diff --git a/vanilla/node_modules/css-tree/cjs/lexer/generic.cjs b/vanilla/node_modules/css-tree/cjs/lexer/generic.cjs new file mode 100644 index 0000000..8489911 --- /dev/null +++ b/vanilla/node_modules/css-tree/cjs/lexer/generic.cjs @@ -0,0 +1,589 @@ +'use strict'; + +const genericConst = require('./generic-const.cjs'); +const genericAnPlusB = require('./generic-an-plus-b.cjs'); +const genericUrange = require('./generic-urange.cjs'); +const charCodeDefinitions = require('../tokenizer/char-code-definitions.cjs'); +const types = require('../tokenizer/types.cjs'); +const utils = require('../tokenizer/utils.cjs'); + +const calcFunctionNames = ['calc(', '-moz-calc(', '-webkit-calc(']; +const balancePair = new Map([ + [types.Function, types.RightParenthesis], + [types.LeftParenthesis, types.RightParenthesis], + [types.LeftSquareBracket, types.RightSquareBracket], + [types.LeftCurlyBracket, types.RightCurlyBracket] +]); + +// safe char code getter +function charCodeAt(str, index) { + return index < str.length ? str.charCodeAt(index) : 0; +} + +function eqStr(actual, expected) { + return utils.cmpStr(actual, 0, actual.length, expected); +} + +function eqStrAny(actual, expected) { + for (let i = 0; i < expected.length; i++) { + if (eqStr(actual, expected[i])) { + return true; + } + } + + return false; +} + +// IE postfix hack, i.e. 123\0 or 123px\9 +function isPostfixIeHack(str, offset) { + if (offset !== str.length - 2) { + return false; + } + + return ( + charCodeAt(str, offset) === 0x005C && // U+005C REVERSE SOLIDUS (\) + charCodeDefinitions.isDigit(charCodeAt(str, offset + 1)) + ); +} + +function outOfRange(opts, value, numEnd) { + if (opts && opts.type === 'Range') { + const num = Number( + numEnd !== undefined && numEnd !== value.length + ? value.substr(0, numEnd) + : value + ); + + if (isNaN(num)) { + return true; + } + + // FIXME: when opts.min is a string it's a dimension, skip a range validation + // for now since it requires a type covertation which is not implmented yet + if (opts.min !== null && num < opts.min && typeof opts.min !== 'string') { + return true; + } + + // FIXME: when opts.max is a string it's a dimension, skip a range validation + // for now since it requires a type covertation which is not implmented yet + if (opts.max !== null && num > opts.max && typeof opts.max !== 'string') { + return true; + } + } + + return false; +} + +function consumeFunction(token, getNextToken) { + let balanceCloseType = 0; + let balanceStash = []; + let length = 0; + + // balanced token consuming + scan: + do { + switch (token.type) { + case types.RightCurlyBracket: + case types.RightParenthesis: + case types.RightSquareBracket: + if (token.type !== balanceCloseType) { + break scan; + } + + balanceCloseType = balanceStash.pop(); + + if (balanceStash.length === 0) { + length++; + break scan; + } + + break; + + case types.Function: + case types.LeftParenthesis: + case types.LeftSquareBracket: + case types.LeftCurlyBracket: + balanceStash.push(balanceCloseType); + balanceCloseType = balancePair.get(token.type); + break; + } + + length++; + } while (token = getNextToken(length)); + + return length; +} + +// TODO: implement +// can be used wherever , , ,