Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@mattsjones/css-core

Package Overview
Dependencies
Maintainers
4
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mattsjones/css-core - npm Package Compare versions

Comparing version 0.0.10 to 0.0.11

5

adapter/dist/mattsjones-css-core-adapter.browser.cjs.js

@@ -8,3 +8,2 @@ 'use strict';

registerClassName: () => {},
getRegisteredClassNames: () => [],
onEndFileScope: () => {}

@@ -21,5 +20,2 @@ };

};
const getRegisteredClassNames = (...props) => {
return adapter.getRegisteredClassNames(...props);
};
const onEndFileScope = (...props) => {

@@ -30,5 +26,4 @@ return adapter.onEndFileScope(...props);

exports.appendCss = appendCss;
exports.getRegisteredClassNames = getRegisteredClassNames;
exports.onEndFileScope = onEndFileScope;
exports.registerClassName = registerClassName;
exports.setAdapter = setAdapter;

6

adapter/dist/mattsjones-css-core-adapter.browser.esm.js
let adapter = {
appendCss: () => {},
registerClassName: () => {},
getRegisteredClassNames: () => [],
onEndFileScope: () => {}

@@ -16,5 +15,2 @@ };

};
const getRegisteredClassNames = (...props) => {
return adapter.getRegisteredClassNames(...props);
};
const onEndFileScope = (...props) => {

@@ -24,2 +20,2 @@ return adapter.onEndFileScope(...props);

export { appendCss, getRegisteredClassNames, onEndFileScope, registerClassName, setAdapter };
export { appendCss, onEndFileScope, registerClassName, setAdapter };

@@ -8,3 +8,2 @@ 'use strict';

registerClassName: () => {},
getRegisteredClassNames: () => [],
onEndFileScope: () => {}

@@ -21,5 +20,2 @@ };

};
const getRegisteredClassNames = (...props) => {
return adapter.getRegisteredClassNames(...props);
};
const onEndFileScope = (...props) => {

@@ -30,5 +26,4 @@ return adapter.onEndFileScope(...props);

exports.appendCss = appendCss;
exports.getRegisteredClassNames = getRegisteredClassNames;
exports.onEndFileScope = onEndFileScope;
exports.registerClassName = registerClassName;
exports.setAdapter = setAdapter;

@@ -8,3 +8,2 @@ 'use strict';

registerClassName: () => {},
getRegisteredClassNames: () => [],
onEndFileScope: () => {}

@@ -21,5 +20,2 @@ };

};
const getRegisteredClassNames = (...props) => {
return adapter.getRegisteredClassNames(...props);
};
const onEndFileScope = (...props) => {

@@ -30,5 +26,4 @@ return adapter.onEndFileScope(...props);

exports.appendCss = appendCss;
exports.getRegisteredClassNames = getRegisteredClassNames;
exports.onEndFileScope = onEndFileScope;
exports.registerClassName = registerClassName;
exports.setAdapter = setAdapter;
let adapter = {
appendCss: () => {},
registerClassName: () => {},
getRegisteredClassNames: () => [],
onEndFileScope: () => {}

@@ -16,5 +15,2 @@ };

};
const getRegisteredClassNames = (...props) => {
return adapter.getRegisteredClassNames(...props);
};
const onEndFileScope = (...props) => {

@@ -24,2 +20,2 @@ return adapter.onEndFileScope(...props);

export { appendCss, getRegisteredClassNames, onEndFileScope, registerClassName, setAdapter };
export { appendCss, onEndFileScope, registerClassName, setAdapter };

7

CHANGELOG.md
# @mattsjones/css-core
## 0.0.11
### Patch Changes
- 8835fec: Export Adapter type
- 3ab713c: Escape generated class names
## 0.0.10

@@ -4,0 +11,0 @@

@@ -5,3 +5,2 @@ import type { Adapter } from './types';

export declare const registerClassName: Adapter['registerClassName'];
export declare const getRegisteredClassNames: Adapter['getRegisteredClassNames'];
export declare const onEndFileScope: Adapter['onEndFileScope'];
import { CSS } from './types';
export declare function generateCss(...allCssObjs: Array<CSS>): Array<string>;
interface GenerateCssParams {
localClassNames: Array<string>;
cssObjs: Array<CSS>;
}
export declare function generateCss({ localClassNames, cssObjs, }: GenerateCssParams): Array<string>;
export {};

@@ -1,2 +0,2 @@

export type { StyleRule } from './types';
export type { StyleRule, Adapter } from './types';
export * from './api';
import type { CSS } from './types';
export declare const simplePseudos: readonly [":-moz-any-link", ":-moz-full-screen", ":-moz-placeholder", ":-moz-read-only", ":-moz-read-write", ":-ms-fullscreen", ":-ms-input-placeholder", ":-webkit-any-link", ":-webkit-full-screen", "::-moz-placeholder", "::-moz-progress-bar", "::-moz-range-progress", "::-moz-range-thumb", "::-moz-range-track", "::-moz-selection", "::-ms-backdrop", "::-ms-browse", "::-ms-check", "::-ms-clear", "::-ms-fill", "::-ms-fill-lower", "::-ms-fill-upper", "::-ms-reveal", "::-ms-thumb", "::-ms-ticks-after", "::-ms-ticks-before", "::-ms-tooltip", "::-ms-track", "::-ms-value", "::-webkit-backdrop", "::-webkit-input-placeholder", "::-webkit-progress-bar", "::-webkit-progress-inner-value", "::-webkit-progress-value", "::-webkit-slider-runnable-track", "::-webkit-slider-thumb", "::after", "::backdrop", "::before", "::cue", "::first-letter", "::first-line", "::grammar-error", "::placeholder", "::selection", "::spelling-error", ":active", ":after", ":any-link", ":before", ":blank", ":checked", ":default", ":defined", ":disabled", ":empty", ":enabled", ":first", ":first-child", ":first-letter", ":first-line", ":first-of-type", ":focus", ":focus-visible", ":focus-within", ":fullscreen", ":hover", ":in-range", ":indeterminate", ":invalid", ":last-child", ":last-of-type", ":left", ":link", ":only-child", ":only-of-type", ":optional", ":out-of-range", ":placeholder-shown", ":read-only", ":read-write", ":required", ":right", ":root", ":scope", ":target", ":valid", ":visited"];
export declare type SimplePseudos = typeof simplePseudos;
export declare function transformCss(...allCssObjs: Array<CSS>): any;
interface TransformCSSParams {
localClassNames: Array<string>;
cssObjs: Array<CSS>;
}
export declare function transformCss({ localClassNames, cssObjs }: TransformCSSParams): any;
export {};

@@ -41,5 +41,4 @@ import type { PropertiesFallback } from 'csstype';

registerClassName: (className: string) => void;
getRegisteredClassNames: () => Array<string>;
onEndFileScope: (fileScope: string) => void;
}
export {};

@@ -1,1 +0,1 @@

export declare const validateSelector: (selector: string) => void[];
export declare const validateSelector: (selector: string, targetClassName: string) => void[];

@@ -5,6 +5,7 @@ 'use strict';

var generateCss_dist_mattsjonesCssCoreGenerateCss = require('./generateCss-0f19bc03.browser.cjs.js');
var generateCss_dist_mattsjonesCssCoreGenerateCss = require('../generateCss/dist/mattsjones-css-core-generateCss.browser.cjs.js');
var adapter_dist_mattsjonesCssCoreAdapter = require('../adapter/dist/mattsjones-css-core-adapter.browser.cjs.js');
var hash = require('@emotion/hash');
var get = require('lodash/get');
var cssesc = require('cssesc');
var fileScope_dist_mattsjonesCssCoreFileScope = require('../fileScope/dist/mattsjones-css-core-fileScope.browser.cjs.js');

@@ -24,2 +25,3 @@ require('postcss-js');

var get__default = /*#__PURE__*/_interopDefault(get);
var cssesc__default = /*#__PURE__*/_interopDefault(cssesc);

@@ -53,5 +55,7 @@ let styleSheet;

},
getRegisteredClassNames: () => Array.from(localClassNames),
onEndFileScope: () => {
const css = generateCss_dist_mattsjonesCssCoreGenerateCss.generateCss(...bufferedCSSObjs);
const css = generateCss_dist_mattsjonesCssCoreGenerateCss.generateCss({
localClassNames: Array.from(localClassNames),
cssObjs: bufferedCSSObjs
});
const stylesheet = getStylesheet();

@@ -85,3 +89,3 @@

const className = process.env.NODE_ENV !== 'production' && debugId ? `${getShortFileName()}_${debugId}__${hash__default['default'](fileScope_dist_mattsjonesCssCoreFileScope.getFileScope())}${refCount}` : `${hash__default['default'](fileScope_dist_mattsjonesCssCoreFileScope.getFileScope())}${refCount}`;
return generateCss_dist_mattsjonesCssCoreGenerateCss.sanitiseIdent(className);
return className.match(/^[0-9]/) ? `_${className}` : className;
};

