css-kits
Version:
Parse css to javascript object. Support change class and id
181 lines (180 loc) • 7.2 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "strkits", "./splitter", "./checker", "./pre-processing", "./detector"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.safeParse = exports.parse = void 0;
const strkits_1 = require("strkits");
const Splitter = __importStar(require("./splitter"));
const Checker = __importStar(require("./checker"));
const Preprocessing = __importStar(require("./pre-processing"));
const detector_1 = require("./detector");
function parseSelectors(subject, transformFunc) {
let selectors = Splitter.splitSelectors(subject);
if (!transformFunc)
return selectors;
return selectors.map((selector) => {
return strkits_1.StrKits.replaceRange(selector, (0, detector_1.detectAllClassAndId)(selector).map(({ start, end }) => {
return {
start,
end,
value: transformFunc(selector.slice(start, end)),
};
}));
});
}
/**
*
* @param subject look like "{ display: block; background-color: blue; color: aqua; }""
* @param camelCasePropertyName default true
*/
function parseDeclarationBlock(subject, transformFunc) {
const results = {};
Splitter.splitDeclarationBlock(subject).forEach((item) => {
const firstIndexOfColon = item.indexOf(':');
if (firstIndexOfColon <= 0) {
throw new SyntaxError(item);
}
let property = item.slice(0, firstIndexOfColon).trim();
const value = item.slice(firstIndexOfColon + 1).trim();
if (property.length === 0 || value.length === 0) {
throw new SyntaxError(item);
}
if (transformFunc && property.startsWith('--') === false) {
property = transformFunc(property);
}
results[property] = value;
});
return results;
}
/**
*
* @param subject look like ".header { display: block; background-color: blue; color: aqua; }"
*/
function parseRuleSet(subject, options) {
const [strSelectors, strDeclarationBlock] = Splitter.splitRuleSetBlock(subject);
const result = {
type: 'rule-set',
selectors: parseSelectors(strSelectors, options.classOrIDTransformFn),
declarationBlock: parseDeclarationBlock(strDeclarationBlock, options.propertyTransformFn),
};
return result;
}
function parseAtRule(subject, options) {
const { identifier, rule, block } = Splitter.splitAtRuleBlock(subject);
switch (Checker.typeOfAtRule(identifier)) {
case 'regular': {
if (block !== null) {
throw new SyntaxError(subject);
}
return {
type: 'regular-at-rule',
identifier,
rule,
};
}
case 'describes': {
if (block === null || !(block.startsWith('{') && block.endsWith('}'))) {
throw new SyntaxError(subject);
}
return {
type: 'describes-at-rule',
identifier,
rule,
declarationBlock: parseDeclarationBlock(block, options.propertyTransformFn),
};
}
case 'nested': {
if (block === null || !(block.startsWith('{') && block.endsWith('}'))) {
throw new SyntaxError(subject);
}
const standardStyleSheet = block.slice(1, -1).trim();
return {
type: 'nested-at-rule',
identifier,
rule,
styleSheetList: parseStyleSheetList(standardStyleSheet, options),
};
}
default: {
throw new SyntaxError(subject);
}
}
}
function parseStyleSheet(standardStyleSheet, options) {
if (standardStyleSheet.startsWith('@')) {
return parseAtRule(standardStyleSheet, options);
}
return parseRuleSet(standardStyleSheet, options);
}
function parseStyleSheetList(standardStyleSheetList, options) {
if (standardStyleSheetList.length === 0)
return [];
const results = [];
Splitter.splitIntoBlocks(standardStyleSheetList).forEach(({ start, end }) => {
const block = standardStyleSheetList.slice(start, end).trim();
if (block.length === 0 || block === ';') {
return;
}
results.push(parseStyleSheet(block, options));
});
return results;
}
function parse(rawCSS, options) {
const finalOptions = {
...options,
};
const standardStyleSheet = Preprocessing.standardizeStyleSheet(rawCSS);
return parseStyleSheetList(standardStyleSheet, finalOptions);
}
exports.parse = parse;
function safeParse(rawCSS, options) {
try {
const styleSheetList = parse(rawCSS, options);
return {
success: true,
styleSheetList,
};
}
catch (e) {
let errorMessage = '';
if (e instanceof Error) {
errorMessage = `[${e.name}] ${e.message}`;
}
return {
success: false,
errorMessage,
};
}
}
exports.safeParse = safeParse;
});