UNPKG

@aesthetic/style

Version:

A low-level, high-performance, atomic-based CSS-in-JS style engine.

266 lines (204 loc) 7.65 kB
// Bundled with Packemon: https://packemon.dev // Platform: browser, Support: stable, Format: lib 'use strict'; 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