@@ -114,3 +118,5 @@

const cssVarName = generateCss_dist_mattsjonesCssCoreGenerateCss.sanitiseIdent(varName).replace(/([A-Z])/g, '-$1').toLowerCase();
const cssVarName = cssesc__default['default'](varName.match(/^[0-9]/) ? `_${varName}` : varName, {
isIdentifier: true
}).replace(/([A-Z])/g, '-$1').toLowerCase();
return `var(--${cssVarName})`;

@@ -117,0 +123,0 @@ }

@@ -1,5 +0,6 @@

import { g as generateCss, s as sanitiseIdent } from './generateCss-a758bf8f.browser.esm.js';
import { generateCss } from '../generateCss/dist/mattsjones-css-core-generateCss.browser.esm.js';
import { registerClassName, appendCss, setAdapter } from '../adapter/dist/mattsjones-css-core-adapter.browser.esm.js';
import hash from '@emotion/hash';
import get from 'lodash/get';
import cssesc from 'cssesc';
import { getAndIncrementRefCounter, getFileScope } from '../fileScope/dist/mattsjones-css-core-fileScope.browser.esm.js';

@@ -42,5 +43,7 @@ import 'postcss-js';

},
getRegisteredClassNames: () => Array.from(localClassNames),
onEndFileScope: () => {
const css = generateCss(...bufferedCSSObjs);
const css = generateCss({
localClassNames: Array.from(localClassNames),
cssObjs: bufferedCSSObjs
});
const stylesheet = getStylesheet();

@@ -74,3 +77,3 @@

const className = process.env.NODE_ENV !== 'production' && debugId ? `${getShortFileName()}_${debugId}__${hash(getFileScope())}${refCount}` : `${hash(getFileScope())}${refCount}`;
return sanitiseIdent(className);
return className.match(/^[0-9]/) ? `_${className}` : className;
};

@@ -103,3 +106,5 @@

const cssVarName = sanitiseIdent(varName).replace(/([A-Z])/g, '-$1').toLowerCase();
const cssVarName = cssesc(varName.match(/^[0-9]/) ? `_${varName}` : varName, {
isIdentifier: true
}).replace(/([A-Z])/g, '-$1').toLowerCase();
return `var(--${cssVarName})`;

@@ -106,0 +111,0 @@ }

@@ -5,6 +5,7 @@ 'use strict';

var generateCss_dist_mattsjonesCssCoreGenerateCss = require('./generateCss-35f6aedf.cjs.dev.js');
var generateCss_dist_mattsjonesCssCoreGenerateCss = require('../generateCss/dist/mattsjones-css-core-generateCss.cjs.dev.js');
var adapter_dist_mattsjonesCssCoreAdapter = require('../adapter/dist/mattsjones-css-core-adapter.cjs.dev.js');
var hash = require('@emotion/hash');
var get = require('lodash/get');
var cssesc = require('cssesc');
var fileScope_dist_mattsjonesCssCoreFileScope = require('../fileScope/dist/mattsjones-css-core-fileScope.cjs.dev.js');

@@ -24,2 +25,3 @@ require('postcss-js');

var get__default = /*#__PURE__*/_interopDefault(get);
var cssesc__default = /*#__PURE__*/_interopDefault(cssesc);

@@ -53,5 +55,7 @@ let styleSheet;

},
getRegisteredClassNames: () => Array.from(localClassNames),
onEndFileScope: () => {
const css = generateCss_dist_mattsjonesCssCoreGenerateCss.generateCss(...bufferedCSSObjs);
const css = generateCss_dist_mattsjonesCssCoreGenerateCss.generateCss({
localClassNames: Array.from(localClassNames),
cssObjs: bufferedCSSObjs
});
const stylesheet = getStylesheet();

@@ -85,3 +89,3 @@

const className = process.env.NODE_ENV !== 'production' && debugId ? `${getShortFileName()}_${debugId}__${hash__default['default'](fileScope_dist_mattsjonesCssCoreFileScope.getFileScope())}${refCount}` : `${hash__default['default'](fileScope_dist_mattsjonesCssCoreFileScope.getFileScope())}${refCount}`;
return generateCss_dist_mattsjonesCssCoreGenerateCss.sanitiseIdent(className);
return className.match(/^[0-9]/) ? `_${className}` : className;
};

@@ -114,3 +118,5 @@

const cssVarName = generateCss_dist_mattsjonesCssCoreGenerateCss.sanitiseIdent(varName).replace(/([A-Z])/g, '-$1').toLowerCase();
const cssVarName = cssesc__default['default'](varName.match(/^[0-9]/) ? `_${varName}` : varName, {
isIdentifier: true
}).replace(/([A-Z])/g, '-$1').toLowerCase();
return `var(--${cssVarName})`;

@@ -117,0 +123,0 @@ }

@@ -5,6 +5,7 @@ 'use strict';

var generateCss_dist_mattsjonesCssCoreGenerateCss = require('./generateCss-0e42352c.cjs.prod.js');
var generateCss_dist_mattsjonesCssCoreGenerateCss = require('../generateCss/dist/mattsjones-css-core-generateCss.cjs.prod.js');
var adapter_dist_mattsjonesCssCoreAdapter = require('../adapter/dist/mattsjones-css-core-adapter.cjs.prod.js');
var hash = require('@emotion/hash');
var get = require('lodash/get');
var cssesc = require('cssesc');
var fileScope_dist_mattsjonesCssCoreFileScope = require('../fileScope/dist/mattsjones-css-core-fileScope.cjs.prod.js');

@@ -24,2 +25,3 @@ require('postcss-js');

var get__default = /*#__PURE__*/_interopDefault(get);
var cssesc__default = /*#__PURE__*/_interopDefault(cssesc);

@@ -53,5 +55,7 @@ let styleSheet;

},
getRegisteredClassNames: () => Array.from(localClassNames),
onEndFileScope: () => {
const css = generateCss_dist_mattsjonesCssCoreGenerateCss.generateCss(...bufferedCSSObjs);
const css = generateCss_dist_mattsjonesCssCoreGenerateCss.generateCss({
localClassNames: Array.from(localClassNames),
cssObjs: bufferedCSSObjs
});
const stylesheet = getStylesheet();

@@ -74,3 +78,3 @@

const className = `${hash__default['default'](fileScope_dist_mattsjonesCssCoreFileScope.getFileScope())}${refCount}`;
return generateCss_dist_mattsjonesCssCoreGenerateCss.sanitiseIdent(className);
return className.match(/^[0-9]/) ? `_${className}` : className;
};

@@ -103,3 +107,5 @@

const cssVarName = generateCss_dist_mattsjonesCssCoreGenerateCss.sanitiseIdent(varName).replace(/([A-Z])/g, '-$1').toLowerCase();
const cssVarName = cssesc__default['default'](varName.match(/^[0-9]/) ? `_${varName}` : varName, {
isIdentifier: true
}).replace(/([A-Z])/g, '-$1').toLowerCase();
return `var(--${cssVarName})`;

@@ -106,0 +112,0 @@ }

@@ -1,5 +0,6 @@

import { g as generateCss, s as sanitiseIdent } from './generateCss-addefd6f.esm.js';
import { generateCss } from '../generateCss/dist/mattsjones-css-core-generateCss.esm.js';
import { registerClassName, appendCss, setAdapter } from '../adapter/dist/mattsjones-css-core-adapter.esm.js';
import hash from '@emotion/hash';
import get from 'lodash/get';
import cssesc from 'cssesc';
import { getAndIncrementRefCounter, getFileScope } from '../fileScope/dist/mattsjones-css-core-fileScope.esm.js';

@@ -42,5 +43,7 @@ import 'postcss-js';

},
getRegisteredClassNames: () => Array.from(localClassNames),
onEndFileScope: () => {
const css = generateCss(...bufferedCSSObjs);
const css = generateCss({
localClassNames: Array.from(localClassNames),
cssObjs: bufferedCSSObjs
});
const stylesheet = getStylesheet();

@@ -74,3 +77,3 @@

const className = process.env.NODE_ENV !== 'production' && debugId ? `${getShortFileName()}_${debugId}__${hash(getFileScope())}${refCount}` : `${hash(getFileScope())}${refCount}`;
return sanitiseIdent(className);
return className.match(/^[0-9]/) ? `_${className}` : className;
};

@@ -103,3 +106,5 @@

const cssVarName = sanitiseIdent(varName).replace(/([A-Z])/g, '-$1').toLowerCase();
const cssVarName = cssesc(varName.match(/^[0-9]/) ? `_${varName}` : varName, {
isIdentifier: true
}).replace(/([A-Z])/g, '-$1').toLowerCase();
return `var(--${cssVarName})`;

