Files
rspade_system/node_modules/css-tree/lib/walker/create.js
root d523f0f600 Fix code quality violations and exclude Manifest from checks
Document application modes (development/debug/production)
Add global file drop handler, order column normalization, SPA hash fix
Serve CDN assets via /_vendor/ URLs instead of merging into bundles
Add production minification with license preservation
Improve JSON formatting for debugging and production optimization
Add CDN asset caching with CSS URL inlining for production builds
Add three-mode system (development, debug, production)
Update Manifest CLAUDE.md to reflect helper class architecture
Refactor Manifest.php into helper classes for better organization
Pre-manifest-refactor checkpoint: Add app_mode documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-14 10:38:22 +00:00

288 lines
7.3 KiB
JavaScript
Executable File

const { hasOwnProperty } = Object.prototype;
const noop = function() {};
function ensureFunction(value) {
return typeof value === 'function' ? value : noop;
}
function invokeForType(fn, type) {
return function(node, item, list) {
if (node.type === type) {
fn.call(this, node, item, list);
}
};
}
function getWalkersFromStructure(name, nodeType) {
const structure = nodeType.structure;
const walkers = [];
for (const key in structure) {
if (hasOwnProperty.call(structure, key) === false) {
continue;
}
let fieldTypes = structure[key];
const walker = {
name: key,
type: false,
nullable: false
};
if (!Array.isArray(fieldTypes)) {
fieldTypes = [fieldTypes];
}
for (const fieldType of fieldTypes) {
if (fieldType === null) {
walker.nullable = true;
} else if (typeof fieldType === 'string') {
walker.type = 'node';
} else if (Array.isArray(fieldType)) {
walker.type = 'list';
}
}
if (walker.type) {
walkers.push(walker);
}
}
if (walkers.length) {
return {
context: nodeType.walkContext,
fields: walkers
};
}
return null;
}
function getTypesFromConfig(config) {
const types = {};
for (const name in config.node) {
if (hasOwnProperty.call(config.node, name)) {
const nodeType = config.node[name];
if (!nodeType.structure) {
throw new Error('Missed `structure` field in `' + name + '` node type definition');
}
types[name] = getWalkersFromStructure(name, nodeType);
}
}
return types;
}
function createTypeIterator(config, reverse) {
const fields = config.fields.slice();
const contextName = config.context;
const useContext = typeof contextName === 'string';
if (reverse) {
fields.reverse();
}
return function(node, context, walk, walkReducer) {
let prevContextValue;
if (useContext) {
prevContextValue = context[contextName];
context[contextName] = node;
}
for (const field of fields) {
const ref = node[field.name];
if (!field.nullable || ref) {
if (field.type === 'list') {
const breakWalk = reverse
? ref.reduceRight(walkReducer, false)
: ref.reduce(walkReducer, false);
if (breakWalk) {
return true;
}
} else if (walk(ref)) {
return true;
}
}
}
if (useContext) {
context[contextName] = prevContextValue;
}
};
}
function createFastTraveralMap({
StyleSheet,
Atrule,
Rule,
Block,
DeclarationList
}) {
return {
Atrule: {
StyleSheet,
Atrule,
Rule,
Block
},
Rule: {
StyleSheet,
Atrule,
Rule,
Block
},
Declaration: {
StyleSheet,
Atrule,
Rule,
Block,
DeclarationList
}
};
}
export function createWalker(config) {
const types = getTypesFromConfig(config);
const iteratorsNatural = {};
const iteratorsReverse = {};
const breakWalk = Symbol('break-walk');
const skipNode = Symbol('skip-node');
for (const name in types) {
if (hasOwnProperty.call(types, name) && types[name] !== null) {
iteratorsNatural[name] = createTypeIterator(types[name], false);
iteratorsReverse[name] = createTypeIterator(types[name], true);
}
}
const fastTraversalIteratorsNatural = createFastTraveralMap(iteratorsNatural);
const fastTraversalIteratorsReverse = createFastTraveralMap(iteratorsReverse);
const walk = function(root, options) {
function walkNode(node, item, list) {
const enterRet = enter.call(context, node, item, list);
if (enterRet === breakWalk) {
return true;
}
if (enterRet === skipNode) {
return false;
}
if (iterators.hasOwnProperty(node.type)) {
if (iterators[node.type](node, context, walkNode, walkReducer)) {
return true;
}
}
if (leave.call(context, node, item, list) === breakWalk) {
return true;
}
return false;
}
let enter = noop;
let leave = noop;
let iterators = iteratorsNatural;
let walkReducer = (ret, data, item, list) => ret || walkNode(data, item, list);
const context = {
break: breakWalk,
skip: skipNode,
root,
stylesheet: null,
atrule: null,
atrulePrelude: null,
rule: null,
selector: null,
block: null,
declaration: null,
function: null
};
if (typeof options === 'function') {
enter = options;
} else if (options) {
enter = ensureFunction(options.enter);
leave = ensureFunction(options.leave);
if (options.reverse) {
iterators = iteratorsReverse;
}
if (options.visit) {
if (fastTraversalIteratorsNatural.hasOwnProperty(options.visit)) {
iterators = options.reverse
? fastTraversalIteratorsReverse[options.visit]
: fastTraversalIteratorsNatural[options.visit];
} else if (!types.hasOwnProperty(options.visit)) {
throw new Error('Bad value `' + options.visit + '` for `visit` option (should be: ' + Object.keys(types).sort().join(', ') + ')');
}
enter = invokeForType(enter, options.visit);
leave = invokeForType(leave, options.visit);
}
}
if (enter === noop && leave === noop) {
throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
}
walkNode(root);
};
walk.break = breakWalk;
walk.skip = skipNode;
walk.find = function(ast, fn) {
let found = null;
walk(ast, function(node, item, list) {
if (fn.call(this, node, item, list)) {
found = node;
return breakWalk;
}
});
return found;
};
walk.findLast = function(ast, fn) {
let found = null;
walk(ast, {
reverse: true,
enter(node, item, list) {
if (fn.call(this, node, item, list)) {
found = node;
return breakWalk;
}
}
});
return found;
};
walk.findAll = function(ast, fn) {
const found = [];
walk(ast, function(node, item, list) {
if (fn.call(this, node, item, list)) {
found.push(node);
}
});
return found;
};
return walk;
};