@aesthetic/style
Version:
A low-level, high-performance, atomic-based CSS-in-JS style engine.
266 lines (204 loc) • 7.65 kB
JavaScript
// Bundled with Packemon: https://packemon.dev
// Platform: browser, Support: stable, Format: lib
;
Object.defineProperty(exports, '__esModule', {
value: true
});
const utils = require('@aesthetic/utils');
const sortMediaQueries = require('sort-css-media-queries');
const engine = require('./bundle-cfb1e92a.js');
function _interopDefaultLegacy(e) {
return e && typeof e === 'object' && 'default' in e ? e : {
'default': e
};
}
const sortMediaQueries__default = /*#__PURE__*/_interopDefaultLegacy(sortMediaQueries);
class TransientSheet {
constructor(type = engine.STYLE_RULE, rule = '') {
this.conditionText = '';
this.cssRules = [];
this.cssVariables = {};
this.textContent = '';
this.type = void 0;
this.rule = void 0;
this.rule = rule;
this.type = type;
if (type === engine.MEDIA_RULE || type === engine.SUPPORTS_RULE) {
this.rule = '';
this.conditionText = rule.slice(0, rule.indexOf('{') - 1).replace(this.conditionAtRule, '').trim();
}
}
get cssText() {
const css = utils.arrayReduce(this.cssRules, rule => rule.cssText, this.rule);
if (this.type === engine.MEDIA_RULE || this.type === engine.SUPPORTS_RULE) {
return `${this.conditionAtRule} ${this.conditionText} { ${css} }`;
}
return css;
}
insertRule(rule, index) {
this.cssRules.splice(index, 0, new TransientSheet(this.determineType(rule), rule));
return index;
}
get conditionAtRule() {
return this.type === engine.MEDIA_RULE ? '@media' : '@supports';
}
determineType(rule) {
if (!engine.isAtRule(rule)) {
return engine.STYLE_RULE;
}
if (rule.startsWith('@media')) {
return engine.MEDIA_RULE;
}
if (rule.startsWith('@supports')) {
return engine.SUPPORTS_RULE;
}
if (rule.startsWith('@font-face')) {
return engine.FONT_FACE_RULE;
}
if (rule.startsWith('@keyframes')) {
return engine.KEYFRAMES_RULE;
}
if (rule.startsWith('@import')) {
return engine.IMPORT_RULE;
}
return engine.STYLE_RULE;
}
}
function findNestedRule(sheet, query, type) {
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < sheet.cssRules.length; i += 1) {
const child = sheet.cssRules[i];
if (child && child.type === type && child.conditionText === query) {
return child;
}
}
return null;
}
function insertFeatureRule(manager, sheet, query, rule, parentSheet) {
const formattedRule = `@supports ${query} { ${rule} }`; // Already exists so append a new rule
if (parentSheet && parentSheet !== sheet) {
return parentSheet.insertRule(formattedRule, parentSheet.cssRules.length);
} // Insert the rule and capture the instance
const index = engine.insertRule(sheet, formattedRule);
manager.featureQueries[query] = sheet.cssRules[index];
return index;
}
function insertMediaRule(manager, sheet, query, rule, parentSheet) {
const formattedRule = `@media ${query} { ${rule} }`; // Already exists so append a new rule (except for root sorting)
if (parentSheet && parentSheet !== sheet) {
return parentSheet.insertRule(formattedRule, parentSheet.cssRules.length);
} // Sort and determine the index in which to insert a new query
const sortedQueries = [...Object.keys(manager.mediaQueries), query].sort(sortMediaQueries__default['default']);
const index = sortedQueries.indexOf(query);
engine.insertRule(sheet, formattedRule, index);
manager.mediaQueries[query] = sheet.cssRules[index];
return index;
}
function insertConditionRule(manager, sheet, rule, conditions) {
let parent = sheet;
utils.arrayLoop(conditions, ({
query,
type
}) => {
const instance = findNestedRule(parent, query, type); // Nested found, so continue without inserting a new rule
if (instance) {
parent = instance;
return;
}
const index = type === engine.MEDIA_RULE ? insertMediaRule(manager, sheet, query, '', parent) : insertFeatureRule(manager, sheet, query, '', parent);
parent = parent.cssRules[index];
});
return parent.insertRule(rule, parent.cssRules.length);
}
function createSheetManager(sheets) {
const manager = {
featureQueries: {},
insertRule(rule, options, index) {
var _options$type;
const sheet = sheets[(_options$type = options.type) !== null && _options$type !== void 0 ? _options$type : options.media || options.supports ? 'conditions' : 'standard']; // Imports highest precedence
if (engine.isImportRule(rule)) {
return engine.insertImportRule(sheet, rule);
} // Media and feature queries require special treatment
if (options.media || options.supports) {
const conditions = [];
if (options.supports) {
conditions.push({
query: options.supports,
type: engine.SUPPORTS_RULE
});
}
if (options.media) {
conditions.push({
query: options.media,
type: engine.MEDIA_RULE
});
}
return insertConditionRule(manager, sheet, rule, conditions);
} // Font faces and keyframes lowest precedence
if (engine.isAtRule(rule)) {
return engine.insertAtRule(sheet, rule);
}
return engine.insertRule(sheet, rule, index);
},
mediaQueries: {},
sheets
};
return manager;
}
function extractCssFromSheet(sheet) {
let css = '';
if (Object.keys(sheet.cssVariables).length > 0) {
css += `:root { ${engine.formatVariableBlock(sheet.cssVariables)} }`;
}
css += sheet.cssText;
return css;
}
function getStyleElementAttributes(type, sheet, ruleCount) {
return {
'data-aesthetic-hydrate-index': sheet.cssRules.length - 1,
'data-aesthetic-rule-count': ruleCount,
'data-aesthetic-type': type,
id: `aesthetic-${type}`,
media: 'screen',
nonce: utils.nonce(),
type: 'text/css'
};
}
function createStyleElement(type, sheet, ruleCount) {
const css = extractCssFromSheet(sheet);
const attrs = utils.objectReduce(getStyleElementAttributes(type, sheet, ruleCount), (value, key) => value === undefined ? '' : ` ${key}="${value}"`);
return `<style ${attrs}>${css}</style>`;
}
function renderToStyleMarkup(engine) {
return createStyleElement('global', engine.sheetManager.sheets.global, engine.ruleCount) + createStyleElement('standard', engine.sheetManager.sheets.standard, engine.ruleCount) + createStyleElement('conditions', engine.sheetManager.sheets.conditions, engine.ruleCount);
}
function setRootVariables(engine$1, vars) {
const sheet = engine$1.sheetManager.sheets.global;
utils.objectLoop(vars, (value, key) => {
sheet.cssVariables[engine.formatVariable(key)] = String(value);
});
}
function extractStyles(engine, result) {
global.AESTHETIC_CUSTOM_ENGINE = engine;
process.env.AESTHETIC_SSR = 'true';
return result;
}
function createServerEngine(options = {}) {
const engine$1 = engine.createStyleEngine({
cacheManager: engine.createCacheManager(),
sheetManager: createSheetManager({
conditions: new TransientSheet(),
global: new TransientSheet(),
standard: new TransientSheet()
}),
...options
});
engine$1.setRootVariables = vars => void setRootVariables(engine$1, vars);
engine$1.extractStyles = result => extractStyles(engine$1, result);
return engine$1;
}
exports.createServerEngine = createServerEngine;
exports.extractCssFromSheet = extractCssFromSheet;
exports.getStyleElementAttributes = getStyleElementAttributes;
exports.renderToStyleMarkup = renderToStyleMarkup;
//# sourceMappingURL=server.js.map