@@ -106,0 +111,0 @@ }

@@ -5,16 +5,304 @@ 'use strict';

require('postcss-js');
require('postcss');
var generateCss_dist_mattsjonesCssCoreGenerateCss = require('../../dist/generateCss-0f19bc03.browser.cjs.js');
require('@emotion/hash');
require('lodash/each');
require('lodash/omit');
require('lodash/isEqual');
require('lodash/mapKeys');
require('css-selector-parser');
require('dedent');
require('../../adapter/dist/mattsjones-css-core-adapter.browser.cjs.js');
var postcssJs = require('postcss-js');
var postcss = require('postcss');
var cssesc = require('cssesc');
var hash = require('@emotion/hash');
var each = require('lodash/each');
var omit = require('lodash/omit');
var isEqual = require('lodash/isEqual');
var mapKeys = require('lodash/mapKeys');
var cssSelectorParser = require('css-selector-parser');
var dedent = require('dedent');
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
var postcssJs__default = /*#__PURE__*/_interopDefault(postcssJs);
var postcss__default = /*#__PURE__*/_interopDefault(postcss);
var cssesc__default = /*#__PURE__*/_interopDefault(cssesc);
var hash__default = /*#__PURE__*/_interopDefault(hash);
var each__default = /*#__PURE__*/_interopDefault(each);
var omit__default = /*#__PURE__*/_interopDefault(omit);
var isEqual__default = /*#__PURE__*/_interopDefault(isEqual);
var mapKeys__default = /*#__PURE__*/_interopDefault(mapKeys);
var dedent__default = /*#__PURE__*/_interopDefault(dedent);
exports.generateCss = generateCss_dist_mattsjonesCssCoreGenerateCss.generateCss;
function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
const parser = new cssSelectorParser.CssSelectorParser();
parser.registerSelectorPseudos('has');
parser.registerNestingOperators('>', '+', '~');
parser.registerAttrEqualityMods('^', '$', '*', '~');
parser.enableSubstitutes();
const validateSelector = (selector, targetClassName) => {
const replaceTarget = () => {
const targetRegex = new RegExp(`.${escapeRegex(cssesc__default['default'](targetClassName, {
isIdentifier: true
}))}`, 'g');
return selector.replace(targetRegex, '&');
};
return selector.split(',').map(selectorPart => {
if (selectorPart.indexOf(targetClassName) === -1) {
throw new Error(dedent__default['default']`
Invalid selector: ${replaceTarget()}
Selectors must target the ampersand character ('&'), which refers to the generated class name, e.g. '&:nth-child(2n)'
`);
}
let currentRule;
try {
const result = parser.parse(selectorPart);
if (result.type === 'ruleSet') {
currentRule = result.rule;
} else {
throw new Error();
}
} catch (err) {
throw new Error(`Invalid selector: ${replaceTarget()}`);
}
while (currentRule.rule) {
currentRule = currentRule.rule;
}
const targetRule = currentRule;
if (!Array.isArray(targetRule.classNames) || !targetRule.classNames.find(className => className === targetClassName)) {
throw new Error(dedent__default['default']`
Invalid selector: ${replaceTarget()}
Style selectors must end with the '&' character (along with any modifiers), e.g. ${'`${parent} &`'} or ${'`${parent} &:hover`'}.
This is to ensure that each style block only affects the styling of a single class.
If your selector is targeting another class, you should move it to the style definition for that class, e.g. given we have styles for 'parent' and 'child' elements, instead of adding a selector of ${'`& ${child}`'}) to 'parent', you should add ${'`${parent} &`'} to 'child').
If your selector is targeting something global, use the 'globalStyle' function instead, e.g. if you wanted to write ${'`& h1`'}, you should instead write 'globalStyle(${'`${parent} h1`'}, { ... })'
`);
}
});
};
const simplePseudos = [':-moz-any-link', ':-moz-full-screen', ':-moz-placeholder', ':-moz-read-only', ':-moz-read-write', ':-ms-fullscreen', ':-ms-input-placeholder', ':-webkit-any-link', ':-webkit-full-screen', '::-moz-placeholder', '::-moz-progress-bar', '::-moz-range-progress', '::-moz-range-thumb', '::-moz-range-track', '::-moz-selection', '::-ms-backdrop', '::-ms-browse', '::-ms-check', '::-ms-clear', '::-ms-fill', '::-ms-fill-lower', '::-ms-fill-upper', '::-ms-reveal', '::-ms-thumb', '::-ms-ticks-after', '::-ms-ticks-before', '::-ms-tooltip', '::-ms-track', '::-ms-value', '::-webkit-backdrop', '::-webkit-input-placeholder', '::-webkit-progress-bar', '::-webkit-progress-inner-value', '::-webkit-progress-value', '::-webkit-slider-runnable-track', '::-webkit-slider-thumb', '::after', '::backdrop', '::before', '::cue', '::first-letter', '::first-line', '::grammar-error', '::placeholder', '::selection', '::spelling-error', ':active', ':after', ':any-link', ':before', ':blank', ':checked', ':default', ':defined', ':disabled', ':empty', ':enabled', ':first', ':first-child', ':first-letter', ':first-line', ':first-of-type', ':focus', ':focus-visible', ':focus-within', ':fullscreen', ':hover', ':in-range', ':indeterminate', ':invalid', ':last-child', ':last-of-type', ':left', ':link', ':only-child', ':only-of-type', ':optional', ':out-of-range', ':placeholder-shown', ':read-only', ':read-write', ':required', ':right', ':root', ':scope', ':target', ':valid', ':visited'];
const simplePseudoSet = new Set(simplePseudos);
const specialKeys = [...simplePseudos, '@media', '@supports', 'selectors'];
class Stylesheet {
constructor(localClassNames) {
this.rules = [];
this.conditionalRules = [];
this.localClassNameRegex = localClassNames.length > 0 ? RegExp(`(^|[^\.])(${localClassNames.join('|')})`, 'g') : null;
}
processCssObj(root) {
// Add main styles
const mainRule = omit__default['default'](root.rule, specialKeys);
this.addRule({
selector: root.selector,
rule: mainRule
});
this.transformSimplePsuedos(root.rule, root.selector);
this.transformMedia(root.rule['@media'], root.selector);
this.transformSupports(root.rule['@supports'], root.selector);
this.transformSelectors(root.rule, root.selector);
}
addRule(cssRule) {
const rule = this.transformVars(this.transformRuleKeyframes(cssRule.rule));
const selector = this.transformSelector(cssRule.selector);
if (cssRule.conditions) {
this.conditionalRules.push({
selector,
rule,
conditions: cssRule.conditions.sort()
});
} else {
this.rules.push({
selector,
rule
});
}
}
transformVars({
vars,
...rest
}) {
if (!vars) {
return rest;
}
return { ...mapKeys__default['default'](vars, (_value, key) => {
const matches = key.match(/^var\((.*)\)$/);
if (matches) {
return matches[1];
}
return key;
}),
...rest
};
}
transformRuleKeyframes(rule) {
let {
'@keyframes': keyframes,
animation,
animationName,
...rest
} = rule;
if (!keyframes && !rule.animation && !rule.animationName) {
return rest;
}
let keyframesRef = typeof keyframes === 'string' ? keyframes : '';
if (keyframes && typeof keyframes !== 'string') {
keyframesRef = cssesc__default['default'](hash__default['default'](JSON.stringify(keyframes)), {
isIdentifier: true
}); // Hoist keyframes to the top of the stylesheet
this.rules.unshift({
selector: `@keyframes ${keyframesRef}`,
rule: keyframes
});
}
return { ...rest,
animation: animation && typeof animation === 'string' ? // @ts-expect-error Why???????????
animation.replace('@keyframes', keyframesRef) : animation,
animationName: animationName ? undefined : keyframesRef
};
}
transformSelector(selector) {
return this.localClassNameRegex ? selector.replace(this.localClassNameRegex, (_, leadingChar, className) => `${leadingChar}.${cssesc__default['default'](className, {
isIdentifier: true
})}`) : selector;
}
transformSelectors(rule, rootSelector, conditions) {
each__default['default'](rule.selectors, (selectorRule, selector) => {
const transformedSelector = this.transformSelector(selector.replace(RegExp('&', 'g'), rootSelector));
validateSelector(transformedSelector, rootSelector);
this.addRule({
conditions,
selector: transformedSelector,
rule: selectorRule
});
});
}
transformMedia(rules, rootSelector, parentConditions = []) {
each__default['default'](rules, (mediaRule, query) => {
const conditions = [`@media ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: rootSelector,
rule: omit__default['default'](mediaRule, specialKeys)
});
this.transformSimplePsuedos(mediaRule, rootSelector, conditions);
this.transformSelectors(mediaRule, rootSelector, conditions);
this.transformSupports(mediaRule['@supports'], rootSelector, conditions);
});
}
transformSupports(rules, rootSelector, parentConditions = []) {
each__default['default'](rules, (supportsRule, query) => {
const conditions = [`@supports ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: rootSelector,
rule: omit__default['default'](supportsRule, specialKeys)
});
this.transformSimplePsuedos(supportsRule, rootSelector, conditions);
this.transformSelectors(supportsRule, rootSelector, conditions);
this.transformMedia(supportsRule['@media'], rootSelector, conditions);
});
}
transformSimplePsuedos(rule, rootSelector, conditions) {
for (const key of Object.keys(rule)) {
// Process simple psuedos
if (simplePseudoSet.has(key)) {
this.addRule({
conditions,
selector: `${rootSelector}${key}`,
rule: rule[key]
});
}
}
}
toPostcssJs() {
const styles = {};
for (const rule of [...this.rules, ...this.conditionalRules]) {
if (rule.conditions && isEqual__default['default'](styles[rule.selector], rule.rule)) {
// Ignore conditional rules if they are identical to a non-conditional rule
continue;
}
if (Object.keys(rule.rule).length === 0) {
// Ignore empty rules
continue;
}
let styleNode = styles;
for (const condition of rule.conditions || []) {
if (!styleNode[condition]) {
styleNode[condition] = {};
}
styleNode = styleNode[condition];
}
styleNode[rule.selector] = { ...styleNode[rule.selector],
...rule.rule
};
}
return styles;
}
}
function transformCss({
localClassNames,
cssObjs
}) {
const stylesheet = new Stylesheet(localClassNames);
for (const root of cssObjs) {
stylesheet.processCssObj(root);
}
return stylesheet.toPostcssJs();
}
// @ts-expect-error
function generateCss({
localClassNames,
cssObjs
}) {
const flattenedCss = transformCss({
localClassNames,
cssObjs
});
const result = postcss__default['default']().process(flattenedCss, {
parser: postcssJs__default['default'],
from: undefined
});
return result.root.nodes.map(node => node.toString());
}
exports.generateCss = generateCss;

