This commit is contained in:
Aevann1 2021-12-13 22:28:32 +00:00
parent 628618df89
commit e031240dff
3749 changed files with 1120848 additions and 1 deletions

View file

@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = applyImportantConfiguration;
function applyImportantConfiguration(_config) {
return function (css) {
css.walkRules(rule => {
const important = rule.__tailwind ? rule.__tailwind.important : false;
if (!important) {
return;
}
if (typeof important === 'string') {
rule.selectors = rule.selectors.map(selector => {
return `${rule.__tailwind.important} ${selector}`;
});
} else {
rule.walkDecls(decl => decl.important = true);
}
});
};
}

View file

@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = convertLayerAtRulesToControlComments;
var _postcss = _interopRequireDefault(require("postcss"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function convertLayerAtRulesToControlComments() {
return function (css) {
css.walkAtRules('layer', atRule => {
const layer = atRule.params;
if (!['base', 'components', 'utilities'].includes(layer)) {
return;
}
atRule.before(_postcss.default.comment({
text: `tailwind start ${layer}`
}));
atRule.before(atRule.nodes);
atRule.before(_postcss.default.comment({
text: `tailwind end ${layer}`
}));
atRule.remove();
});
};
}

View file

@ -0,0 +1,188 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
var _lodash = _interopRequireDefault(require("lodash"));
var _didyoumean = _interopRequireDefault(require("didyoumean"));
var _transformThemeValue = _interopRequireDefault(require("../util/transformThemeValue"));
var _postcssValueParser = _interopRequireDefault(require("postcss-value-parser"));
var _buildMediaQuery = _interopRequireDefault(require("../util/buildMediaQuery"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function findClosestExistingPath(theme, path) {
const parts = _lodash.default.toPath(path);
do {
parts.pop();
if (_lodash.default.hasIn(theme, parts)) break;
} while (parts.length);
return parts.length ? parts : undefined;
}
function pathToString(path) {
if (typeof path === 'string') return path;
return path.reduce((acc, cur, i) => {
if (cur.includes('.')) return `${acc}[${cur}]`;
return i === 0 ? cur : `${acc}.${cur}`;
}, '');
}
function list(items) {
return items.map(key => `'${key}'`).join(', ');
}
function listKeys(obj) {
return list(Object.keys(obj));
}
function validatePath(config, path, defaultValue) {
const pathString = Array.isArray(path) ? pathToString(path) : _lodash.default.trim(path, `'"`);
const pathSegments = Array.isArray(path) ? path : _lodash.default.toPath(pathString);
const value = _lodash.default.get(config.theme, pathString, defaultValue);
if (typeof value === 'undefined') {
let error = `'${pathString}' does not exist in your theme config.`;
const parentSegments = pathSegments.slice(0, -1);
const parentValue = _lodash.default.get(config.theme, parentSegments);
if (_lodash.default.isObject(parentValue)) {
const validKeys = Object.keys(parentValue).filter(key => validatePath(config, [...parentSegments, key]).isValid);
const suggestion = (0, _didyoumean.default)(_lodash.default.last(pathSegments), validKeys);
if (suggestion) {
error += ` Did you mean '${pathToString([...parentSegments, suggestion])}'?`;
} else if (validKeys.length > 0) {
error += ` '${pathToString(parentSegments)}' has the following valid keys: ${list(validKeys)}`;
}
} else {
const closestPath = findClosestExistingPath(config.theme, pathString);
if (closestPath) {
const closestValue = _lodash.default.get(config.theme, closestPath);
if (_lodash.default.isObject(closestValue)) {
error += ` '${pathToString(closestPath)}' has the following keys: ${listKeys(closestValue)}`;
} else {
error += ` '${pathToString(closestPath)}' is not an object.`;
}
} else {
error += ` Your theme has the following top-level keys: ${listKeys(config.theme)}`;
}
}
return {
isValid: false,
error
};
}
if (!(typeof value === 'string' || typeof value === 'number' || typeof value === 'function' || value instanceof String || value instanceof Number || Array.isArray(value))) {
let error = `'${pathString}' was found but does not resolve to a string.`;
if (_lodash.default.isObject(value)) {
let validKeys = Object.keys(value).filter(key => validatePath(config, [...pathSegments, key]).isValid);
if (validKeys.length) {
error += ` Did you mean something like '${pathToString([...pathSegments, validKeys[0]])}'?`;
}
}
return {
isValid: false,
error
};
}
const [themeSection] = pathSegments;
return {
isValid: true,
value: (0, _transformThemeValue.default)(themeSection)(value)
};
}
function extractArgs(node, vNodes, functions) {
vNodes = vNodes.map(vNode => resolveVNode(node, vNode, functions));
let args = [''];
for (let vNode of vNodes) {
if (vNode.type === 'div' && vNode.value === ',') {
args.push('');
} else {
args[args.length - 1] += _postcssValueParser.default.stringify(vNode);
}
}
return args;
}
function resolveVNode(node, vNode, functions) {
if (vNode.type === 'function' && functions[vNode.value] !== undefined) {
let args = extractArgs(node, vNode.nodes, functions);
vNode.type = 'word';
vNode.value = functions[vNode.value](node, ...args);
}
return vNode;
}
function resolveFunctions(node, input, functions) {
return (0, _postcssValueParser.default)(input).walk(vNode => {
resolveVNode(node, vNode, functions);
}).toString();
}
let nodeTypePropertyMap = {
atrule: 'params',
decl: 'value'
};
function _default({
tailwindConfig: config
}) {
let functions = {
theme: (node, path, ...defaultValue) => {
const {
isValid,
value,
error
} = validatePath(config, path, defaultValue.length ? defaultValue : undefined);
if (!isValid) {
throw node.error(error);
}
return value;
},
screen: (node, screen) => {
screen = _lodash.default.trim(screen, `'"`);
if (config.theme.screens[screen] === undefined) {
throw node.error(`The '${screen}' screen does not exist in your theme.`);
}
return (0, _buildMediaQuery.default)(config.theme.screens[screen]);
}
};
return root => {
root.walk(node => {
let property = nodeTypePropertyMap[node.type];
if (property === undefined) {
return;
}
node[property] = resolveFunctions(node, node[property], functions);
});
};
}

25
node_modules/tailwindcss/lib/lib/formatCSS.js generated vendored Normal file
View file

@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = formatNodes;
function indentRecursive(node, indent = 0) {
node.each && node.each((child, i) => {
if (!child.raws.before || child.raws.before.includes('\n')) {
child.raws.before = `\n${node.type !== 'rule' && i > 0 ? '\n' : ''}${' '.repeat(indent)}`;
}
child.raws.after = `\n${' '.repeat(indent)}`;
indentRecursive(child, indent + 1);
});
}
function formatNodes(root) {
indentRecursive(root);
if (root.first) {
root.first.raws.before = '';
}
}

View file

@ -0,0 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = getModuleDependencies;
var _fs = _interopRequireDefault(require("fs"));
var _path = _interopRequireDefault(require("path"));
var _resolve = _interopRequireDefault(require("resolve"));
var _detective = _interopRequireDefault(require("detective"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function createModule(file) {
const source = _fs.default.readFileSync(file, 'utf-8');
const requires = (0, _detective.default)(source);
return {
file,
requires
};
}
function getModuleDependencies(entryFile) {
const rootModule = createModule(entryFile);
const modules = [rootModule]; // Iterate over the modules, even when new
// ones are being added
for (const mdl of modules) {
mdl.requires.filter(dep => {
// Only track local modules, not node_modules
return dep.startsWith('./') || dep.startsWith('../');
}).forEach(dep => {
try {
const basedir = _path.default.dirname(mdl.file);
const depPath = _resolve.default.sync(dep, {
basedir
});
const depModule = createModule(depPath);
modules.push(depModule);
} catch (_err) {// eslint-disable-next-line no-empty
}
});
}
return modules;
}

236
node_modules/tailwindcss/lib/lib/purgeUnusedStyles.js generated vendored Normal file
View file

@ -0,0 +1,236 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.tailwindExtractor = tailwindExtractor;
exports.default = purgeUnusedUtilities;
var _lodash = _interopRequireDefault(require("lodash"));
var _postcss = _interopRequireDefault(require("postcss"));
var _purgecss = _interopRequireWildcard(require("purgecss"));
var _log = _interopRequireDefault(require("../util/log"));
var _htmlTags = _interopRequireDefault(require("html-tags"));
var _path = _interopRequireDefault(require("path"));
var _parseDependency = _interopRequireDefault(require("../util/parseDependency"));
var _normalizePath = _interopRequireDefault(require("normalize-path"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function removeTailwindMarkers(css) {
css.walkAtRules('tailwind', rule => rule.remove());
css.walkComments(comment => {
switch (comment.text.trim()) {
case 'tailwind start base':
case 'tailwind end base':
case 'tailwind start components':
case 'tailwind start utilities':
case 'tailwind end components':
case 'tailwind end utilities':
comment.remove();
break;
default:
break;
}
});
}
function tailwindExtractor(content) {
// Capture as liberally as possible, including things like `h-(screen-1.5)`
const broadMatches = content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || [];
const broadMatchesWithoutTrailingSlash = broadMatches.map(match => _lodash.default.trimEnd(match, '\\')); // Capture classes within other delimiters like .block(class="w-1/2") in Pug
const innerMatches = content.match(/[^<>"'`\s.(){}[\]#=%]*[^<>"'`\s.(){}[\]#=%:]/g) || [];
return broadMatches.concat(broadMatchesWithoutTrailingSlash).concat(innerMatches);
}
function getTransformer(config, fileExtension) {
let transformers = config.purge && config.purge.transform || {};
if (typeof transformers === 'function') {
transformers = {
DEFAULT: transformers
};
}
return transformers[fileExtension] || transformers.DEFAULT || (content => content);
}
function purgeUnusedUtilities(config, configChanged, registerDependency) {
var _config$purge;
const purgeEnabled = _lodash.default.get(config, 'purge.enabled', config.purge !== false && config.purge !== undefined && process.env.NODE_ENV === 'production');
if (!purgeEnabled) {
return removeTailwindMarkers;
} // Skip if `purge: []` since that's part of the default config
if (Array.isArray(config.purge) && config.purge.length === 0) {
if (configChanged) {
_log.default.warn(['Tailwind is not purging unused styles because no template paths have been provided.', 'If you have manually configured PurgeCSS outside of Tailwind or are deliberately not removing unused styles, set `purge: false` in your Tailwind config file to silence this warning.', 'https://tailwindcss.com/docs/controlling-file-size/#removing-unused-css']);
}
return removeTailwindMarkers;
}
const extractors = config.purge.extract || {};
const transformers = config.purge.transform || {};
let {
defaultExtractor: originalDefaultExtractor,
...purgeOptions
} = config.purge.options || {};
if ((_config$purge = config.purge) !== null && _config$purge !== void 0 && _config$purge.safelist && !purgeOptions.hasOwnProperty('safelist')) {
purgeOptions.safelist = config.purge.safelist;
}
if (!originalDefaultExtractor) {
originalDefaultExtractor = typeof extractors === 'function' ? extractors : extractors.DEFAULT || tailwindExtractor;
}
const defaultExtractor = content => {
const preserved = originalDefaultExtractor(content);
if (_lodash.default.get(config, 'purge.preserveHtmlElements', true)) {
preserved.push(..._htmlTags.default);
}
return preserved;
}; // If `extractors` is a function then we don't have any file-specific extractors,
// only a default one.
let fileSpecificExtractors = typeof extractors === 'function' ? {} : extractors; // PurgeCSS doesn't support "transformers," so we implement those using extractors.
// If we have a custom transformer for an extension, but not a matching extractor,
// then we need to create an extractor that we can augment later.
if (typeof transformers !== 'function') {
for (let [extension] of Object.entries(transformers)) {
if (!fileSpecificExtractors[extension]) {
fileSpecificExtractors[extension] = defaultExtractor;
}
}
} // Augment file-specific extractors by running the transformer before we extract classes.
fileSpecificExtractors = Object.entries(fileSpecificExtractors).map(([extension, extractor]) => {
return {
extensions: [extension],
extractor: content => {
const transformer = getTransformer(config, extension);
return extractor(transformer(content));
}
};
});
let content = (Array.isArray(config.purge) ? config.purge : config.purge.content || purgeOptions.content || []).map(item => {
if (typeof item === 'string') {
return (0, _normalizePath.default)(_path.default.resolve(item));
}
return item;
});
for (let fileOrGlob of content.filter(item => typeof item === 'string')) {
registerDependency((0, _parseDependency.default)(fileOrGlob));
}
let hasLayers = false;
const mode = _lodash.default.get(config, 'purge.mode', 'layers');
return (0, _postcss.default)([function (css) {
if (!['all', 'layers'].includes(mode)) {
throw new Error('Purge `mode` must be one of `layers` or `all`.');
}
if (mode === 'all') {
return;
}
const layers = _lodash.default.get(config, 'purge.layers', ['base', 'components', 'utilities']);
css.walkComments(comment => {
switch (comment.text.trim()) {
case `purgecss start ignore`:
comment.before(_postcss.default.comment({
text: 'purgecss end ignore'
}));
break;
case `purgecss end ignore`:
comment.before(_postcss.default.comment({
text: 'purgecss end ignore'
}));
comment.text = 'purgecss start ignore';
break;
default:
break;
}
layers.forEach(layer => {
switch (comment.text.trim()) {
case `tailwind start ${layer}`:
comment.text = 'purgecss end ignore';
hasLayers = true;
break;
case `tailwind end ${layer}`:
comment.text = 'purgecss start ignore';
break;
default:
break;
}
});
});
css.prepend(_postcss.default.comment({
text: 'purgecss start ignore'
}));
css.append(_postcss.default.comment({
text: 'purgecss end ignore'
}));
}, removeTailwindMarkers, async function (css) {
if (mode === 'layers' && !hasLayers) {
return;
}
const purgeCSS = new _purgecss.default();
purgeCSS.options = { ..._purgecss.defaultOptions,
defaultExtractor: content => {
const transformer = getTransformer(config);
return defaultExtractor(transformer(content));
},
extractors: fileSpecificExtractors,
...purgeOptions,
safelist: (0, _purgecss.standardizeSafelist)(purgeOptions.safelist)
};
if (purgeCSS.options.variables) {
purgeCSS.variablesStructure.safelist = purgeCSS.options.safelist.variables || [];
}
const fileFormatContents = content.filter(o => typeof o === 'string');
const rawFormatContents = content.filter(o => typeof o === 'object');
const cssFileSelectors = await purgeCSS.extractSelectorsFromFiles(fileFormatContents, purgeCSS.options.extractors);
const cssRawSelectors = await purgeCSS.extractSelectorsFromString(rawFormatContents, purgeCSS.options.extractors);
const cssSelectors = (0, _purgecss.mergeExtractorSelectors)(cssFileSelectors, cssRawSelectors);
purgeCSS.walkThroughCSS(css, cssSelectors);
if (purgeCSS.options.fontFace) purgeCSS.removeUnusedFontFaces();
if (purgeCSS.options.keyframes) purgeCSS.removeUnusedKeyframes();
if (purgeCSS.options.variables) purgeCSS.removeUnusedCSSVariables();
}]);
}

View file

@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
var _fs = _interopRequireDefault(require("fs"));
var _getModuleDependencies = _interopRequireDefault(require("./getModuleDependencies"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _default(configFile) {
if (!_fs.default.existsSync(configFile)) {
throw new Error(`Specified Tailwind config file "${configFile}" doesn't exist.`);
}
return function (css, opts) {
(0, _getModuleDependencies.default)(configFile).forEach(mdl => {
opts.messages.push({
type: 'dependency',
parent: css.source.input.file,
file: mdl.file
});
});
};
}

View file

@ -0,0 +1,385 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = substituteClassApplyAtRules;
var _lodash = _interopRequireDefault(require("lodash"));
var _postcssSelectorParser = _interopRequireDefault(require("postcss-selector-parser"));
var _postcss = _interopRequireDefault(require("postcss"));
var _didyoumean = _interopRequireDefault(require("didyoumean"));
var _substituteTailwindAtRules = _interopRequireDefault(require("./substituteTailwindAtRules"));
var _evaluateTailwindFunctions = _interopRequireDefault(require("./evaluateTailwindFunctions"));
var _substituteVariantsAtRules = _interopRequireDefault(require("./substituteVariantsAtRules"));
var _substituteResponsiveAtRules = _interopRequireDefault(require("./substituteResponsiveAtRules"));
var _convertLayerAtRulesToControlComments = _interopRequireDefault(require("./convertLayerAtRulesToControlComments"));
var _substituteScreenAtRules = _interopRequireDefault(require("./substituteScreenAtRules"));
var _prefixSelector = _interopRequireDefault(require("../util/prefixSelector"));
var _useMemo = require("../util/useMemo");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function hasAtRule(css, atRule, condition) {
let found = false;
css.walkAtRules(atRule, condition === undefined ? () => {
found = true;
return false;
} : node => {
if (condition(node)) {
found = true;
return false;
}
});
return found;
}
function cloneWithoutChildren(node) {
if (node.type === 'atrule') {
return _postcss.default.atRule({
name: node.name,
params: node.params
});
}
if (node.type === 'rule') {
return _postcss.default.rule({
name: node.name,
selectors: node.selectors
});
}
const clone = node.clone();
clone.removeAll();
return clone;
}
const tailwindApplyPlaceholder = _postcssSelectorParser.default.attribute({
attribute: '__TAILWIND-APPLY-PLACEHOLDER__'
});
function generateRulesFromApply({
rule,
utilityName: className,
classPosition
}, replaceWiths) {
const parser = (0, _postcssSelectorParser.default)(selectors => {
let i = 0;
selectors.walkClasses(c => {
if (classPosition === i++ && c.value === className) {
c.replaceWith(tailwindApplyPlaceholder);
}
});
});
const processedSelectors = _lodash.default.flatMap(rule.selectors, selector => {
// You could argue we should make this replacement at the AST level, but if we believe
// the placeholder string is safe from collisions then it is safe to do this is a simple
// string replacement, and much, much faster.
return replaceWiths.map(replaceWith => parser.processSync(selector).replace('[__TAILWIND-APPLY-PLACEHOLDER__]', replaceWith));
});
const cloned = rule.clone();
let current = cloned;
let parent = rule.parent;
while (parent && parent.type !== 'root') {
const parentClone = cloneWithoutChildren(parent);
parentClone.append(current);
current.parent = parentClone;
current = parentClone;
parent = parent.parent;
}
cloned.selectors = processedSelectors;
return current;
}
const extractUtilityNamesParser = (0, _postcssSelectorParser.default)(selectors => {
let classes = [];
selectors.walkClasses(c => classes.push(c.value));
return classes;
});
const extractUtilityNames = (0, _useMemo.useMemo)(selector => extractUtilityNamesParser.transformSync(selector), selector => selector);
const cloneRuleWithParent = (0, _useMemo.useMemo)(rule => rule.clone({
parent: rule.parent
}), rule => rule);
function buildCssUtilityMap(css, startIndex) {
let index = startIndex;
const utilityMap = {};
function handle(getRule, rule) {
const utilityNames = extractUtilityNames(rule.selector);
utilityNames.forEach((utilityName, i) => {
if (utilityMap[utilityName] === undefined) {
utilityMap[utilityName] = [];
}
utilityMap[utilityName].push({
index,
utilityName,
classPosition: i,
...getRule(rule)
});
index++;
});
} // This is the end user's css. This might contain rules that we want to
// apply. We want immediate copies of everything in case that we have user
// defined classes that are recursively applied. Down below we are modifying
// the rules directly. We could do a better solution where we keep track of a
// dependency tree, but that is a bit more complex. Might revisit later,
// we'll see how this turns out!
css.walkRules(handle.bind(null, rule => ({
rule: cloneRuleWithParent(rule)
})));
return utilityMap;
}
const buildLookupTreeUtilityMap = (0, _useMemo.useMemo)(lookupTree => {
let index = 0;
const utilityMap = {};
function handle(getRule, rule) {
const utilityNames = extractUtilityNames(rule.selector);
utilityNames.forEach((utilityName, i) => {
if (utilityMap[utilityName] === undefined) {
utilityMap[utilityName] = [];
}
utilityMap[utilityName].push({
index,
utilityName,
classPosition: i,
...getRule(rule)
});
index++;
});
} // Lookup tree is the big lookup tree, making the rule lazy allows us to save
// some memory because we don't need everything.
lookupTree.walkRules(handle.bind(null, rule => ({
get rule() {
return cloneRuleWithParent(rule);
}
})));
return utilityMap;
}, tree => tree);
function mergeAdjacentRules(initialRule, rulesToInsert) {
let previousRule = initialRule;
rulesToInsert.forEach(toInsert => {
if (toInsert.type === 'rule' && previousRule.type === 'rule' && toInsert.selector === previousRule.selector) {
previousRule.append(toInsert.nodes);
} else if (toInsert.type === 'atrule' && previousRule.type === 'atrule' && toInsert.params === previousRule.params) {
const merged = mergeAdjacentRules(previousRule.nodes[previousRule.nodes.length - 1], toInsert.nodes);
previousRule.append(merged);
} else {
previousRule = toInsert;
}
toInsert.walk(n => {
if (n.nodes && n.nodes.length === 0) {
n.remove();
}
});
});
return rulesToInsert.filter(r => r.nodes.length > 0);
}
function makeExtractUtilityRules(css, lookupTree, config) {
const lookupTreeUtilityMap = buildLookupTreeUtilityMap(lookupTree);
const lookupTreeUtilityMapKeys = Object.keys(lookupTreeUtilityMap);
const utilityMap = buildCssUtilityMap(css, lookupTreeUtilityMapKeys.length);
function getUtility(utilityName) {
const utility = [];
if (lookupTreeUtilityMap[utilityName]) {
utility.push(...lookupTreeUtilityMap[utilityName]);
}
if (utilityMap[utilityName]) {
utility.push(...utilityMap[utilityName]);
}
if (utility.length > 0) return utility;
}
return function extractUtilityRules(utilityNames, rule) {
const combined = [];
utilityNames.forEach(utilityName => {
const utility = getUtility(utilityName);
if (utility === undefined) {
// Look for prefixed utility in case the user has goofed
const prefixedUtilityName = (0, _prefixSelector.default)(config.prefix, `.${utilityName}`).slice(1);
const prefixedUtility = getUtility(prefixedUtilityName);
if (prefixedUtility !== undefined) {
throw rule.error(`The \`${utilityName}\` class does not exist, but \`${prefixedUtilityName}\` does. Did you forget the prefix?`);
}
const suggestedClass = (0, _didyoumean.default)(utilityName, Object.keys(utilityMap).concat(lookupTreeUtilityMapKeys));
const suggestionMessage = suggestedClass ? `, but \`${suggestedClass}\` does` : '';
throw rule.error(`The \`${utilityName}\` class does not exist${suggestionMessage}. If you're sure that \`${utilityName}\` exists, make sure that any \`@import\` statements are being properly processed before Tailwind CSS sees your CSS, as \`@apply\` can only be used for classes in the same CSS tree.`, {
word: utilityName
});
}
combined.push(...utility);
});
return combined.sort((a, b) => a.index - b.index);
};
}
function findParent(rule, predicate) {
let parent = rule.parent;
while (parent) {
if (predicate(parent)) {
return parent;
}
parent = parent.parent;
}
throw new Error('No parent could be found');
}
function processApplyAtRules(css, lookupTree, config) {
const extractUtilityRules = makeExtractUtilityRules(css, lookupTree, config);
do {
css.walkAtRules('apply', applyRule => {
const parent = applyRule.parent; // Direct parent
const nearestParentRule = findParent(applyRule, r => r.type === 'rule');
const currentUtilityNames = extractUtilityNames(nearestParentRule.selector);
const [importantEntries, applyUtilityNames, important = importantEntries.length > 0] = _lodash.default.partition(applyRule.params.split(/[\s\t\n]+/g), n => n === '!important');
if (_lodash.default.intersection(applyUtilityNames, currentUtilityNames).length > 0) {
const currentUtilityName = _lodash.default.intersection(applyUtilityNames, currentUtilityNames)[0];
throw parent.error(`You cannot \`@apply\` the \`${currentUtilityName}\` utility here because it creates a circular dependency.`);
} // Extract any post-apply declarations and re-insert them after apply rules
const afterRule = parent.clone({
raws: {}
});
afterRule.nodes = afterRule.nodes.slice(parent.index(applyRule) + 1);
parent.nodes = parent.nodes.slice(0, parent.index(applyRule) + 1); // Sort applys to match CSS source order
const applys = extractUtilityRules(applyUtilityNames, applyRule); // Get new rules with the utility portion of the selector replaced with the new selector
const rulesToInsert = [];
applys.forEach(nearestParentRule === parent ? util => rulesToInsert.push(generateRulesFromApply(util, parent.selectors)) : util => util.rule.nodes.forEach(n => afterRule.append(n.clone())));
rulesToInsert.forEach(rule => {
if (rule.type === 'atrule') {
rule.walkRules(rule => {
rule.__tailwind = { ...rule.__tailwind,
important
};
});
} else {
rule.__tailwind = { ...rule.__tailwind,
important
};
}
});
const {
nodes
} = _lodash.default.tap(_postcss.default.root({
nodes: rulesToInsert
}), root => {
root.walkDecls(d => {
d.important = important;
});
});
const mergedRules = mergeAdjacentRules(nearestParentRule, [...nodes, afterRule]);
applyRule.remove();
parent.after(mergedRules); // If the base rule has nothing in it (all applys were pseudo or responsive variants),
// remove the rule fuggit.
if (parent.nodes.length === 0) {
parent.remove();
}
}); // We already know that we have at least 1 @apply rule. Otherwise this
// function would not have been called. Therefore we can execute this code
// at least once. This also means that in the best case scenario we only
// call this 2 times, instead of 3 times.
// 1st time -> before we call this function
// 2nd time -> when we check if we have to do this loop again (because do {} while (check))
// .. instead of
// 1st time -> before we call this function
// 2nd time -> when we check the first time (because while (check) do {})
// 3rd time -> when we re-check to see if we should do this loop again
} while (hasAtRule(css, 'apply'));
return css;
}
let defaultTailwindTree = new Map();
function substituteClassApplyAtRules(config, getProcessedPlugins, configChanged) {
return function (css) {
// We can stop already when we don't have any @apply rules. Vue users: you're welcome!
if (!hasAtRule(css, 'apply')) {
return css;
}
let requiredTailwindAtRules = ['base', 'components', 'utilities'];
if (hasAtRule(css, 'tailwind', node => {
let idx = requiredTailwindAtRules.indexOf(node.params);
if (idx !== -1) requiredTailwindAtRules.splice(idx, 1);
if (requiredTailwindAtRules.length <= 0) return true;
return false;
})) {
// Tree already contains all the at rules (requiredTailwindAtRules)
return processApplyAtRules(css, _postcss.default.root(), config);
}
let lookupKey = requiredTailwindAtRules.join(','); // We mutated the `requiredTailwindAtRules`, but when we hit this point in
// time, it means that we don't have all the atrules. The missing atrules
// are listed inside the requiredTailwindAtRules, which we can use to fill
// in the missing pieces.
//
// Important for <style> blocks in Vue components.
const generateLookupTree = configChanged || !defaultTailwindTree.has(lookupKey) ? () => {
return (0, _postcss.default)([(0, _substituteTailwindAtRules.default)(config, getProcessedPlugins()), (0, _evaluateTailwindFunctions.default)({
tailwindConfig: config
}), (0, _substituteVariantsAtRules.default)(config, getProcessedPlugins()), (0, _substituteResponsiveAtRules.default)(config), (0, _convertLayerAtRulesToControlComments.default)(config), (0, _substituteScreenAtRules.default)({
tailwindConfig: config
})]).process(requiredTailwindAtRules.map(rule => `@tailwind ${rule};`).join('\n'), {
from: __filename
}).then(result => {
defaultTailwindTree.set(lookupKey, result);
return result;
});
} : () => Promise.resolve(defaultTailwindTree.get(lookupKey));
return generateLookupTree().then(result => {
return processApplyAtRules(css, result.root, config);
});
};
}

View file

@ -0,0 +1,104 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
var _lodash = _interopRequireDefault(require("lodash"));
var _postcss = _interopRequireDefault(require("postcss"));
var _cloneNodes = _interopRequireDefault(require("../util/cloneNodes"));
var _buildMediaQuery = _interopRequireDefault(require("../util/buildMediaQuery"));
var _buildSelectorVariant = _interopRequireDefault(require("../util/buildSelectorVariant"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function isLayer(node) {
if (Array.isArray(node)) {
return node.length === 1 && isLayer(node[0]);
}
return node.type === 'atrule' && node.name === 'layer';
}
function layerNodes(nodes) {
return isLayer(nodes) ? nodes[0].nodes : nodes;
}
function _default(config) {
return function (css) {
// Wrap any `responsive` rules with a copy of their parent `layer` to
// ensure the layer isn't lost when copying to the `screens` location.
css.walkAtRules('layer', layerAtRule => {
const layer = layerAtRule.params;
layerAtRule.walkAtRules('responsive', responsiveAtRule => {
const nestedlayerAtRule = _postcss.default.atRule({
name: 'layer',
params: layer
});
nestedlayerAtRule.prepend(responsiveAtRule.nodes);
responsiveAtRule.removeAll();
responsiveAtRule.prepend(nestedlayerAtRule);
});
});
const {
theme: {
screens
},
separator
} = config;
const responsiveRules = _postcss.default.root();
const finalRules = [];
css.walkAtRules('responsive', atRule => {
const nodes = atRule.nodes;
responsiveRules.append(...(0, _cloneNodes.default)(nodes)); // If the parent is already a `layer` (this is true for anything coming from
// a plugin, including core plugins) we don't want to create a double nested
// layer, so only insert the layer children. If there is no parent layer,
// preserve the layer information when inserting the nodes.
if (isLayer(atRule.parent)) {
atRule.before(layerNodes(nodes));
} else {
atRule.before(nodes);
}
atRule.remove();
});
_lodash.default.keys(screens).forEach(screen => {
const mediaQuery = _postcss.default.atRule({
name: 'media',
params: (0, _buildMediaQuery.default)(screens[screen])
});
mediaQuery.append(_lodash.default.tap(responsiveRules.clone(), clonedRoot => {
clonedRoot.walkRules(rule => {
rule.selectors = _lodash.default.map(rule.selectors, selector => (0, _buildSelectorVariant.default)(selector, screen, separator, message => {
throw rule.error(message);
}));
});
}));
finalRules.push(mediaQuery);
});
const hasScreenRules = finalRules.some(i => i.nodes.length !== 0);
css.walkAtRules('tailwind', atRule => {
if (atRule.params !== 'screens') {
return;
}
if (hasScreenRules) {
atRule.before(finalRules);
}
atRule.remove();
});
};
}

View file

@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
var _lodash = _interopRequireDefault(require("lodash"));
var _buildMediaQuery = _interopRequireDefault(require("../util/buildMediaQuery"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _default({
tailwindConfig: {
theme
}
}) {
return function (css) {
css.walkAtRules('screen', atRule => {
const screen = atRule.params;
if (!_lodash.default.has(theme.screens, screen)) {
throw atRule.error(`No \`${screen}\` screen found.`);
}
atRule.name = 'media';
atRule.params = (0, _buildMediaQuery.default)(theme.screens[screen]);
});
};
}

View file

@ -0,0 +1,97 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
var _lodash = _interopRequireDefault(require("lodash"));
var _postcss = _interopRequireDefault(require("postcss"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function updateSource(nodes, source) {
return _lodash.default.tap(Array.isArray(nodes) ? _postcss.default.root({
nodes
}) : nodes, tree => {
tree.walk(node => node.source = source);
});
}
function _default(_config, {
base: pluginBase,
components: pluginComponents,
utilities: pluginUtilities
}) {
return function (css) {
css.walkAtRules('import', atRule => {
if (atRule.params === '"tailwindcss/base"' || atRule.params === "'tailwindcss/base'") {
atRule.name = 'tailwind';
atRule.params = 'base';
}
if (atRule.params === '"tailwindcss/components"' || atRule.params === "'tailwindcss/components'") {
atRule.name = 'tailwind';
atRule.params = 'components';
}
if (atRule.params === '"tailwindcss/utilities"' || atRule.params === "'tailwindcss/utilities'") {
atRule.name = 'tailwind';
atRule.params = 'utilities';
}
if (atRule.params === '"tailwindcss/screens"' || atRule.params === "'tailwindcss/screens'") {
atRule.name = 'tailwind';
atRule.params = 'screens';
}
});
let includesScreensExplicitly = false;
const layers = {
base: [],
components: [],
utilities: []
};
css.walkAtRules('layer', atRule => {
if (!['base', 'components', 'utilities'].includes(atRule.params)) {
return;
}
layers[atRule.params].push(atRule);
});
css.walkAtRules('tailwind', atRule => {
if (atRule.params === 'preflight') {
// prettier-ignore
throw atRule.error("`@tailwind preflight` is not a valid at-rule in Tailwind v2.0, use `@tailwind base` instead.", {
word: 'preflight'
});
}
if (atRule.params === 'base') {
atRule.after(layers.base);
atRule.after(updateSource(pluginBase, atRule.source));
}
if (atRule.params === 'components') {
atRule.after(layers.components);
atRule.after(updateSource(pluginComponents, atRule.source));
}
if (atRule.params === 'utilities') {
atRule.after(layers.utilities);
atRule.after(updateSource(pluginUtilities, atRule.source));
}
if (atRule.params === 'screens') {
includesScreensExplicitly = true;
}
});
if (!includesScreensExplicitly) {
css.append([_postcss.default.atRule({
name: 'tailwind',
params: 'screens'
})]);
}
};
}

View file

@ -0,0 +1,247 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
var _lodash = _interopRequireDefault(require("lodash"));
var _postcss = _interopRequireDefault(require("postcss"));
var _postcssSelectorParser = _interopRequireDefault(require("postcss-selector-parser"));
var _generateVariantFunction = _interopRequireDefault(require("../util/generateVariantFunction"));
var _prefixSelector = _interopRequireDefault(require("../util/prefixSelector"));
var _buildSelectorVariant = _interopRequireDefault(require("../util/buildSelectorVariant"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function generatePseudoClassVariant(pseudoClass, selectorPrefix = pseudoClass) {
return (0, _generateVariantFunction.default)(({
modifySelectors,
separator
}) => {
const parser = (0, _postcssSelectorParser.default)(selectors => {
selectors.walkClasses(sel => {
sel.value = `${selectorPrefix}${separator}${sel.value}`;
sel.parent.insertAfter(sel, _postcssSelectorParser.default.pseudo({
value: `:${pseudoClass}`
}));
});
});
return modifySelectors(({
selector
}) => parser.processSync(selector));
});
}
function ensureIncludesDefault(variants) {
return variants.includes('DEFAULT') ? variants : ['DEFAULT', ...variants];
}
const defaultVariantGenerators = config => ({
DEFAULT: (0, _generateVariantFunction.default)(() => {}),
dark: (0, _generateVariantFunction.default)(({
container,
separator,
modifySelectors
}) => {
if (config.darkMode === false) {
return _postcss.default.root();
}
if (config.darkMode === 'media') {
const modified = modifySelectors(({
selector
}) => {
return (0, _buildSelectorVariant.default)(selector, 'dark', separator, message => {
throw container.error(message);
});
});
const mediaQuery = _postcss.default.atRule({
name: 'media',
params: '(prefers-color-scheme: dark)'
});
mediaQuery.append(modified);
container.append(mediaQuery);
return container;
}
if (config.darkMode === 'class') {
const modified = modifySelectors(({
selector
}) => {
return (0, _buildSelectorVariant.default)(selector, 'dark', separator, message => {
throw container.error(message);
});
});
modified.walkRules(rule => {
rule.selectors = rule.selectors.map(selector => {
return `${(0, _prefixSelector.default)(config.prefix, '.dark')} ${selector}`;
});
});
return modified;
}
throw new Error("The `darkMode` config option must be either 'media' or 'class'.");
}, {
unstable_stack: true
}),
'motion-safe': (0, _generateVariantFunction.default)(({
container,
separator,
modifySelectors
}) => {
const modified = modifySelectors(({
selector
}) => {
return (0, _buildSelectorVariant.default)(selector, 'motion-safe', separator, message => {
throw container.error(message);
});
});
const mediaQuery = _postcss.default.atRule({
name: 'media',
params: '(prefers-reduced-motion: no-preference)'
});
mediaQuery.append(modified);
container.append(mediaQuery);
}, {
unstable_stack: true
}),
'motion-reduce': (0, _generateVariantFunction.default)(({
container,
separator,
modifySelectors
}) => {
const modified = modifySelectors(({
selector
}) => {
return (0, _buildSelectorVariant.default)(selector, 'motion-reduce', separator, message => {
throw container.error(message);
});
});
const mediaQuery = _postcss.default.atRule({
name: 'media',
params: '(prefers-reduced-motion: reduce)'
});
mediaQuery.append(modified);
container.append(mediaQuery);
}, {
unstable_stack: true
}),
'group-hover': (0, _generateVariantFunction.default)(({
modifySelectors,
separator
}) => {
const parser = (0, _postcssSelectorParser.default)(selectors => {
selectors.walkClasses(sel => {
sel.value = `group-hover${separator}${sel.value}`;
sel.parent.insertBefore(sel, (0, _postcssSelectorParser.default)().astSync((0, _prefixSelector.default)(config.prefix, '.group:hover ')));
});
});
return modifySelectors(({
selector
}) => parser.processSync(selector));
}),
'group-focus': (0, _generateVariantFunction.default)(({
modifySelectors,
separator
}) => {
const parser = (0, _postcssSelectorParser.default)(selectors => {
selectors.walkClasses(sel => {
sel.value = `group-focus${separator}${sel.value}`;
sel.parent.insertBefore(sel, (0, _postcssSelectorParser.default)().astSync((0, _prefixSelector.default)(config.prefix, '.group:focus ')));
});
});
return modifySelectors(({
selector
}) => parser.processSync(selector));
}),
hover: generatePseudoClassVariant('hover'),
'focus-within': generatePseudoClassVariant('focus-within'),
'focus-visible': generatePseudoClassVariant('focus-visible'),
'read-only': generatePseudoClassVariant('read-only'),
focus: generatePseudoClassVariant('focus'),
active: generatePseudoClassVariant('active'),
visited: generatePseudoClassVariant('visited'),
disabled: generatePseudoClassVariant('disabled'),
checked: generatePseudoClassVariant('checked'),
first: generatePseudoClassVariant('first-child', 'first'),
last: generatePseudoClassVariant('last-child', 'last'),
odd: generatePseudoClassVariant('nth-child(odd)', 'odd'),
even: generatePseudoClassVariant('nth-child(even)', 'even'),
empty: generatePseudoClassVariant('empty')
});
function prependStackableVariants(atRule, variants, stackableVariants) {
if (!_lodash.default.some(variants, v => stackableVariants.includes(v))) {
return variants;
}
if (_lodash.default.every(variants, v => stackableVariants.includes(v))) {
return variants;
}
const variantsParent = _postcss.default.atRule({
name: 'variants',
params: variants.filter(v => stackableVariants.includes(v)).join(', ')
});
atRule.before(variantsParent);
variantsParent.append(atRule);
variants = _lodash.default.without(variants, ...stackableVariants);
return variants;
}
function _default(config, {
variantGenerators: pluginVariantGenerators
}) {
return function (css) {
const variantGenerators = { ...defaultVariantGenerators(config),
...pluginVariantGenerators
};
const stackableVariants = Object.entries(variantGenerators).filter(([_variant, {
options
}]) => options.unstable_stack).map(([variant]) => variant);
let variantsFound = false;
do {
variantsFound = false;
css.walkAtRules('variants', atRule => {
variantsFound = true;
let variants = _postcss.default.list.comma(atRule.params).filter(variant => variant !== '');
if (variants.includes('responsive')) {
const responsiveParent = _postcss.default.atRule({
name: 'responsive'
});
atRule.before(responsiveParent);
responsiveParent.append(atRule);
}
const remainingVariants = prependStackableVariants(atRule, variants, stackableVariants);
_lodash.default.forEach(_lodash.default.without(ensureIncludesDefault(remainingVariants), 'responsive'), variant => {
if (!variantGenerators[variant]) {
throw new Error(`Your config mentions the "${variant}" variant, but "${variant}" doesn't appear to be a variant. Did you forget or misconfigure a plugin that supplies that variant?`);
}
variantGenerators[variant].handler(atRule, config);
});
atRule.remove();
});
} while (variantsFound);
};
}