192 lines
5.8 KiB
JavaScript
Raw Permalink Normal View History

2024-01-29 09:26:07 +08:00
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.render = void 0;
const parse_1 = require("./parse");
const utils_1 = require("./utils");
const kebabRegex = /[A-Z]/g;
function kebabCase(pattern) {
return pattern.replace(kebabRegex, match => '-' + match.toLowerCase());
}
/** TODO: refine it to solve nested object */
function unwrapProperty(prop, indent = ' ') {
if (typeof prop === 'object' && prop !== null) {
return (' {\n' +
Object.entries(prop).map(v => {
return indent + ` ${kebabCase(v[0])}: ${v[1]};`;
}).join('\n') +
'\n' + indent + '}');
}
return `: ${prop};`;
}
/** unwrap properties */
function unwrapProperties(props, instance, params) {
if (typeof props === 'function') {
return props({
context: instance.context,
props: params
});
}
return props;
}
function createStyle(selector, props, instance, params) {
if (!props)
return '';
// eslint-disable-next-line
const unwrappedProps = unwrapProperties(props, instance, params);
if (!unwrappedProps)
return '';
if (typeof unwrappedProps === 'string') {
return `${selector} {\n${unwrappedProps}\n}`;
}
const propertyNames = Object.keys(unwrappedProps);
if (propertyNames.length === 0) {
if (instance.config.keepEmptyBlock)
return selector + ' {\n}';
return '';
}
const statements = selector
? [
selector + ' {'
]
: [];
propertyNames.forEach(propertyName => {
const property = unwrappedProps[propertyName];
if (propertyName === 'raw') {
statements.push('\n' + property + '\n');
return;
}
propertyName = kebabCase(propertyName);
if (property !== null && property !== undefined) {
statements.push(` ${propertyName}${unwrapProperty(property)}`);
}
});
if (selector) {
statements.push('}');
}
return statements.join('\n');
}
function loopCNodeListWithCallback(children, options, callback) {
/* istanbul ignore if */
if (!children)
return;
children.forEach(child => {
if (Array.isArray(child)) {
loopCNodeListWithCallback(child, options, callback);
}
else if (typeof child === 'function') {
const grandChildren = child(options);
if (Array.isArray(grandChildren)) {
loopCNodeListWithCallback(grandChildren, options, callback);
}
else if (grandChildren) {
callback(grandChildren);
}
}
else if (child) {
callback(child);
}
});
}
function traverseCNode(node, selectorPaths, styles, instance, params, styleSheet) {
const $ = node.$;
let blockSelector = '';
if (!$ || typeof $ === 'string') {
if ((0, utils_1.isMediaOrSupports)($)) {
blockSelector = $;
}
else {
// as a string selector
selectorPaths.push($);
}
}
else if (typeof $ === 'function') {
const selector = $({
context: instance.context,
props: params
});
if ((0, utils_1.isMediaOrSupports)(selector)) {
blockSelector = selector;
}
else {
// as a lazy selector
selectorPaths.push(selector);
}
}
else { // as a option selector
if ($.before)
$.before(instance.context);
if (!$.$ || typeof $.$ === 'string') {
if ((0, utils_1.isMediaOrSupports)($.$)) {
blockSelector = $.$;
}
else {
// as a string selector
selectorPaths.push($.$);
}
}
else /* istanbul ignore else */ if ($.$) {
const selector = $.$({
context: instance.context,
props: params
});
if ((0, utils_1.isMediaOrSupports)(selector)) {
blockSelector = selector;
}
else {
// as a lazy selector
selectorPaths.push(selector);
}
}
}
const selector = (0, parse_1.parseSelectorPath)(selectorPaths);
const style = createStyle(selector, node.props, instance, params);
if (blockSelector) {
styles.push(`${blockSelector} {`);
if (styleSheet && style) {
styleSheet.insertRule(`${blockSelector} {\n${style}\n}\n`);
}
}
else {
if (styleSheet && style) {
styleSheet.insertRule(style);
}
if (!styleSheet && style.length)
styles.push(style);
}
if (node.children) {
loopCNodeListWithCallback(node.children, {
context: instance.context,
props: params
}, childNode => {
if (typeof childNode === 'string') {
const style = createStyle(selector, { raw: childNode }, instance, params);
if (styleSheet) {
styleSheet.insertRule(style);
}
else {
styles.push(style);
}
}
else {
traverseCNode(childNode, selectorPaths, styles, instance, params, styleSheet);
}
});
}
selectorPaths.pop();
if (blockSelector) {
styles.push('}');
}
if ($ && $.after)
$.after(instance.context);
}
function render(node, instance, props, insertRule = false) {
const styles = [];
traverseCNode(node, [], styles, instance, props, insertRule
? node.instance.__styleSheet
: undefined);
if (insertRule)
return '';
return styles.join('\n\n');
}
exports.render = render;