@@ -1,11 +0,291 @@

import 'postcss-js';
import 'postcss';
export { g as generateCss } from '../../dist/generateCss-a758bf8f.browser.esm.js';
import '@emotion/hash';
import 'lodash/each';
import 'lodash/omit';
import 'lodash/isEqual';
import 'lodash/mapKeys';
import 'css-selector-parser';
import 'dedent';
import '../../adapter/dist/mattsjones-css-core-adapter.browser.esm.js';
import postcssJs from 'postcss-js';
import postcss from 'postcss';
import cssesc from 'cssesc';
import hash from '@emotion/hash';
import each from 'lodash/each';
import omit from 'lodash/omit';
import isEqual from 'lodash/isEqual';
import mapKeys from 'lodash/mapKeys';
import { CssSelectorParser } from 'css-selector-parser';
import dedent from 'dedent';
function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
const parser = new CssSelectorParser();
parser.registerSelectorPseudos('has');
parser.registerNestingOperators('>', '+', '~');
parser.registerAttrEqualityMods('^', '$', '*', '~');
parser.enableSubstitutes();
const validateSelector = (selector, targetClassName) => {
const replaceTarget = () => {
const targetRegex = new RegExp(`.${escapeRegex(cssesc(targetClassName, {
isIdentifier: true
}))}`, 'g');
return selector.replace(targetRegex, '&');
};
return selector.split(',').map(selectorPart => {
if (selectorPart.indexOf(targetClassName) === -1) {
throw new Error(dedent`
Invalid selector: ${replaceTarget()}
Selectors must target the ampersand character ('&'), which refers to the generated class name, e.g. '&:nth-child(2n)'
`);
}
let currentRule;
try {
const result = parser.parse(selectorPart);
if (result.type === 'ruleSet') {
currentRule = result.rule;
} else {
throw new Error();
}
} catch (err) {
throw new Error(`Invalid selector: ${replaceTarget()}`);
}
while (currentRule.rule) {
currentRule = currentRule.rule;
}
const targetRule = currentRule;
if (!Array.isArray(targetRule.classNames) || !targetRule.classNames.find(className => className === targetClassName)) {
throw new Error(dedent`
Invalid selector: ${replaceTarget()}
Style selectors must end with the '&' character (along with any modifiers), e.g. ${'`${parent} &`'} or ${'`${parent} &:hover`'}.
This is to ensure that each style block only affects the styling of a single class.
If your selector is targeting another class, you should move it to the style definition for that class, e.g. given we have styles for 'parent' and 'child' elements, instead of adding a selector of ${'`& ${child}`'}) to 'parent', you should add ${'`${parent} &`'} to 'child').
If your selector is targeting something global, use the 'globalStyle' function instead, e.g. if you wanted to write ${'`& h1`'}, you should instead write 'globalStyle(${'`${parent} h1`'}, { ... })'
`);
}
});
};
const simplePseudos = [':-moz-any-link', ':-moz-full-screen', ':-moz-placeholder', ':-moz-read-only', ':-moz-read-write', ':-ms-fullscreen', ':-ms-input-placeholder', ':-webkit-any-link', ':-webkit-full-screen', '::-moz-placeholder', '::-moz-progress-bar', '::-moz-range-progress', '::-moz-range-thumb', '::-moz-range-track', '::-moz-selection', '::-ms-backdrop', '::-ms-browse', '::-ms-check', '::-ms-clear', '::-ms-fill', '::-ms-fill-lower', '::-ms-fill-upper', '::-ms-reveal', '::-ms-thumb', '::-ms-ticks-after', '::-ms-ticks-before', '::-ms-tooltip', '::-ms-track', '::-ms-value', '::-webkit-backdrop', '::-webkit-input-placeholder', '::-webkit-progress-bar', '::-webkit-progress-inner-value', '::-webkit-progress-value', '::-webkit-slider-runnable-track', '::-webkit-slider-thumb', '::after', '::backdrop', '::before', '::cue', '::first-letter', '::first-line', '::grammar-error', '::placeholder', '::selection', '::spelling-error', ':active', ':after', ':any-link', ':before', ':blank', ':checked', ':default', ':defined', ':disabled', ':empty', ':enabled', ':first', ':first-child', ':first-letter', ':first-line', ':first-of-type', ':focus', ':focus-visible', ':focus-within', ':fullscreen', ':hover', ':in-range', ':indeterminate', ':invalid', ':last-child', ':last-of-type', ':left', ':link', ':only-child', ':only-of-type', ':optional', ':out-of-range', ':placeholder-shown', ':read-only', ':read-write', ':required', ':right', ':root', ':scope', ':target', ':valid', ':visited'];
const simplePseudoSet = new Set(simplePseudos);
const specialKeys = [...simplePseudos, '@media', '@supports', 'selectors'];
class Stylesheet {
constructor(localClassNames) {
this.rules = [];
this.conditionalRules = [];
this.localClassNameRegex = localClassNames.length > 0 ? RegExp(`(^|[^\.])(${localClassNames.join('|')})`, 'g') : null;
}
processCssObj(root) {
// Add main styles
const mainRule = omit(root.rule, specialKeys);
this.addRule({
selector: root.selector,
rule: mainRule
});
this.transformSimplePsuedos(root.rule, root.selector);
this.transformMedia(root.rule['@media'], root.selector);
this.transformSupports(root.rule['@supports'], root.selector);
this.transformSelectors(root.rule, root.selector);
}
addRule(cssRule) {
const rule = this.transformVars(this.transformRuleKeyframes(cssRule.rule));
const selector = this.transformSelector(cssRule.selector);
if (cssRule.conditions) {
this.conditionalRules.push({
selector,
rule,
conditions: cssRule.conditions.sort()
});
} else {
this.rules.push({
selector,
rule
});
}
}
transformVars({
vars,
...rest
}) {
if (!vars) {
return rest;
}
return { ...mapKeys(vars, (_value, key) => {
const matches = key.match(/^var\((.*)\)$/);
if (matches) {
return matches[1];
}
return key;
}),
...rest
};
}
transformRuleKeyframes(rule) {
let {
'@keyframes': keyframes,
animation,
animationName,
...rest
} = rule;
if (!keyframes && !rule.animation && !rule.animationName) {
return rest;
}
let keyframesRef = typeof keyframes === 'string' ? keyframes : '';
if (keyframes && typeof keyframes !== 'string') {
keyframesRef = cssesc(hash(JSON.stringify(keyframes)), {
isIdentifier: true
}); // Hoist keyframes to the top of the stylesheet
this.rules.unshift({
selector: `@keyframes ${keyframesRef}`,
rule: keyframes
});
}
return { ...rest,
animation: animation && typeof animation === 'string' ? // @ts-expect-error Why???????????
animation.replace('@keyframes', keyframesRef) : animation,
animationName: animationName ? undefined : keyframesRef
};
}
transformSelector(selector) {
return this.localClassNameRegex ? selector.replace(this.localClassNameRegex, (_, leadingChar, className) => `${leadingChar}.${cssesc(className, {
isIdentifier: true
})}`) : selector;
}
transformSelectors(rule, rootSelector, conditions) {
each(rule.selectors, (selectorRule, selector) => {
const transformedSelector = this.transformSelector(selector.replace(RegExp('&', 'g'), rootSelector));
validateSelector(transformedSelector, rootSelector);
this.addRule({
conditions,
selector: transformedSelector,
rule: selectorRule
});
});
}
transformMedia(rules, rootSelector, parentConditions = []) {
each(rules, (mediaRule, query) => {
const conditions = [`@media ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: rootSelector,
rule: omit(mediaRule, specialKeys)
});
this.transformSimplePsuedos(mediaRule, rootSelector, conditions);
this.transformSelectors(mediaRule, rootSelector, conditions);
this.transformSupports(mediaRule['@supports'], rootSelector, conditions);
});
}
transformSupports(rules, rootSelector, parentConditions = []) {
each(rules, (supportsRule, query) => {
const conditions = [`@supports ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: rootSelector,
rule: omit(supportsRule, specialKeys)
});
this.transformSimplePsuedos(supportsRule, rootSelector, conditions);
this.transformSelectors(supportsRule, rootSelector, conditions);
this.transformMedia(supportsRule['@media'], rootSelector, conditions);
});
}
transformSimplePsuedos(rule, rootSelector, conditions) {
for (const key of Object.keys(rule)) {
// Process simple psuedos
if (simplePseudoSet.has(key)) {
this.addRule({
conditions,
selector: `${rootSelector}${key}`,
rule: rule[key]
});
}
}
}
toPostcssJs() {
const styles = {};
for (const rule of [...this.rules, ...this.conditionalRules]) {
if (rule.conditions && isEqual(styles[rule.selector], rule.rule)) {
// Ignore conditional rules if they are identical to a non-conditional rule
continue;
}
if (Object.keys(rule.rule).length === 0) {
// Ignore empty rules
continue;
}
let styleNode = styles;
for (const condition of rule.conditions || []) {
if (!styleNode[condition]) {
styleNode[condition] = {};
}
styleNode = styleNode[condition];
}
styleNode[rule.selector] = { ...styleNode[rule.selector],
...rule.rule
};
}
return styles;
}
}
function transformCss({
localClassNames,
cssObjs
}) {
const stylesheet = new Stylesheet(localClassNames);
for (const root of cssObjs) {
stylesheet.processCssObj(root);
}
return stylesheet.toPostcssJs();
}
// @ts-expect-error
function generateCss({
localClassNames,
cssObjs
}) {
const flattenedCss = transformCss({
localClassNames,
cssObjs
});
const result = postcss().process(flattenedCss, {
parser: postcssJs,
from: undefined
});
return result.root.nodes.map(node => node.toString());
}
export { generateCss };

