aboutsummaryrefslogtreecommitdiffstats
path: root/vanilla/node_modules/css-tree/cjs/generator
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-13 21:34:48 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-13 21:34:48 -0800
commit76cb9c2a39d477a64824a985ade40507e3bbade1 (patch)
tree41e997aa9c6f538d3a136af61dae9424db2005a9 /vanilla/node_modules/css-tree/cjs/generator
parent819a39a21ac992b1393244a4c283bbb125208c69 (diff)
downloadneko-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/generator')
-rw-r--r--vanilla/node_modules/css-tree/cjs/generator/create.cjs102
-rw-r--r--vanilla/node_modules/css-tree/cjs/generator/index.cjs8
-rw-r--r--vanilla/node_modules/css-tree/cjs/generator/sourceMap.cjs96
-rw-r--r--vanilla/node_modules/css-tree/cjs/generator/token-before.cjs170
4 files changed, 376 insertions, 0 deletions
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 <whitespace-token>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;