UNPKG

stylesheet-loader

Version:
139 lines 6.43 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getFontFaceContent = exports.parse = void 0; var css = require("css"); var loaderUtils = require("loader-utils"); var transformer_1 = require("./transformer"); var globalCSSVariable_1 = require("./globalCSSVariable"); var promptMessage_1 = require("./promptMessage"); var processPrefersColorScheme_1 = require("./processPrefersColorScheme"); var RULE = 'rule'; var FONT_FACE_RULE = 'font-face'; var MEDIA_RULE = 'media'; var QUOTES_REG = /['|"]/g; // example "color: var(--name);" search string "var(" and ")" var VAR_KEY_VAL_REG = /"(.*?)"\s*:\s*"var\((.*)\)"/g; var GLOBAL_CSS_VAR = '__CSSVariables'; var CSS_VAR_NAME = ':root'; function styleSheetLoader(source) { var self = typeof this === 'object' ? this : {}; self.cacheable && self.cacheable(); var stylesheet = css.parse(source).stylesheet; if (stylesheet.parsingErrors.length) { throw new Error('StyleSheet Parsing Error occured.'); } // getOptions can return null if no query passed. var parsedQuery = loaderUtils.getOptions(self) || {}; // Compatible with string true. if (parsedQuery.log === 'true') { parsedQuery.log = true; } var parsedData = exports.parse(parsedQuery, stylesheet); return genStyleContent(parsedData, parsedQuery); } // export for test case exports.parse = function (parsedQuery, stylesheet) { var styles = {}; var fontFaceRules = []; var mediaRules = []; var transformDescendantCombinator = parsedQuery.transformDescendantCombinator; stylesheet.rules.forEach(function (rule) { var style = {}; // normal rule if (rule.type === RULE) { style = transformer_1.default.convert(rule, parsedQuery); rule.selectors.forEach(function (selector) { var sanitizedSelector = transformer_1.default.sanitizeSelector(selector, transformDescendantCombinator, rule.position, parsedQuery.log); if (sanitizedSelector) { // handle pseudo class var pseudoIndex = sanitizedSelector.indexOf(':'); if (pseudoIndex > -1 && !parsedQuery.theme) { var pseudoStyle_1 = {}; var pseudoName_1 = selector.slice(pseudoIndex + 1); sanitizedSelector = sanitizedSelector.slice(0, pseudoIndex); Object.keys(style).forEach(function (prop) { pseudoStyle_1[prop + pseudoName_1] = style[prop]; }); style = pseudoStyle_1; } // eslint-disable-next-line eqeqeq if (sanitizedSelector == CSS_VAR_NAME && parsedQuery.theme) { sanitizedSelector = GLOBAL_CSS_VAR; } styles[sanitizedSelector] = Object.assign(styles[sanitizedSelector] || {}, style); } }); } // font face rule if (rule.type === FONT_FACE_RULE) { var font_1 = {}; rule.declarations.forEach(function (declaration) { font_1[declaration.property] = declaration.value; }); fontFaceRules.push(font_1); } // media rule if (rule.type === MEDIA_RULE) { mediaRules.push({ key: rule.media, data: exports.parse(parsedQuery, rule).styles, }); } }); return { styles: styles, fontFaceRules: fontFaceRules, mediaRules: mediaRules, }; }; var genStyleContent = function (parsedData, parsedQuery) { var fontFaceRules = parsedData.fontFaceRules, mediaRules = parsedData.mediaRules; var styles = processPrefersColorScheme_1.processPrefersColorScheme(mediaRules, parsedData.styles, parsedQuery.taskName); var fontFaceContent = exports.getFontFaceContent(fontFaceRules); var mediaContent = getMediaContent(mediaRules, parsedQuery); var warnMessageOutput = parsedQuery.log ? getWarnMessageOutput() : ''; promptMessage_1.resetMessage(); return (parsedQuery.theme ? globalCSSVariable_1.default({ styles: styles, globalCSSVarName: GLOBAL_CSS_VAR }) : '') + "\n var _styles = " + stringifyData(styles, parsedQuery.theme) + ";\n" + fontFaceContent + "\n" + mediaContent + "\n" + warnMessageOutput + "\n module.exports = _styles;\n "; }; var getWarnMessageOutput = function () { var errorMessages = promptMessage_1.getErrorMessages(); var warnMessages = promptMessage_1.getWarnMessages(); var output = ''; if (errorMessages) { output += "\n if (process.env.NODE_ENV !== 'production') {\n console.error('" + errorMessages + "');\n }\n "; } if (warnMessages) { output += "\n if (process.env.NODE_ENV !== 'production') {\n console.warn('" + warnMessages + "');\n }\n "; } return output; }; var getMediaContent = function (mediaRules, parsedQuery) { var content = ''; mediaRules.forEach(function (rule) { // Weex no need to process prefers-color-scheme media if (parsedQuery.taskName !== 'weex' || !processPrefersColorScheme_1.isPrefersColorScheme(rule.key)) { content += "\n if (window.matchMedia && window.matchMedia('" + rule.key + "').matches) {\n var ruleData = " + stringifyData(rule.data) + ";\n for(var key in ruleData) {\n _styles[key] = Object.assign(_styles[key] || {}, ruleData[key]);\n }\n }\n "; } }); return content; }; // export for test case exports.getFontFaceContent = function (rules) { var content = ''; if (rules.length > 0) { content += "\n if (typeof FontFace === 'function') {\n "; } rules.forEach(function (rule, index) { content += "\n var fontFace" + index + " = new FontFace('" + rule['font-family'].replace(QUOTES_REG, '') + "', '" + rule.src.replace(QUOTES_REG, '"') + "');\n document.fonts.add(fontFace" + index + ");\n "; }); if (rules.length > 0) { content += "\n }\n "; } return content; }; var stringifyData = function (data, theme) { var str = JSON.stringify(data, undefined, ' '); return !theme ? str : str.replace(VAR_KEY_VAL_REG, 'get $1(){return __getValue("$2")}'); }; exports.default = styleSheetLoader; //# sourceMappingURL=index.js.map