@@ -5,16 +5,304 @@ 'use strict';

require('postcss-js');
require('postcss');
var generateCss_dist_mattsjonesCssCoreGenerateCss = require('../../dist/generateCss-35f6aedf.cjs.dev.js');
require('@emotion/hash');
require('lodash/each');
require('lodash/omit');
require('lodash/isEqual');
require('lodash/mapKeys');
require('css-selector-parser');
require('dedent');
require('../../adapter/dist/mattsjones-css-core-adapter.cjs.dev.js');
var postcssJs = require('postcss-js');
var postcss = require('postcss');
var cssesc = require('cssesc');
var hash = require('@emotion/hash');
var each = require('lodash/each');
var omit = require('lodash/omit');
var isEqual = require('lodash/isEqual');
var mapKeys = require('lodash/mapKeys');
var cssSelectorParser = require('css-selector-parser');
var dedent = require('dedent');
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
var postcssJs__default = /*#__PURE__*/_interopDefault(postcssJs);
var postcss__default = /*#__PURE__*/_interopDefault(postcss);
var cssesc__default = /*#__PURE__*/_interopDefault(cssesc);
var hash__default = /*#__PURE__*/_interopDefault(hash);
var each__default = /*#__PURE__*/_interopDefault(each);
var omit__default = /*#__PURE__*/_interopDefault(omit);
var isEqual__default = /*#__PURE__*/_interopDefault(isEqual);
var mapKeys__default = /*#__PURE__*/_interopDefault(mapKeys);
var dedent__default = /*#__PURE__*/_interopDefault(dedent);
exports.generateCss = generateCss_dist_mattsjonesCssCoreGenerateCss.generateCss;
function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
const parser = new cssSelectorParser.CssSelectorParser();
parser.registerSelectorPseudos('has');
parser.registerNestingOperators('>', '+', '~');
parser.registerAttrEqualityMods('^', '$', '*', '~');
parser.enableSubstitutes();
const validateSelector = (selector, targetClassName) => {
const replaceTarget = () => {
const targetRegex = new RegExp(`.${escapeRegex(cssesc__default['default'](targetClassName, {
isIdentifier: true
}))}`, 'g');
return selector.replace(targetRegex, '&');
};
return selector.split(',').map(selectorPart => {
if (selectorPart.indexOf(targetClassName) === -1) {
throw new Error(dedent__default['default']`
Invalid selector: ${replaceTarget()}
Selectors must target the ampersand character ('&'), which refers to the generated class name, e.g. '&:nth-child(2n)'
`);
}
let currentRule;
try {
const result = parser.parse(selectorPart);
if (result.type === 'ruleSet') {
currentRule = result.rule;
} else {
throw new Error();
}
} catch (err) {
throw new Error(`Invalid selector: ${replaceTarget()}`);
}
while (currentRule.rule) {
currentRule = currentRule.rule;
}
const targetRule = currentRule;
if (!Array.isArray(targetRule.classNames) || !targetRule.classNames.find(className => className === targetClassName)) {
throw new Error(dedent__default['default']`
Invalid selector: ${replaceTarget()}
Style selectors must end with the '&' character (along with any modifiers), e.g. ${'`${parent} &`'} or ${'`${parent} &:hover`'}.
This is to ensure that each style block only affects the styling of a single class.
If your selector is targeting another class, you should move it to the style definition for that class, e.g. given we have styles for 'parent' and 'child' elements, instead of adding a selector of ${'`& ${child}`'}) to 'parent', you should add ${'`${parent} &`'} to 'child').
If your selector is targeting something global, use the 'globalStyle' function instead, e.g. if you wanted to write ${'`& h1`'}, you should instead write 'globalStyle(${'`${parent} h1`'}, { ... })'
`);
}
});
};
const simplePseudos = [':-moz-any-link', ':-moz-full-screen', ':-moz-placeholder', ':-moz-read-only', ':-moz-read-write', ':-ms-fullscreen', ':-ms-input-placeholder', ':-webkit-any-link', ':-webkit-full-screen', '::-moz-placeholder', '::-moz-progress-bar', '::-moz-range-progress', '::-moz-range-thumb', '::-moz-range-track', '::-moz-selection', '::-ms-backdrop', '::-ms-browse', '::-ms-check', '::-ms-clear', '::-ms-fill', '::-ms-fill-lower', '::-ms-fill-upper', '::-ms-reveal', '::-ms-thumb', '::-ms-ticks-after', '::-ms-ticks-before', '::-ms-tooltip', '::-ms-track', '::-ms-value', '::-webkit-backdrop', '::-webkit-input-placeholder', '::-webkit-progress-bar', '::-webkit-progress-inner-value', '::-webkit-progress-value', '::-webkit-slider-runnable-track', '::-webkit-slider-thumb', '::after', '::backdrop', '::before', '::cue', '::first-letter', '::first-line', '::grammar-error', '::placeholder', '::selection', '::spelling-error', ':active', ':after', ':any-link', ':before', ':blank', ':checked', ':default', ':defined', ':disabled', ':empty', ':enabled', ':first', ':first-child', ':first-letter', ':first-line', ':first-of-type', ':focus', ':focus-visible', ':focus-within', ':fullscreen', ':hover', ':in-range', ':indeterminate', ':invalid', ':last-child', ':last-of-type', ':left', ':link', ':only-child', ':only-of-type', ':optional', ':out-of-range', ':placeholder-shown', ':read-only', ':read-write', ':required', ':right', ':root', ':scope', ':target', ':valid', ':visited'];
const simplePseudoSet = new Set(simplePseudos);
const specialKeys = [...simplePseudos, '@media', '@supports', 'selectors'];
class Stylesheet {
constructor(localClassNames) {
this.rules = [];
this.conditionalRules = [];
this.localClassNameRegex = localClassNames.length > 0 ? RegExp(`(^|[^\.])(${localClassNames.join('|')})`, 'g') : null;
}
processCssObj(root) {
// Add main styles
const mainRule = omit__default['default'](root.rule, specialKeys);
this.addRule({
selector: root.selector,
rule: mainRule
});
this.transformSimplePsuedos(root.rule, root.selector);
this.transformMedia(root.rule['@media'], root.selector);
this.transformSupports(root.rule['@supports'], root.selector);
this.transformSelectors(root.rule, root.selector);
}
addRule(cssRule) {
const rule = this.transformVars(this.transformRuleKeyframes(cssRule.rule));
const selector = this.transformSelector(cssRule.selector);
if (cssRule.conditions) {
this.conditionalRules.push({
selector,
rule,
conditions: cssRule.conditions.sort()
});
} else {
this.rules.push({
selector,
rule
});
}
}
transformVars({
vars,
...rest
}) {
if (!vars) {
return rest;
}
return { ...mapKeys__default['default'](vars, (_value, key) => {
const matches = key.match(/^var\((.*)\)$/);
if (matches) {
return matches[1];
}
return key;
}),
...rest
};
}
transformRuleKeyframes(rule) {
let {
'@keyframes': keyframes,
animation,
animationName,
...rest
} = rule;
if (!keyframes && !rule.animation && !rule.animationName) {
return rest;
}
let keyframesRef = typeof keyframes === 'string' ? keyframes : '';
if (keyframes && typeof keyframes !== 'string') {
keyframesRef = cssesc__default['default'](hash__default['default'](JSON.stringify(keyframes)), {
isIdentifier: true
}); // Hoist keyframes to the top of the stylesheet
this.rules.unshift({
selector: `@keyframes ${keyframesRef}`,
rule: keyframes
});
}
return { ...rest,
animation: animation && typeof animation === 'string' ? // @ts-expect-error Why???????????
animation.replace('@keyframes', keyframesRef) : animation,
animationName: animationName ? undefined : keyframesRef
};
}
transformSelector(selector) {
return this.localClassNameRegex ? selector.replace(this.localClassNameRegex, (_, leadingChar, className) => `${leadingChar}.${cssesc__default['default'](className, {
isIdentifier: true
})}`) : selector;
}
transformSelectors(rule, rootSelector, conditions) {
each__default['default'](rule.selectors, (selectorRule, selector) => {
const transformedSelector = this.transformSelector(selector.replace(RegExp('&', 'g'), rootSelector));
validateSelector(transformedSelector, rootSelector);
this.addRule({
conditions,
selector: transformedSelector,
rule: selectorRule
});
});
}
transformMedia(rules, rootSelector, parentConditions = []) {
each__default['default'](rules, (mediaRule, query) => {
const conditions = [`@media ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: rootSelector,
rule: omit__default['default'](mediaRule, specialKeys)
});
this.transformSimplePsuedos(mediaRule, rootSelector, conditions);
this.transformSelectors(mediaRule, rootSelector, conditions);
this.transformSupports(mediaRule['@supports'], rootSelector, conditions);
});
}
transformSupports(rules, rootSelector, parentConditions = []) {
each__default['default'](rules, (supportsRule, query) => {
const conditions = [`@supports ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: rootSelector,
rule: omit__default['default'](supportsRule, specialKeys)
});
this.transformSimplePsuedos(supportsRule, rootSelector, conditions);
this.transformSelectors(supportsRule, rootSelector, conditions);
this.transformMedia(supportsRule['@media'], rootSelector, conditions);
});
}
transformSimplePsuedos(rule, rootSelector, conditions) {
for (const key of Object.keys(rule)) {
// Process simple psuedos
if (simplePseudoSet.has(key)) {
this.addRule({
conditions,
selector: `${rootSelector}${key}`,
rule: rule[key]
});
}
}
}
toPostcssJs() {
const styles = {};
for (const rule of [...this.rules, ...this.conditionalRules]) {
if (rule.conditions && isEqual__default['default'](styles[rule.selector], rule.rule)) {
// Ignore conditional rules if they are identical to a non-conditional rule
continue;
}
if (Object.keys(rule.rule).length === 0) {
// Ignore empty rules
continue;
}
let styleNode = styles;
for (const condition of rule.conditions || []) {
if (!styleNode[condition]) {
styleNode[condition] = {};
}
styleNode = styleNode[condition];
}
styleNode[rule.selector] = { ...styleNode[rule.selector],
...rule.rule
};
}
return styles;
}
}
function transformCss({
localClassNames,
cssObjs
}) {
const stylesheet = new Stylesheet(localClassNames);
for (const root of cssObjs) {
stylesheet.processCssObj(root);
}
return stylesheet.toPostcssJs();
}
// @ts-expect-error
function generateCss({
localClassNames,
cssObjs
}) {
const flattenedCss = transformCss({
localClassNames,
cssObjs
});
const result = postcss__default['default']().process(flattenedCss, {
parser: postcssJs__default['default'],
from: undefined
});
return result.root.nodes.map(node => node.toString());
}
exports.generateCss = generateCss;

