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>
This commit is contained in:
root
2026-01-14 10:38:22 +00:00
parent bb9046af1b
commit d523f0f600
2355 changed files with 231384 additions and 32223 deletions

View File

@@ -1,3 +1,5 @@
module.exports = {
getNode: require('./default')
import getNode from './default.js';
export default {
getNode
};

View File

@@ -1,73 +1,70 @@
var cmpChar = require('../../tokenizer').cmpChar;
var cmpStr = require('../../tokenizer').cmpStr;
var TYPE = require('../../tokenizer').TYPE;
import {
Ident,
String as StringToken,
Number as NumberToken,
Function as FunctionToken,
Url,
Hash,
Dimension,
Percentage,
LeftParenthesis,
LeftSquareBracket,
Comma,
Delim
} from '../../tokenizer/index.js';
var IDENT = TYPE.Ident;
var STRING = TYPE.String;
var NUMBER = TYPE.Number;
var FUNCTION = TYPE.Function;
var URL = TYPE.Url;
var HASH = TYPE.Hash;
var DIMENSION = TYPE.Dimension;
var PERCENTAGE = TYPE.Percentage;
var LEFTPARENTHESIS = TYPE.LeftParenthesis;
var LEFTSQUAREBRACKET = TYPE.LeftSquareBracket;
var COMMA = TYPE.Comma;
var DELIM = TYPE.Delim;
var NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
var ASTERISK = 0x002A; // U+002A ASTERISK (*)
var PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
var HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)
var SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
var U = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
const ASTERISK = 0x002A; // U+002A ASTERISK (*)
const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)
const SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
const U = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
module.exports = function defaultRecognizer(context) {
switch (this.scanner.tokenType) {
case HASH:
export default function defaultRecognizer(context) {
switch (this.tokenType) {
case Hash:
return this.Hash();
case COMMA:
context.space = null;
context.ignoreWSAfter = true;
case Comma:
return this.Operator();
case LEFTPARENTHESIS:
case LeftParenthesis:
return this.Parentheses(this.readSequence, context.recognizer);
case LEFTSQUAREBRACKET:
case LeftSquareBracket:
return this.Brackets(this.readSequence, context.recognizer);
case STRING:
case StringToken:
return this.String();
case DIMENSION:
case Dimension:
return this.Dimension();
case PERCENTAGE:
case Percentage:
return this.Percentage();
case NUMBER:
case NumberToken:
return this.Number();
case FUNCTION:
return cmpStr(this.scanner.source, this.scanner.tokenStart, this.scanner.tokenEnd, 'url(')
case FunctionToken:
return this.cmpStr(this.tokenStart, this.tokenEnd, 'url(')
? this.Url()
: this.Function(this.readSequence, context.recognizer);
case URL:
case Url:
return this.Url();
case IDENT:
case Ident:
// check for unicode range, it should start with u+ or U+
if (cmpChar(this.scanner.source, this.scanner.tokenStart, U) &&
cmpChar(this.scanner.source, this.scanner.tokenStart + 1, PLUSSIGN)) {
if (this.cmpChar(this.tokenStart, U) &&
this.cmpChar(this.tokenStart + 1, PLUSSIGN)) {
return this.UnicodeRange();
} else {
return this.Identifier();
}
case DELIM:
var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
case Delim: {
const code = this.charCodeAt(this.tokenStart);
if (code === SOLIDUS ||
code === ASTERISK ||
@@ -79,9 +76,10 @@ module.exports = function defaultRecognizer(context) {
// TODO: produce a node with Delim node type
if (code === NUMBERSIGN) {
this.error('Hex or identifier is expected', this.scanner.tokenStart + 1);
this.error('Hex or identifier is expected', this.tokenStart + 1);
}
break;
}
}
};

View File

@@ -1,5 +1,3 @@
module.exports = {
AtrulePrelude: require('./atrulePrelude'),
Selector: require('./selector'),
Value: require('./value')
};
export { default as AtrulePrelude } from './atrulePrelude.js';
export { default as Selector } from './selector.js';
export { default as Value } from './value.js';

View File

@@ -1,62 +1,71 @@
var TYPE = require('../../tokenizer').TYPE;
import {
Delim,
Ident,
Dimension,
Percentage,
Number as NumberToken,
Hash,
Colon,
LeftSquareBracket
} from '../../tokenizer/index.js';
var DELIM = TYPE.Delim;
var IDENT = TYPE.Ident;
var DIMENSION = TYPE.Dimension;
var PERCENTAGE = TYPE.Percentage;
var NUMBER = TYPE.Number;
var HASH = TYPE.Hash;
var COLON = TYPE.Colon;
var LEFTSQUAREBRACKET = TYPE.LeftSquareBracket;
var NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
var ASTERISK = 0x002A; // U+002A ASTERISK (*)
var PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
var SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
var FULLSTOP = 0x002E; // U+002E FULL STOP (.)
var GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>)
var VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|)
var TILDE = 0x007E; // U+007E TILDE (~)
const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&)
const ASTERISK = 0x002A; // U+002A ASTERISK (*)
const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
const SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
const FULLSTOP = 0x002E; // U+002E FULL STOP (.)
const GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>)
const VERTICALLINE = 0x007C; // U+007C VERTICAL LINE (|)
const TILDE = 0x007E; // U+007E TILDE (~)
function getNode(context) {
switch (this.scanner.tokenType) {
case LEFTSQUAREBRACKET:
function onWhiteSpace(next, children) {
if (children.last !== null && children.last.type !== 'Combinator' &&
next !== null && next.type !== 'Combinator') {
children.push({ // FIXME: this.Combinator() should be used instead
type: 'Combinator',
loc: null,
name: ' '
});
}
}
function getNode() {
switch (this.tokenType) {
case LeftSquareBracket:
return this.AttributeSelector();
case HASH:
case Hash:
return this.IdSelector();
case COLON:
if (this.scanner.lookupType(1) === COLON) {
case Colon:
if (this.lookupType(1) === Colon) {
return this.PseudoElementSelector();
} else {
return this.PseudoClassSelector();
}
case IDENT:
case Ident:
return this.TypeSelector();
case NUMBER:
case PERCENTAGE:
case NumberToken:
case Percentage:
return this.Percentage();
case DIMENSION:
case Dimension:
// throws when .123ident
if (this.scanner.source.charCodeAt(this.scanner.tokenStart) === FULLSTOP) {
this.error('Identifier is expected', this.scanner.tokenStart + 1);
if (this.charCodeAt(this.tokenStart) === FULLSTOP) {
this.error('Identifier is expected', this.tokenStart + 1);
}
break;
case DELIM:
var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
case Delim: {
const code = this.charCodeAt(this.tokenStart);
switch (code) {
case PLUSSIGN:
case GREATERTHANSIGN:
case TILDE:
context.space = null;
context.ignoreWSAfter = true;
return this.Combinator();
case SOLIDUS: // /deep/
return this.Combinator();
@@ -69,12 +78,17 @@ function getNode(context) {
case NUMBERSIGN:
return this.IdSelector();
case AMPERSAND:
return this.NestingSelector();
}
break;
}
}
};
module.exports = {
getNode: getNode
export default {
onWhiteSpace,
getNode
};

View File

@@ -1,5 +1,25 @@
module.exports = {
getNode: require('./default'),
'expression': require('../function/expression'),
'var': require('../function/var')
import getNode from './default.js';
import expressionFn from '../function/expression.js';
import varFn from '../function/var.js';
function isPlusMinusOperator(node) {
return (
node !== null &&
node.type === 'Operator' &&
(node.value[node.value.length - 1] === '-' || node.value[node.value.length - 1] === '+')
);
}
export default {
getNode,
onWhiteSpace(next, children) {
if (isPlusMinusOperator(next)) {
next.value = ' ' + next.value;
}
if (isPlusMinusOperator(children.last)) {
children.last.value += ' ';
}
},
'expression': expressionFn,
'var': varFn
};