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:
74
node_modules/css-tree/cjs/parser/SyntaxError.cjs
generated
vendored
Normal file
74
node_modules/css-tree/cjs/parser/SyntaxError.cjs
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
'use strict';
|
||||
|
||||
const createCustomError = require('../utils/create-custom-error.cjs');
|
||||
|
||||
const MAX_LINE_LENGTH = 100;
|
||||
const OFFSET_CORRECTION = 60;
|
||||
const TAB_REPLACEMENT = ' ';
|
||||
|
||||
function sourceFragment({ source, line, column, baseLine, baseColumn }, extraLines) {
|
||||
function processLines(start, end) {
|
||||
return lines
|
||||
.slice(start, end)
|
||||
.map((line, idx) =>
|
||||
String(start + idx + 1).padStart(maxNumLength) + ' |' + line
|
||||
).join('\n');
|
||||
}
|
||||
|
||||
const prelines = '\n'.repeat(Math.max(baseLine - 1, 0));
|
||||
const precolumns = ' '.repeat(Math.max(baseColumn - 1, 0));
|
||||
const lines = (prelines + precolumns + source).split(/\r\n?|\n|\f/);
|
||||
const startLine = Math.max(1, line - extraLines) - 1;
|
||||
const endLine = Math.min(line + extraLines, lines.length + 1);
|
||||
const maxNumLength = Math.max(4, String(endLine).length) + 1;
|
||||
let cutLeft = 0;
|
||||
|
||||
// column correction according to replaced tab before column
|
||||
column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length;
|
||||
|
||||
if (column > MAX_LINE_LENGTH) {
|
||||
cutLeft = column - OFFSET_CORRECTION + 3;
|
||||
column = OFFSET_CORRECTION - 2;
|
||||
}
|
||||
|
||||
for (let i = startLine; i <= endLine; i++) {
|
||||
if (i >= 0 && i < lines.length) {
|
||||
lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT);
|
||||
lines[i] =
|
||||
(cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') +
|
||||
lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +
|
||||
(lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : '');
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
processLines(startLine, line),
|
||||
new Array(column + maxNumLength + 2).join('-') + '^',
|
||||
processLines(line, endLine)
|
||||
].filter(Boolean)
|
||||
.join('\n')
|
||||
.replace(/^(\s+\d+\s+\|\n)+/, '')
|
||||
.replace(/\n(\s+\d+\s+\|)+$/, '');
|
||||
}
|
||||
|
||||
function SyntaxError(message, source, offset, line, column, baseLine = 1, baseColumn = 1) {
|
||||
const error = Object.assign(createCustomError.createCustomError('SyntaxError', message), {
|
||||
source,
|
||||
offset,
|
||||
line,
|
||||
column,
|
||||
sourceFragment(extraLines) {
|
||||
return sourceFragment({ source, line, column, baseLine, baseColumn }, isNaN(extraLines) ? 0 : extraLines);
|
||||
},
|
||||
get formattedMessage() {
|
||||
return (
|
||||
`Parse error: ${message}\n` +
|
||||
sourceFragment({ source, line, column, baseLine, baseColumn }, 2)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
exports.SyntaxError = SyntaxError;
|
||||
340
node_modules/css-tree/cjs/parser/create.cjs
generated
vendored
Normal file
340
node_modules/css-tree/cjs/parser/create.cjs
generated
vendored
Normal file
@@ -0,0 +1,340 @@
|
||||
'use strict';
|
||||
|
||||
const List = require('../utils/List.cjs');
|
||||
const SyntaxError = require('./SyntaxError.cjs');
|
||||
const index = require('../tokenizer/index.cjs');
|
||||
const sequence = require('./sequence.cjs');
|
||||
const OffsetToLocation = require('../tokenizer/OffsetToLocation.cjs');
|
||||
const TokenStream = require('../tokenizer/TokenStream.cjs');
|
||||
const utils = require('../tokenizer/utils.cjs');
|
||||
const types = require('../tokenizer/types.cjs');
|
||||
const names = require('../tokenizer/names.cjs');
|
||||
|
||||
const NOOP = () => {};
|
||||
const EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!)
|
||||
const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
|
||||
const SEMICOLON = 0x003B; // U+003B SEMICOLON (;)
|
||||
const LEFTCURLYBRACKET = 0x007B; // U+007B LEFT CURLY BRACKET ({)
|
||||
const NULL = 0;
|
||||
|
||||
function createParseContext(name) {
|
||||
return function() {
|
||||
return this[name]();
|
||||
};
|
||||
}
|
||||
|
||||
function fetchParseValues(dict) {
|
||||
const result = Object.create(null);
|
||||
|
||||
for (const name of Object.keys(dict)) {
|
||||
const item = dict[name];
|
||||
const fn = item.parse || item;
|
||||
|
||||
if (fn) {
|
||||
result[name] = fn;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function processConfig(config) {
|
||||
const parseConfig = {
|
||||
context: Object.create(null),
|
||||
features: Object.assign(Object.create(null), config.features),
|
||||
scope: Object.assign(Object.create(null), config.scope),
|
||||
atrule: fetchParseValues(config.atrule),
|
||||
pseudo: fetchParseValues(config.pseudo),
|
||||
node: fetchParseValues(config.node)
|
||||
};
|
||||
|
||||
for (const [name, context] of Object.entries(config.parseContext)) {
|
||||
switch (typeof context) {
|
||||
case 'function':
|
||||
parseConfig.context[name] = context;
|
||||
break;
|
||||
|
||||
case 'string':
|
||||
parseConfig.context[name] = createParseContext(context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
config: parseConfig,
|
||||
...parseConfig,
|
||||
...parseConfig.node
|
||||
};
|
||||
}
|
||||
|
||||
function createParser(config) {
|
||||
let source = '';
|
||||
let filename = '<unknown>';
|
||||
let needPositions = false;
|
||||
let onParseError = NOOP;
|
||||
let onParseErrorThrow = false;
|
||||
|
||||
const locationMap = new OffsetToLocation.OffsetToLocation();
|
||||
const parser = Object.assign(new TokenStream.TokenStream(), processConfig(config || {}), {
|
||||
parseAtrulePrelude: true,
|
||||
parseRulePrelude: true,
|
||||
parseValue: true,
|
||||
parseCustomProperty: false,
|
||||
|
||||
readSequence: sequence.readSequence,
|
||||
|
||||
consumeUntilBalanceEnd: () => 0,
|
||||
consumeUntilLeftCurlyBracket(code) {
|
||||
return code === LEFTCURLYBRACKET ? 1 : 0;
|
||||
},
|
||||
consumeUntilLeftCurlyBracketOrSemicolon(code) {
|
||||
return code === LEFTCURLYBRACKET || code === SEMICOLON ? 1 : 0;
|
||||
},
|
||||
consumeUntilExclamationMarkOrSemicolon(code) {
|
||||
return code === EXCLAMATIONMARK || code === SEMICOLON ? 1 : 0;
|
||||
},
|
||||
consumeUntilSemicolonIncluded(code) {
|
||||
return code === SEMICOLON ? 2 : 0;
|
||||
},
|
||||
|
||||
createList() {
|
||||
return new List.List();
|
||||
},
|
||||
createSingleNodeList(node) {
|
||||
return new List.List().appendData(node);
|
||||
},
|
||||
getFirstListNode(list) {
|
||||
return list && list.first;
|
||||
},
|
||||
getLastListNode(list) {
|
||||
return list && list.last;
|
||||
},
|
||||
|
||||
parseWithFallback(consumer, fallback) {
|
||||
const startIndex = this.tokenIndex;
|
||||
|
||||
try {
|
||||
return consumer.call(this);
|
||||
} catch (e) {
|
||||
if (onParseErrorThrow) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
this.skip(startIndex - this.tokenIndex);
|
||||
const fallbackNode = fallback.call(this);
|
||||
|
||||
onParseErrorThrow = true;
|
||||
onParseError(e, fallbackNode);
|
||||
onParseErrorThrow = false;
|
||||
|
||||
return fallbackNode;
|
||||
}
|
||||
},
|
||||
|
||||
lookupNonWSType(offset) {
|
||||
let type;
|
||||
|
||||
do {
|
||||
type = this.lookupType(offset++);
|
||||
if (type !== types.WhiteSpace && type !== types.Comment) {
|
||||
return type;
|
||||
}
|
||||
} while (type !== NULL);
|
||||
|
||||
return NULL;
|
||||
},
|
||||
|
||||
charCodeAt(offset) {
|
||||
return offset >= 0 && offset < source.length ? source.charCodeAt(offset) : 0;
|
||||
},
|
||||
substring(offsetStart, offsetEnd) {
|
||||
return source.substring(offsetStart, offsetEnd);
|
||||
},
|
||||
substrToCursor(start) {
|
||||
return this.source.substring(start, this.tokenStart);
|
||||
},
|
||||
|
||||
cmpChar(offset, charCode) {
|
||||
return utils.cmpChar(source, offset, charCode);
|
||||
},
|
||||
cmpStr(offsetStart, offsetEnd, str) {
|
||||
return utils.cmpStr(source, offsetStart, offsetEnd, str);
|
||||
},
|
||||
|
||||
consume(tokenType) {
|
||||
const start = this.tokenStart;
|
||||
|
||||
this.eat(tokenType);
|
||||
|
||||
return this.substrToCursor(start);
|
||||
},
|
||||
consumeFunctionName() {
|
||||
const name = source.substring(this.tokenStart, this.tokenEnd - 1);
|
||||
|
||||
this.eat(types.Function);
|
||||
|
||||
return name;
|
||||
},
|
||||
consumeNumber(type) {
|
||||
const number = source.substring(this.tokenStart, utils.consumeNumber(source, this.tokenStart));
|
||||
|
||||
this.eat(type);
|
||||
|
||||
return number;
|
||||
},
|
||||
|
||||
eat(tokenType) {
|
||||
if (this.tokenType !== tokenType) {
|
||||
const tokenName = names[tokenType].slice(0, -6).replace(/-/g, ' ').replace(/^./, m => m.toUpperCase());
|
||||
let message = `${/[[\](){}]/.test(tokenName) ? `"${tokenName}"` : tokenName} is expected`;
|
||||
let offset = this.tokenStart;
|
||||
|
||||
// tweak message and offset
|
||||
switch (tokenType) {
|
||||
case types.Ident:
|
||||
// when identifier is expected but there is a function or url
|
||||
if (this.tokenType === types.Function || this.tokenType === types.Url) {
|
||||
offset = this.tokenEnd - 1;
|
||||
message = 'Identifier is expected but function found';
|
||||
} else {
|
||||
message = 'Identifier is expected';
|
||||
}
|
||||
break;
|
||||
|
||||
case types.Hash:
|
||||
if (this.isDelim(NUMBERSIGN)) {
|
||||
this.next();
|
||||
offset++;
|
||||
message = 'Name is expected';
|
||||
}
|
||||
break;
|
||||
|
||||
case types.Percentage:
|
||||
if (this.tokenType === types.Number) {
|
||||
offset = this.tokenEnd;
|
||||
message = 'Percent sign is expected';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this.error(message, offset);
|
||||
}
|
||||
|
||||
this.next();
|
||||
},
|
||||
eatIdent(name) {
|
||||
if (this.tokenType !== types.Ident || this.lookupValue(0, name) === false) {
|
||||
this.error(`Identifier "${name}" is expected`);
|
||||
}
|
||||
|
||||
this.next();
|
||||
},
|
||||
eatDelim(code) {
|
||||
if (!this.isDelim(code)) {
|
||||
this.error(`Delim "${String.fromCharCode(code)}" is expected`);
|
||||
}
|
||||
|
||||
this.next();
|
||||
},
|
||||
|
||||
getLocation(start, end) {
|
||||
if (needPositions) {
|
||||
return locationMap.getLocationRange(
|
||||
start,
|
||||
end,
|
||||
filename
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
getLocationFromList(list) {
|
||||
if (needPositions) {
|
||||
const head = this.getFirstListNode(list);
|
||||
const tail = this.getLastListNode(list);
|
||||
return locationMap.getLocationRange(
|
||||
head !== null ? head.loc.start.offset - locationMap.startOffset : this.tokenStart,
|
||||
tail !== null ? tail.loc.end.offset - locationMap.startOffset : this.tokenStart,
|
||||
filename
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
error(message, offset) {
|
||||
const location = typeof offset !== 'undefined' && offset < source.length
|
||||
? locationMap.getLocation(offset)
|
||||
: this.eof
|
||||
? locationMap.getLocation(utils.findWhiteSpaceStart(source, source.length - 1))
|
||||
: locationMap.getLocation(this.tokenStart);
|
||||
|
||||
throw new SyntaxError.SyntaxError(
|
||||
message || 'Unexpected input',
|
||||
source,
|
||||
location.offset,
|
||||
location.line,
|
||||
location.column,
|
||||
locationMap.startLine,
|
||||
locationMap.startColumn
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const parse = function(source_, options) {
|
||||
source = source_;
|
||||
options = options || {};
|
||||
|
||||
parser.setSource(source, index.tokenize);
|
||||
locationMap.setSource(
|
||||
source,
|
||||
options.offset,
|
||||
options.line,
|
||||
options.column
|
||||
);
|
||||
|
||||
filename = options.filename || '<unknown>';
|
||||
needPositions = Boolean(options.positions);
|
||||
onParseError = typeof options.onParseError === 'function' ? options.onParseError : NOOP;
|
||||
onParseErrorThrow = false;
|
||||
|
||||
parser.parseAtrulePrelude = 'parseAtrulePrelude' in options ? Boolean(options.parseAtrulePrelude) : true;
|
||||
parser.parseRulePrelude = 'parseRulePrelude' in options ? Boolean(options.parseRulePrelude) : true;
|
||||
parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true;
|
||||
parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false;
|
||||
|
||||
const { context = 'default', onComment } = options;
|
||||
|
||||
if (context in parser.context === false) {
|
||||
throw new Error('Unknown context `' + context + '`');
|
||||
}
|
||||
|
||||
if (typeof onComment === 'function') {
|
||||
parser.forEachToken((type, start, end) => {
|
||||
if (type === types.Comment) {
|
||||
const loc = parser.getLocation(start, end);
|
||||
const value = utils.cmpStr(source, end - 2, end, '*/')
|
||||
? source.slice(start + 2, end - 2)
|
||||
: source.slice(start + 2, end);
|
||||
|
||||
onComment(value, loc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const ast = parser.context[context].call(parser, options);
|
||||
|
||||
if (!parser.eof) {
|
||||
parser.error();
|
||||
}
|
||||
|
||||
return ast;
|
||||
};
|
||||
|
||||
return Object.assign(parse, {
|
||||
SyntaxError: SyntaxError.SyntaxError,
|
||||
config: parser.config
|
||||
});
|
||||
}
|
||||
|
||||
exports.createParser = createParser;
|
||||
8
node_modules/css-tree/cjs/parser/index.cjs
generated
vendored
Normal file
8
node_modules/css-tree/cjs/parser/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
const create = require('./create.cjs');
|
||||
const parser = require('../syntax/config/parser.cjs');
|
||||
|
||||
const index = create.createParser(parser);
|
||||
|
||||
module.exports = index;
|
||||
8
node_modules/css-tree/cjs/parser/parse-selector.cjs
generated
vendored
Normal file
8
node_modules/css-tree/cjs/parser/parse-selector.cjs
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
const create = require('./create.cjs');
|
||||
const parserSelector = require('../syntax/config/parser-selector.cjs');
|
||||
|
||||
const parseSelector = create.createParser(parserSelector);
|
||||
|
||||
module.exports = parseSelector;
|
||||
47
node_modules/css-tree/cjs/parser/sequence.cjs
generated
vendored
Normal file
47
node_modules/css-tree/cjs/parser/sequence.cjs
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
'use strict';
|
||||
|
||||
const types = require('../tokenizer/types.cjs');
|
||||
|
||||
function readSequence(recognizer) {
|
||||
const children = this.createList();
|
||||
let space = false;
|
||||
const context = {
|
||||
recognizer
|
||||
};
|
||||
|
||||
while (!this.eof) {
|
||||
switch (this.tokenType) {
|
||||
case types.Comment:
|
||||
this.next();
|
||||
continue;
|
||||
|
||||
case types.WhiteSpace:
|
||||
space = true;
|
||||
this.next();
|
||||
continue;
|
||||
}
|
||||
|
||||
let child = recognizer.getNode.call(this, context);
|
||||
|
||||
if (child === undefined) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (space) {
|
||||
if (recognizer.onWhiteSpace) {
|
||||
recognizer.onWhiteSpace.call(this, child, children, context);
|
||||
}
|
||||
space = false;
|
||||
}
|
||||
|
||||
children.push(child);
|
||||
}
|
||||
|
||||
if (space && recognizer.onWhiteSpace) {
|
||||
recognizer.onWhiteSpace.call(this, null, children, context);
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
exports.readSequence = readSequence;
|
||||
Reference in New Issue
Block a user