@@ -5,16 +5,304 @@ 'use strict';

require('postcss-js');
require('postcss');
var generateCss_dist_mattsjonesCssCoreGenerateCss = require('../../dist/generateCss-0e42352c.cjs.prod.js');
require('@emotion/hash');
require('lodash/each');
require('lodash/omit');
require('lodash/isEqual');
require('lodash/mapKeys');
require('css-selector-parser');
require('dedent');
require('../../adapter/dist/mattsjones-css-core-adapter.cjs.prod.js');
var postcssJs = require('postcss-js');
var postcss = require('postcss');
var cssesc = require('cssesc');
var hash = require('@emotion/hash');
var each = require('lodash/each');
var omit = require('lodash/omit');
var isEqual = require('lodash/isEqual');
var mapKeys = require('lodash/mapKeys');
var cssSelectorParser = require('css-selector-parser');
var dedent = require('dedent');
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
var postcssJs__default = /*#__PURE__*/_interopDefault(postcssJs);
var postcss__default = /*#__PURE__*/_interopDefault(postcss);
var cssesc__default = /*#__PURE__*/_interopDefault(cssesc);
var hash__default = /*#__PURE__*/_interopDefault(hash);
var each__default = /*#__PURE__*/_interopDefault(each);
var omit__default = /*#__PURE__*/_interopDefault(omit);
var isEqual__default = /*#__PURE__*/_interopDefault(isEqual);
var mapKeys__default = /*#__PURE__*/_interopDefault(mapKeys);
var dedent__default = /*#__PURE__*/_interopDefault(dedent);
exports.generateCss = generateCss_dist_mattsjonesCssCoreGenerateCss.generateCss;
function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
const parser = new cssSelectorParser.CssSelectorParser();
parser.registerSelectorPseudos('has');
parser.registerNestingOperators('>', '+', '~');
parser.registerAttrEqualityMods('^', '$', '*', '~');
parser.enableSubstitutes();
const validateSelector = (selector, targetClassName) => {
const replaceTarget = () => {
const targetRegex = new RegExp(`.${escapeRegex(cssesc__default['default'](targetClassName, {
isIdentifier: true
}))}`, 'g');
return selector.replace(targetRegex, '&');
};
return selector.split(',').map(selectorPart => {
if (selectorPart.indexOf(targetClassName) === -1) {
throw new Error(dedent__default['default']`
Invalid selector: ${replaceTarget()}
Selectors must target the ampersand character ('&'), which refers to the generated class name, e.g. '&:nth-child(2n)'
`);
}
let currentRule;
try {
const result = parser.parse(selectorPart);
if (result.type === 'ruleSet') {
currentRule = result.rule;
} else {
throw new Error();
}
} catch (err) {
throw new Error(`Invalid selector: ${replaceTarget()}`);
}
while (currentRule.rule) {
currentRule = currentRule.rule;
}
const targetRule = currentRule;
if (!Array.isArray(targetRule.classNames) || !targetRule.classNames.find(className => className === targetClassName)) {
throw new Error(dedent__default['default']`
Invalid selector: ${replaceTarget()}
Style selectors must end with the '&' character (along with any modifiers), e.g. ${'`${parent} &`'} or ${'`${parent} &:hover`'}.
This is to ensure that each style block only affects the styling of a single class.
If your selector is targeting another class, you should move it to the style definition for that class, e.g. given we have styles for 'parent' and 'child' elements, instead of adding a selector of ${'`& ${child}`'}) to 'parent', you should add ${'`${parent} &`'} to 'child').
If your selector is targeting something global, use the 'globalStyle' function instead, e.g. if you wanted to write ${'`& h1`'}, you should instead write 'globalStyle(${'`${parent} h1`'}, { ... })'
`);
}
});
};
const simplePseudos = [':-moz-any-link', ':-moz-full-screen', ':-moz-placeholder', ':-moz-read-only', ':-moz-read-write', ':-ms-fullscreen', ':-ms-input-placeholder', ':-webkit-any-link', ':-webkit-full-screen', '::-moz-placeholder', '::-moz-progress-bar', '::-moz-range-progress', '::-moz-range-thumb', '::-moz-range-track', '::-moz-selection', '::-ms-backdrop', '::-ms-browse', '::-ms-check', '::-ms-clear', '::-ms-fill', '::-ms-fill-lower', '::-ms-fill-upper', '::-ms-reveal', '::-ms-thumb', '::-ms-ticks-after', '::-ms-ticks-before', '::-ms-tooltip', '::-ms-track', '::-ms-value', '::-webkit-backdrop', '::-webkit-input-placeholder', '::-webkit-progress-bar', '::-webkit-progress-inner-value', '::-webkit-progress-value', '::-webkit-slider-runnable-track', '::-webkit-slider-thumb', '::after', '::backdrop', '::before', '::cue', '::first-letter', '::first-line', '::grammar-error', '::placeholder', '::selection', '::spelling-error', ':active', ':after', ':any-link', ':before', ':blank', ':checked', ':default', ':defined', ':disabled', ':empty', ':enabled', ':first', ':first-child', ':first-letter', ':first-line', ':first-of-type', ':focus', ':focus-visible', ':focus-within', ':fullscreen', ':hover', ':in-range', ':indeterminate', ':invalid', ':last-child', ':last-of-type', ':left', ':link', ':only-child', ':only-of-type', ':optional', ':out-of-range', ':placeholder-shown', ':read-only', ':read-write', ':required', ':right', ':root', ':scope', ':target', ':valid', ':visited'];
const simplePseudoSet = new Set(simplePseudos);
const specialKeys = [...simplePseudos, '@media', '@supports', 'selectors'];
class Stylesheet {
constructor(localClassNames) {
this.rules = [];
this.conditionalRules = [];
this.localClassNameRegex = localClassNames.length > 0 ? RegExp(`(^|[^\.])(${localClassNames.join('|')})`, 'g') : null;
}
processCssObj(root) {
// Add main styles
const mainRule = omit__default['default'](root.rule, specialKeys);
this.addRule({
selector: root.selector,
rule: mainRule
});
this.transformSimplePsuedos(root.rule, root.selector);
this.transformMedia(root.rule['@media'], root.selector);
this.transformSupports(root.rule['@supports'], root.selector);
this.transformSelectors(root.rule, root.selector);
}
addRule(cssRule) {
const rule = this.transformVars(this.transformRuleKeyframes(cssRule.rule));
const selector = this.transformSelector(cssRule.selector);
if (cssRule.conditions) {
this.conditionalRules.push({
selector,
rule,
conditions: cssRule.conditions.sort()
});
} else {
this.rules.push({
selector,
rule
});
}
}
transformVars({
vars,
...rest
}) {
if (!vars) {
return rest;
}
return { ...mapKeys__default['default'](vars, (_value, key) => {
const matches = key.match(/^var\((.*)\)$/);
if (matches) {
return matches[1];
}
return key;
}),
...rest
};
}
transformRuleKeyframes(rule) {
let {
'@keyframes': keyframes,
animation,
animationName,
...rest
} = rule;
if (!keyframes && !rule.animation && !rule.animationName) {
return rest;
}
let keyframesRef = typeof keyframes === 'string' ? keyframes : '';
if (keyframes && typeof keyframes !== 'string') {
keyframesRef = cssesc__default['default'](hash__default['default'](JSON.stringify(keyframes)), {
isIdentifier: true
}); // Hoist keyframes to the top of the stylesheet
this.rules.unshift({
selector: `@keyframes ${keyframesRef}`,
rule: keyframes
});
}
return { ...rest,
animation: animation && typeof animation === 'string' ? // @ts-expect-error Why???????????
animation.replace('@keyframes', keyframesRef) : animation,
animationName: animationName ? undefined : keyframesRef
};
}
transformSelector(selector) {
return this.localClassNameRegex ? selector.replace(this.localClassNameRegex, (_, leadingChar, className) => `${leadingChar}.${cssesc__default['default'](className, {
isIdentifier: true
})}`) : selector;
}
transformSelectors(rule, rootSelector, conditions) {
each__default['default'](rule.selectors, (selectorRule, selector) => {
const transformedSelector = this.transformSelector(selector.replace(RegExp('&', 'g'), rootSelector));
validateSelector(transformedSelector, rootSelector);
this.addRule({
conditions,
selector: transformedSelector,
rule: selectorRule
});
});
}
transformMedia(rules, rootSelector, parentConditions = []) {
each__default['default'](rules, (mediaRule, query) => {
const conditions = [`@media ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: rootSelector,
rule: omit__default['default'](mediaRule, specialKeys)
});
this.transformSimplePsuedos(mediaRule, rootSelector, conditions);
this.transformSelectors(mediaRule, rootSelector, conditions);
this.transformSupports(mediaRule['@supports'], rootSelector, conditions);
});
}
transformSupports(rules, rootSelector, parentConditions = []) {
each__default['default'](rules, (supportsRule, query) => {
const conditions = [`@supports ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: rootSelector,
rule: omit__default['default'](supportsRule, specialKeys)
});
this.transformSimplePsuedos(supportsRule, rootSelector, conditions);
this.transformSelectors(supportsRule, rootSelector, conditions);
this.transformMedia(supportsRule['@media'], rootSelector, conditions);
});
}
transformSimplePsuedos(rule, rootSelector, conditions) {
for (const key of Object.keys(rule)) {
// Process simple psuedos
if (simplePseudoSet.has(key)) {
this.addRule({
conditions,
selector: `${rootSelector}${key}`,
rule: rule[key]
});
}
}
}
toPostcssJs() {
const styles = {};
for (const rule of [...this.rules, ...this.conditionalRules]) {
if (rule.conditions && isEqual__default['default'](styles[rule.selector], rule.rule)) {
// Ignore conditional rules if they are identical to a non-conditional rule
continue;
}
if (Object.keys(rule.rule).length === 0) {
// Ignore empty rules
continue;
}
let styleNode = styles;
for (const condition of rule.conditions || []) {
if (!styleNode[condition]) {
styleNode[condition] = {};
}
styleNode = styleNode[condition];
}
styleNode[rule.selector] = { ...styleNode[rule.selector],
...rule.rule
};
}
return styles;
}
}
function transformCss({
localClassNames,
cssObjs
}) {
const stylesheet = new Stylesheet(localClassNames);
for (const root of cssObjs) {
stylesheet.processCssObj(root);
}
return stylesheet.toPostcssJs();
}
// @ts-expect-error
function generateCss({
localClassNames,
cssObjs
}) {
const flattenedCss = transformCss({
localClassNames,
cssObjs
});
const result = postcss__default['default']().process(flattenedCss, {
parser: postcssJs__default['default'],
from: undefined
});
return result.root.nodes.map(node => node.toString());
}
exports.generateCss = generateCss;

@@ -1,11 +0,291 @@

import 'postcss-js';
import 'postcss';
export { g as generateCss } from '../../dist/generateCss-addefd6f.esm.js';
import '@emotion/hash';
import 'lodash/each';
import 'lodash/omit';
import 'lodash/isEqual';
import 'lodash/mapKeys';
import 'css-selector-parser';
import 'dedent';
import '../../adapter/dist/mattsjones-css-core-adapter.esm.js';
import postcssJs from 'postcss-js';
import postcss from 'postcss';
import cssesc from 'cssesc';
import hash from '@emotion/hash';
import each from 'lodash/each';
import omit from 'lodash/omit';
import isEqual from 'lodash/isEqual';
import mapKeys from 'lodash/mapKeys';
import { CssSelectorParser } from 'css-selector-parser';
import dedent from 'dedent';
function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
const parser = new CssSelectorParser();
parser.registerSelectorPseudos('has');
parser.registerNestingOperators('>', '+', '~');
parser.registerAttrEqualityMods('^', '$', '*', '~');
parser.enableSubstitutes();
const validateSelector = (selector, targetClassName) => {
const replaceTarget = () => {
const targetRegex = new RegExp(`.${escapeRegex(cssesc(targetClassName, {
isIdentifier: true
}))}`, 'g');
return selector.replace(targetRegex, '&');
};
return selector.split(',').map(selectorPart => {
if (selectorPart.indexOf(targetClassName) === -1) {
throw new Error(dedent`
Invalid selector: ${replaceTarget()}
Selectors must target the ampersand character ('&'), which refers to the generated class name, e.g. '&:nth-child(2n)'
`);
}
let currentRule;
try {
const result = parser.parse(selectorPart);
if (result.type === 'ruleSet') {
currentRule = result.rule;
} else {
throw new Error();
}
} catch (err) {
throw new Error(`Invalid selector: ${replaceTarget()}`);
}
while (currentRule.rule) {
currentRule = currentRule.rule;
}
const targetRule = currentRule;
if (!Array.isArray(targetRule.classNames) || !targetRule.classNames.find(className => className === targetClassName)) {
throw new Error(dedent`
Invalid selector: ${replaceTarget()}
Style selectors must end with the '&' character (along with any modifiers), e.g. ${'`${parent} &`'} or ${'`${parent} &:hover`'}.
This is to ensure that each style block only affects the styling of a single class.
If your selector is targeting another class, you should move it to the style definition for that class, e.g. given we have styles for 'parent' and 'child' elements, instead of adding a selector of ${'`& ${child}`'}) to 'parent', you should add ${'`${parent} &`'} to 'child').
If your selector is targeting something global, use the 'globalStyle' function instead, e.g. if you wanted to write ${'`& h1`'}, you should instead write 'globalStyle(${'`${parent} h1`'}, { ... })'
`);
}
});
};
const simplePseudos = [':-moz-any-link', ':-moz-full-screen', ':-moz-placeholder', ':-moz-read-only', ':-moz-read-write', ':-ms-fullscreen', ':-ms-input-placeholder', ':-webkit-any-link', ':-webkit-full-screen', '::-moz-placeholder', '::-moz-progress-bar', '::-moz-range-progress', '::-moz-range-thumb', '::-moz-range-track', '::-moz-selection', '::-ms-backdrop', '::-ms-browse', '::-ms-check', '::-ms-clear', '::-ms-fill', '::-ms-fill-lower', '::-ms-fill-upper', '::-ms-reveal', '::-ms-thumb', '::-ms-ticks-after', '::-ms-ticks-before', '::-ms-tooltip', '::-ms-track', '::-ms-value', '::-webkit-backdrop', '::-webkit-input-placeholder', '::-webkit-progress-bar', '::-webkit-progress-inner-value', '::-webkit-progress-value', '::-webkit-slider-runnable-track', '::-webkit-slider-thumb', '::after', '::backdrop', '::before', '::cue', '::first-letter', '::first-line', '::grammar-error', '::placeholder', '::selection', '::spelling-error', ':active', ':after', ':any-link', ':before', ':blank', ':checked', ':default', ':defined', ':disabled', ':empty', ':enabled', ':first', ':first-child', ':first-letter', ':first-line', ':first-of-type', ':focus', ':focus-visible', ':focus-within', ':fullscreen', ':hover', ':in-range', ':indeterminate', ':invalid', ':last-child', ':last-of-type', ':left', ':link', ':only-child', ':only-of-type', ':optional', ':out-of-range', ':placeholder-shown', ':read-only', ':read-write', ':required', ':right', ':root', ':scope', ':target', ':valid', ':visited'];
const simplePseudoSet = new Set(simplePseudos);
const specialKeys = [...simplePseudos, '@media', '@supports', 'selectors'];
class Stylesheet {
constructor(localClassNames) {
this.rules = [];
this.conditionalRules = [];
this.localClassNameRegex = localClassNames.length > 0 ? RegExp(`(^|[^\.])(${localClassNames.join('|')})`, 'g') : null;
}
processCssObj(root) {
// Add main styles
const mainRule = omit(root.rule, specialKeys);
this.addRule({
selector: root.selector,
rule: mainRule
});
this.transformSimplePsuedos(root.rule, root.selector);
this.transformMedia(root.rule['@media'], root.selector);
this.transformSupports(root.rule['@supports'], root.selector);
this.transformSelectors(root.rule, root.selector);
}
addRule(cssRule) {
const rule = this.transformVars(this.transformRuleKeyframes(cssRule.rule));
const selector = this.transformSelector(cssRule.selector);
if (cssRule.conditions) {
this.conditionalRules.push({
selector,
rule,
conditions: cssRule.conditions.sort()
});
} else {
this.rules.push({
selector,
rule
});
}
}
transformVars({
vars,
...rest
}) {
if (!vars) {
return rest;
}
return { ...mapKeys(vars, (_value, key) => {
const matches = key.match(/^var\((.*)\)$/);
if (matches) {
return matches[1];
}
return key;
}),
...rest
};
}
transformRuleKeyframes(rule) {
let {
'@keyframes': keyframes,
animation,
animationName,
...rest
} = rule;
if (!keyframes && !rule.animation && !rule.animationName) {
return rest;
}
let keyframesRef = typeof keyframes === 'string' ? keyframes : '';
if (keyframes && typeof keyframes !== 'string') {
keyframesRef = cssesc(hash(JSON.stringify(keyframes)), {
isIdentifier: true
}); // Hoist keyframes to the top of the stylesheet
this.rules.unshift({
selector: `@keyframes ${keyframesRef}`,
rule: keyframes
});
}
return { ...rest,
animation: animation && typeof animation === 'string' ? // @ts-expect-error Why???????????
animation.replace('@keyframes', keyframesRef) : animation,
animationName: animationName ? undefined : keyframesRef
};
}
transformSelector(selector) {
return this.localClassNameRegex ? selector.replace(this.localClassNameRegex, (_, leadingChar, className) => `${leadingChar}.${cssesc(className, {
isIdentifier: true
})}`) : selector;
}
transformSelectors(rule, rootSelector, conditions) {
each(rule.selectors, (selectorRule, selector) => {
const transformedSelector = this.transformSelector(selector.replace(RegExp('&', 'g'), rootSelector));
validateSelector(transformedSelector, rootSelector);
this.addRule({
conditions,
selector: transformedSelector,
rule: selectorRule
});
});
}
transformMedia(rules, rootSelector, parentConditions = []) {
each(rules, (mediaRule, query) => {
const conditions = [`@media ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: rootSelector,
rule: omit(mediaRule, specialKeys)
});
this.transformSimplePsuedos(mediaRule, rootSelector, conditions);
this.transformSelectors(mediaRule, rootSelector, conditions);
this.transformSupports(mediaRule['@supports'], rootSelector, conditions);
});
}
transformSupports(rules, rootSelector, parentConditions = []) {
each(rules, (supportsRule, query) => {
const conditions = [`@supports ${query}`, ...parentConditions];
this.addRule({
conditions,
selector: rootSelector,
rule: omit(supportsRule, specialKeys)
});
this.transformSimplePsuedos(supportsRule, rootSelector, conditions);
this.transformSelectors(supportsRule, rootSelector, conditions);
this.transformMedia(supportsRule['@media'], rootSelector, conditions);
});
}
transformSimplePsuedos(rule, rootSelector, conditions) {
for (const key of Object.keys(rule)) {
// Process simple psuedos
if (simplePseudoSet.has(key)) {
this.addRule({
conditions,
selector: `${rootSelector}${key}`,
rule: rule[key]
});
}
}
}
toPostcssJs() {
const styles = {};
for (const rule of [...this.rules, ...this.conditionalRules]) {
if (rule.conditions && isEqual(styles[rule.selector], rule.rule)) {
// Ignore conditional rules if they are identical to a non-conditional rule
continue;
}
if (Object.keys(rule.rule).length === 0) {
// Ignore empty rules
continue;
}
let styleNode = styles;
for (const condition of rule.conditions || []) {
if (!styleNode[condition]) {
styleNode[condition] = {};
}
styleNode = styleNode[condition];
}
styleNode[rule.selector] = { ...styleNode[rule.selector],
...rule.rule
};
}
return styles;
}
}
function transformCss({
localClassNames,
cssObjs
}) {
const stylesheet = new Stylesheet(localClassNames);
for (const root of cssObjs) {
stylesheet.processCssObj(root);
}
return stylesheet.toPostcssJs();
}
// @ts-expect-error
function generateCss({
localClassNames,
cssObjs
}) {
const flattenedCss = transformCss({
localClassNames,
cssObjs
});
const result = postcss().process(flattenedCss, {
parser: postcssJs,
from: undefined
});
return result.root.nodes.map(node => node.toString());
}
export { generateCss };
{
"name": "@mattsjones/css-core",
"version": "0.0.10",
"version": "0.0.11",
"main": "dist/mattsjones-css-core.cjs.js",

@@ -29,2 +29,3 @@ "module": "dist/mattsjones-css-core.esm.js",

"css-selector-parser": "^1.4.1",
"cssesc": "^3.0.0",
"csstype": "^3.0.7",

@@ -37,2 +38,3 @@ "dedent": "^0.7.0",

"devDependencies": {
"@types/cssesc": "^3.0.0",
"@types/dedent": "^0.7.0",

@@ -39,0 +41,0 @@ "@types/lodash": "^4.14.168"

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc