@aesthetic/sss
Advanced tools
Comparing version 0.3.0 to 0.4.0
696
esm/index.js
@@ -1,2 +0,2 @@ | ||
import { objectLoop, toArray, isObject, arrayLoop, hyphenate } from '@aesthetic/utils'; | ||
import { objectLoop, isObject, hyphenate, arrayLoop, toArray } from '@aesthetic/utils'; | ||
@@ -98,8 +98,2 @@ var Block = function () { | ||
function _inheritsLoose(subClass, superClass) { | ||
subClass.prototype = Object.create(superClass.prototype); | ||
subClass.prototype.constructor = subClass; | ||
subClass.__proto__ = superClass; | ||
} | ||
var FORMATS = { | ||
@@ -151,2 +145,79 @@ '.eot': 'embedded-opentype', | ||
function formatImport(value) { | ||
if (typeof value === 'string') { | ||
return value; | ||
} | ||
var path = "\"" + value.path + "\""; | ||
if (value.url) { | ||
path = "url(" + path + ")"; | ||
} | ||
if (value.media) { | ||
path += " " + value.media; | ||
} | ||
return path; | ||
} | ||
function validateDeclarations(block, name) { | ||
if (!isObject(block)) { | ||
throw new Error(name + " must be a mapping of CSS " + (name === '@variables' ? 'variables' : 'declarations') + "."); | ||
} | ||
return true; | ||
} | ||
function parseVariables(parent, variables, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarations(variables, '@variables'); | ||
} | ||
objectLoop(variables, function (value, prop) { | ||
var name = hyphenate(prop); | ||
if (name.slice(0, 2) !== '--') { | ||
name = "--" + name; | ||
} | ||
if (parent) { | ||
parent.addVariable(name, value); | ||
events.onVariable == null ? void 0 : events.onVariable(parent, name, value); | ||
} else { | ||
events.onRootVariable == null ? void 0 : events.onRootVariable(name, value); | ||
} | ||
}); | ||
} | ||
function createQueue(events) { | ||
var items = []; | ||
return { | ||
add: function add(obj, key, callback) { | ||
var value = obj[key]; | ||
if (value !== undefined) { | ||
items.push(function () { | ||
return callback(value, events); | ||
}); | ||
} | ||
delete obj[key]; | ||
}, | ||
process: function process() { | ||
arrayLoop(items, function (cb) { | ||
return cb(); | ||
}); | ||
} | ||
}; | ||
} | ||
function validateDeclarationBlock(block, name) { | ||
if (!isObject(block)) { | ||
throw new TypeError("\"" + name + "\" must be a declaration object of CSS properties."); | ||
} | ||
return true; | ||
} | ||
function processCompoundProperty(property, object, processor, onProcess) { | ||
@@ -186,3 +257,3 @@ var value = ''; | ||
objectLoop(object, function (value, key) { | ||
var longName = property + key.charAt(0).toUpperCase() + key.slice(1); | ||
var longName = property + key[0].toUpperCase() + key.slice(1); | ||
onProcess(longName, value); | ||
@@ -232,467 +303,272 @@ }); | ||
var SELECTOR = /^((\[[\x2Da-z\u017F\u212A]+\])|(::?[\x2Da-z\u017F\u212A]+))$/i; | ||
var EVENT_MAP = { | ||
onBlockAttribute: 'block:attribute', | ||
onBlockFallback: 'block:fallback', | ||
onBlockMedia: 'block:media', | ||
onBlockProperty: 'block:property', | ||
onBlockPseudo: 'block:pseudo', | ||
onBlockSelector: 'block:selector', | ||
onBlockSupports: 'block:supports', | ||
onBlockVariable: 'block:variable', | ||
onBlockVariant: 'block:variant', | ||
onFontFace: 'font-face' | ||
}; | ||
function parseFontFace(object, fontFamily, events) { | ||
var name = object.fontFamily || fontFamily || ''; | ||
var Parser = function () { | ||
function Parser(handlers) { | ||
var _this = this; | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarationBlock(object, name); | ||
} | ||
this.handlers = {}; | ||
var fontFace = formatFontFace(_extends({}, object, { | ||
fontFamily: name | ||
})); | ||
var block = parseBlock(new Block('@font-face'), fontFace, events); | ||
return (events.onFontFace == null ? void 0 : events.onFontFace(block, name, object.srcPaths)) || name; | ||
} | ||
this.parseFontFace = function (object, fontFamily) { | ||
var name = object.fontFamily || fontFamily || ''; | ||
function parseKeyframes(object, animationName, events) { | ||
var keyframes = new Block("@keyframes"); | ||
_this.validateDeclarationBlock(object, name); | ||
var fontFace = formatFontFace(_extends({}, object, { | ||
fontFamily: name | ||
})); | ||
return _this.emit('font-face', _this.parseBlock(new Block('@font-face'), fontFace), name, object.srcPaths); | ||
}; | ||
this.parseKeyframes = function (object, animationName) { | ||
var keyframes = new Block("@keyframes"); | ||
_this.validateDeclarationBlock(object, keyframes.selector); | ||
objectLoop(object, function (value, key) { | ||
if (value !== undefined) { | ||
keyframes.addNested(_this.parseBlock(new Block(key), value)); | ||
} | ||
}); | ||
return _this.emit('keyframes', keyframes, animationName) || animationName || ''; | ||
}; | ||
if (handlers) { | ||
objectLoop(handlers, function (handler, name) { | ||
_this.on(EVENT_MAP[name] || name.slice(2).toLowerCase(), handler); | ||
}); | ||
} | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarationBlock(object, keyframes.selector); | ||
} | ||
var _proto = Parser.prototype; | ||
_proto.parseBlock = function parseBlock(parent, object) { | ||
var _this2 = this; | ||
this.validateDeclarationBlock(object, parent.selector); | ||
objectLoop(object, function (value, key) { | ||
if (value === undefined) { | ||
return; | ||
} | ||
var char = key.charAt(0); | ||
if (char === ':' || char === '[') { | ||
_this2.parseSelector(parent, key, value); | ||
} else if (char === '@') { | ||
parent.addNested(_this2.parseBlock(new Block(key), value)); | ||
} else { | ||
_this2.parseProperty(parent, key, value); | ||
} | ||
}); | ||
this.emit('block', parent); | ||
return parent; | ||
}; | ||
_proto.parseConditionalBlock = function parseConditionalBlock(parent, conditions, type) { | ||
var _this3 = this; | ||
this.validateDeclarations(conditions, "@" + type); | ||
objectLoop(conditions, function (object, condition) { | ||
var nestedBlock = _this3.parseLocalBlock(new Block("@" + type + " " + condition), object); | ||
parent.addNested(nestedBlock); | ||
_this3.emit("block:" + type, parent, condition, nestedBlock); | ||
}); | ||
}; | ||
_proto.parseFallbackProperties = function parseFallbackProperties(parent, fallbacks) { | ||
var _this4 = this; | ||
this.validateDeclarationBlock(fallbacks, '@fallbacks'); | ||
objectLoop(fallbacks, function (value, prop) { | ||
_this4.emit('block:fallback', parent, prop, toArray(value)); | ||
}); | ||
}; | ||
_proto.parseLocalBlock = function parseLocalBlock(parent, object) { | ||
var _this5 = this; | ||
this.validateDeclarationBlock(object, parent.selector); | ||
var props = _extends({}, object); | ||
if (props['@fallbacks']) { | ||
this.parseFallbackProperties(parent, props['@fallbacks']); | ||
delete props['@fallbacks']; | ||
objectLoop(object, function (value, key) { | ||
if (value !== undefined) { | ||
keyframes.addNested(parseBlock(new Block(key), value, events)); | ||
} | ||
}); | ||
return (events.onKeyframes == null ? void 0 : events.onKeyframes(keyframes, animationName)) || animationName || ''; | ||
} | ||
if (props['@media']) { | ||
this.parseConditionalBlock(parent, props['@media'], 'media'); | ||
delete props['@media']; | ||
} | ||
if (props['@selectors']) { | ||
this.validateDeclarations(props['@selectors'], '@selectors'); | ||
objectLoop(props['@selectors'], function (value, key) { | ||
_this5.parseSelector(parent, key, value, true); | ||
}); | ||
delete props['@selectors']; | ||
} | ||
if (props['@supports']) { | ||
this.parseConditionalBlock(parent, props['@supports'], 'supports'); | ||
delete props['@supports']; | ||
} | ||
if (props['@variables']) { | ||
this.parseVariables(parent, props['@variables']); | ||
delete props['@variables']; | ||
} | ||
if (props['@variants']) { | ||
this.parseVariants(parent, props['@variants']); | ||
delete props['@variants']; | ||
} | ||
return this.parseBlock(parent, props); | ||
function parseProperty(parent, name, value, events) { | ||
var handler = function handler(n, v) { | ||
parent.addProperty(n, v); | ||
events.onProperty == null ? void 0 : events.onProperty(parent, n, v); | ||
}; | ||
_proto.parseProperty = function parseProperty(parent, name, value) { | ||
var _this6 = this; | ||
if (EXPANDED_PROPERTIES.has(name) && isObject(value)) { | ||
processExpandedProperty(name, value, expandedProperties[name], handler); | ||
return; | ||
} | ||
var handler = function handler(n, v) { | ||
parent.addProperty(n, v); | ||
_this6.emit('block:property', parent, n, v); | ||
if (COMPOUND_PROPERTIES.has(name) && (isObject(value) || Array.isArray(value))) { | ||
var compoundProperties = { | ||
animationName: function animationName(prop) { | ||
return parseKeyframes(prop, '', events); | ||
}, | ||
fontFamily: function fontFamily(prop) { | ||
return parseFontFace(prop, '', events); | ||
} | ||
}; | ||
processCompoundProperty(name, value, compoundProperties[name], handler); | ||
return; | ||
} | ||
if (EXPANDED_PROPERTIES.has(name) && isObject(value)) { | ||
processExpandedProperty(name, value, expandedProperties[name], handler); | ||
return; | ||
} | ||
if (typeof value === 'number' || typeof value === 'string') { | ||
handler(name, value); | ||
} | ||
} | ||
if (COMPOUND_PROPERTIES.has(name) && (isObject(value) || Array.isArray(value))) { | ||
var compoundProperties = { | ||
animationName: function animationName(prop) { | ||
return _this6.parseKeyframes(prop); | ||
}, | ||
fontFamily: function fontFamily(prop) { | ||
return _this6.parseFontFace(prop); | ||
} | ||
}; | ||
processCompoundProperty(name, value, compoundProperties[name], handler); | ||
return; | ||
} | ||
var SELECTOR = /^((\[[\x2Da-z\u017F\u212A]+\])|(::?[\x2Da-z\u017F\u212A]+))$/i; | ||
function parseSelector(parent, selector, object, inAtRule, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarationBlock(object, selector); | ||
if (typeof value === 'number' || typeof value === 'string') { | ||
handler(name, value); | ||
if ((selector.includes(',') || !selector.match(SELECTOR)) && !inAtRule) { | ||
throw new Error("Advanced selector \"" + selector + "\" must be nested within a @selectors block."); | ||
} | ||
}; | ||
} | ||
_proto.parseSelector = function parseSelector(parent, selector, object, inAtRule) { | ||
var _this7 = this; | ||
var block = parseLocalBlock(new Block(selector), object, events); | ||
arrayLoop(selector.split(','), function (k) { | ||
var name = k.trim(); | ||
var specificity = 0; | ||
if (inAtRule === void 0) { | ||
inAtRule = false; | ||
while (name[0] === '&') { | ||
specificity += 1; | ||
name = name.slice(1); | ||
} | ||
this.validateDeclarationBlock(object, selector); | ||
var nestedBlock = block.clone(name); | ||
var args = [parent, name, nestedBlock, { | ||
specificity: specificity | ||
}]; | ||
parent.addNested(nestedBlock); | ||
if ("production" !== process.env.NODE_ENV) { | ||
if ((selector.includes(',') || !selector.match(SELECTOR)) && !inAtRule) { | ||
throw new Error("Advanced selector \"" + selector + "\" must be nested within a @selectors block."); | ||
} | ||
if (name[0] === ':') { | ||
events.onPseudo == null ? void 0 : events.onPseudo.apply(events, args); | ||
} else if (name[0] === '[') { | ||
events.onAttribute == null ? void 0 : events.onAttribute.apply(events, args); | ||
} else { | ||
events.onSelector == null ? void 0 : events.onSelector.apply(events, args); | ||
} | ||
}); | ||
} | ||
var block = this.parseLocalBlock(new Block(selector), object); | ||
arrayLoop(selector.split(','), function (k) { | ||
var name = k.trim(); | ||
var type = 'block:selector'; | ||
var specificity = 0; | ||
function parseBlock(parent, object, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarationBlock(object, parent.selector); | ||
} | ||
while (name.charAt(0) === '&') { | ||
specificity += 1; | ||
name = name.slice(1); | ||
} | ||
if (name.charAt(0) === ':') { | ||
type = 'block:pseudo'; | ||
} else if (name.charAt(0) === '[') { | ||
type = 'block:attribute'; | ||
} | ||
var nestedBlock = block.clone(name); | ||
parent.addNested(nestedBlock); | ||
_this7.emit(type, parent, name, nestedBlock, { | ||
specificity: specificity | ||
}); | ||
}); | ||
}; | ||
_proto.parseVariables = function parseVariables(parent, variables) { | ||
var _this8 = this; | ||
this.validateDeclarations(variables, '@variables'); | ||
objectLoop(variables, function (value, prop) { | ||
var name = hyphenate(prop); | ||
if (name.slice(0, 2) !== '--') { | ||
name = "--" + name; | ||
} | ||
if (parent) { | ||
parent.addVariable(name, value); | ||
_this8.emit('block:variable', parent, name, value); | ||
} else { | ||
_this8.emit('variable', name, value); | ||
} | ||
}); | ||
}; | ||
_proto.parseVariants = function parseVariants(parent, variants) { | ||
var _this9 = this; | ||
this.validateDeclarations(variants, '@variants'); | ||
objectLoop(variants, function (variant, parentType) { | ||
objectLoop(variant, function (object, subType) { | ||
var type = parentType + "_" + subType; | ||
var block = _this9.parseLocalBlock(new Block(type), object); | ||
parent.addVariant(block); | ||
_this9.emit('block:variant', parent, type, block, { | ||
specificity: 0 | ||
}); | ||
}); | ||
}); | ||
}; | ||
_proto.emit = function emit(name) { | ||
var _this$handlers$name, _this$handlers; | ||
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = arguments[_key]; | ||
objectLoop(object, function (value, key) { | ||
if (value === undefined) { | ||
return; | ||
} | ||
return (_this$handlers$name = (_this$handlers = this.handlers)[name]) == null ? void 0 : _this$handlers$name.call.apply(_this$handlers$name, [_this$handlers].concat(args)); | ||
}; | ||
_proto.on = function on(name, callback) { | ||
this.handlers[name] = callback; | ||
return this; | ||
}; | ||
_proto.validateDeclarationBlock = function validateDeclarationBlock(block, name) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
if (!isObject(block)) { | ||
throw new TypeError("\"" + name + "\" must be a declaration object of CSS properties."); | ||
} | ||
if (key[0] === ':' || key[0] === '[') { | ||
parseSelector(parent, key, value, false, events); | ||
} else { | ||
parseProperty(parent, key, value, events); | ||
} | ||
}); | ||
events.onBlock == null ? void 0 : events.onBlock(parent); | ||
return parent; | ||
} | ||
return true; | ||
}; | ||
_proto.validateDeclarations = function validateDeclarations(block, name) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
if (!isObject(block)) { | ||
throw new Error(name + " must be a mapping of CSS " + (name === '@variables' ? 'variables' : 'declarations') + "."); | ||
} | ||
} | ||
return true; | ||
}; | ||
return Parser; | ||
}(); | ||
function formatImport(value) { | ||
if (typeof value === 'string') { | ||
return value; | ||
function parseConditionalBlock(parent, conditions, type, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarations(conditions, "@" + type); | ||
} | ||
var path = "\"" + value.path + "\""; | ||
objectLoop(conditions, function (object, condition) { | ||
var nestedBlock = parseLocalBlock(new Block("@" + type + " " + condition), object, events); | ||
parent.addNested(nestedBlock); | ||
if (value.url) { | ||
path = "url(" + path + ")"; | ||
} | ||
if (type === 'media') { | ||
events.onMedia == null ? void 0 : events.onMedia(parent, condition, nestedBlock); | ||
} else { | ||
events.onSupports == null ? void 0 : events.onSupports(parent, condition, nestedBlock); | ||
} | ||
}); | ||
} | ||
if (value.media) { | ||
path += " " + value.media; | ||
function parseFallbackProperties(parent, fallbacks, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarationBlock(fallbacks, '@fallbacks'); | ||
} | ||
return path; | ||
objectLoop(fallbacks, function (value, prop) { | ||
events.onFallback == null ? void 0 : events.onFallback(parent, prop, toArray(value)); | ||
}); | ||
} | ||
var GlobalParser = function (_Parser) { | ||
_inheritsLoose(GlobalParser, _Parser); | ||
function GlobalParser() { | ||
return _Parser.apply(this, arguments) || this; | ||
function parseVariants(parent, variants, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarations(variants, '@variants'); | ||
} | ||
var _proto = GlobalParser.prototype; | ||
_proto.parse = function parse(styleSheet) { | ||
this.parseFontFacesMap(styleSheet['@font-face']); | ||
this.parseImport(styleSheet['@import']); | ||
this.parseKeyframesMap(styleSheet['@keyframes']); | ||
this.parsePage(styleSheet['@page']); | ||
this.parseRoot(styleSheet['@root']); | ||
this.parseRootVariables(styleSheet['@variables']); | ||
this.parseViewport(styleSheet['@viewport']); | ||
}; | ||
_proto.parseFontFacesMap = function parseFontFacesMap(fontFaces) { | ||
var _this = this; | ||
if (!fontFaces) { | ||
return; | ||
} | ||
if ("production" !== process.env.NODE_ENV) { | ||
if (!isObject(fontFaces)) { | ||
throw new Error('@font-face must be an object of font family names to font faces.'); | ||
} | ||
} | ||
objectLoop(fontFaces, function (faces, name) { | ||
arrayLoop(toArray(faces), function (fontFace) { | ||
_this.parseFontFace(fontFace, name); | ||
objectLoop(variants, function (variant, parentType) { | ||
objectLoop(variant, function (object, subType) { | ||
var type = parentType + "_" + subType; | ||
var block = parseLocalBlock(new Block(type), object, events); | ||
parent.addVariant(block); | ||
events.onVariant == null ? void 0 : events.onVariant(parent, type, block, { | ||
specificity: 0 | ||
}); | ||
}); | ||
}; | ||
}); | ||
} | ||
_proto.parseImport = function parseImport(imports) { | ||
var _this2 = this; | ||
function parseLocalBlock(parent, object, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarationBlock(object, parent.selector); | ||
} | ||
if (!imports) { | ||
return; | ||
} | ||
var props = _extends({}, object); | ||
var queue = createQueue(events); | ||
queue.add(props, '@fallbacks', function (data) { | ||
return parseFallbackProperties(parent, data, events); | ||
}); | ||
queue.add(props, '@media', function (data) { | ||
return parseConditionalBlock(parent, data, 'media', events); | ||
}); | ||
queue.add(props, '@selectors', function (data) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
if (!Array.isArray(imports)) { | ||
throw new TypeError('@import must be an array of strings or import objects.'); | ||
} | ||
validateDeclarations(data, '@selectors'); | ||
} | ||
arrayLoop(imports, function (value) { | ||
_this2.emit('import', formatImport(value)); | ||
objectLoop(data, function (value, key) { | ||
parseSelector(parent, key, value, true, events); | ||
}); | ||
}; | ||
}); | ||
queue.add(props, '@supports', function (data) { | ||
return parseConditionalBlock(parent, data, 'supports', events); | ||
}); | ||
queue.add(props, '@variables', function (data) { | ||
return parseVariables(parent, data, events); | ||
}); | ||
queue.add(props, '@variants', function (data) { | ||
return parseVariants(parent, data, events); | ||
}); | ||
var block = parseBlock(parent, props, events); | ||
queue.process(); | ||
return block; | ||
} | ||
_proto.parseKeyframesMap = function parseKeyframesMap(keyframes) { | ||
var _this3 = this; | ||
if (!keyframes) { | ||
return; | ||
function parseFontFacesMap(fontFaces, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
if (!isObject(fontFaces)) { | ||
throw new Error('@font-face must be an object of font family names to font faces.'); | ||
} | ||
} | ||
if ("production" !== process.env.NODE_ENV) { | ||
if (!isObject(keyframes)) { | ||
throw new Error('@keyframes must be an object of animation names to keyframes.'); | ||
} | ||
} | ||
objectLoop(keyframes, function (keyframe, name) { | ||
_this3.parseKeyframes(keyframe, name); | ||
objectLoop(fontFaces, function (faces, name) { | ||
arrayLoop(toArray(faces), function (fontFace) { | ||
parseFontFace(fontFace, name, events); | ||
}); | ||
}; | ||
}); | ||
} | ||
_proto.parsePage = function parsePage(page) { | ||
var _this4 = this; | ||
if (!page) { | ||
return; | ||
function parseImport(imports, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
if (!Array.isArray(imports)) { | ||
throw new TypeError('@import must be an array of strings or import objects.'); | ||
} | ||
} | ||
this.validateDeclarationBlock(page, '@page'); | ||
arrayLoop(imports, function (value) { | ||
events.onImport == null ? void 0 : events.onImport(formatImport(value)); | ||
}); | ||
} | ||
var object = _extends({}, page); | ||
var pseudos = [':blank', ':first', ':left', ':right']; | ||
pseudos.forEach(function (selector) { | ||
var value = object[selector]; | ||
if (value) { | ||
_this4.emit('page', _this4.parseBlock(new Block("@page " + selector), value)); | ||
delete object[selector]; | ||
} | ||
}); | ||
if (Object.keys(object).length > 0) { | ||
this.emit('page', this.parseBlock(new Block('@page'), object)); | ||
function parseKeyframesMap(keyframes, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
if (!isObject(keyframes)) { | ||
throw new Error('@keyframes must be an object of animation names to keyframes.'); | ||
} | ||
}; | ||
} | ||
_proto.parseRoot = function parseRoot(globals) { | ||
if (globals) { | ||
this.emit('root', this.parseLocalBlock(new Block('@root'), globals)); | ||
} | ||
}; | ||
objectLoop(keyframes, function (keyframe, name) { | ||
parseKeyframes(keyframe, name, events); | ||
}); | ||
} | ||
_proto.parseRootVariables = function parseRootVariables(variables) { | ||
if (variables) { | ||
this.parseVariables(null, variables); | ||
} | ||
}; | ||
function parseRoot(globals, events) { | ||
var block = parseLocalBlock(new Block('@root'), globals, events); | ||
events.onRoot == null ? void 0 : events.onRoot(block); | ||
} | ||
_proto.parseViewport = function parseViewport(viewport) { | ||
if (viewport) { | ||
this.emit('viewport', this.parseBlock(new Block('@viewport'), viewport)); | ||
} | ||
}; | ||
function parseRootVariables(variables, events) { | ||
parseVariables(null, variables, events); | ||
} | ||
return GlobalParser; | ||
}(Parser); | ||
function parseGlobalStyleSheet(styleSheet, events) { | ||
var queue = createQueue(events); | ||
queue.add(styleSheet, '@font-face', parseFontFacesMap); | ||
queue.add(styleSheet, '@import', parseImport); | ||
queue.add(styleSheet, '@keyframes', parseKeyframesMap); | ||
queue.add(styleSheet, '@root', parseRoot); | ||
queue.add(styleSheet, '@variables', parseRootVariables); | ||
queue.process(); | ||
} | ||
var CLASS_NAME = /^[a-z\u017F\u212A]{1}[\x2D0-9_a-z\u017F\u212A]+$/i; | ||
var LocalParser = function (_Parser) { | ||
_inheritsLoose(LocalParser, _Parser); | ||
function LocalParser() { | ||
return _Parser.apply(this, arguments) || this; | ||
} | ||
var _proto = LocalParser.prototype; | ||
_proto.parse = function parse(styleSheet) { | ||
var _this = this; | ||
objectLoop(styleSheet, function (declaration, selector) { | ||
if (selector.charAt(0) === '@') { | ||
if ("production" !== process.env.NODE_ENV) { | ||
throw new SyntaxError("At-rules may not be defined at the root of a local block, found \"" + selector + "\"."); | ||
} | ||
} else if (typeof declaration === 'string' && declaration.match(CLASS_NAME)) { | ||
_this.emit('class', selector, declaration); | ||
} else if (isObject(declaration)) { | ||
_this.emit('rule', selector, _this.parseLocalBlock(new Block(selector), declaration)); | ||
} else if ("production" !== process.env.NODE_ENV) { | ||
throw new Error("Invalid declaration for \"" + selector + "\". Must be an object (style declaration) or string (class name)."); | ||
function parseLocalStyleSheet(styleSheet, events) { | ||
objectLoop(styleSheet, function (declaration, selector) { | ||
if (selector[0] === '@') { | ||
if ("production" !== process.env.NODE_ENV) { | ||
throw new SyntaxError("At-rules may not be defined at the root of a local block, found \"" + selector + "\"."); | ||
} | ||
}); | ||
}; | ||
} else if (typeof declaration === 'string' && declaration.match(CLASS_NAME)) { | ||
events.onClass == null ? void 0 : events.onClass(selector, declaration); | ||
} else if (isObject(declaration)) { | ||
var block = parseLocalBlock(new Block(selector), declaration, events); | ||
events.onRule == null ? void 0 : events.onRule(selector, block); | ||
} else if ("production" !== process.env.NODE_ENV) { | ||
throw new Error("Invalid declaration for \"" + selector + "\". Must be an object (style declaration) or string (class name)."); | ||
} | ||
}); | ||
} | ||
return LocalParser; | ||
}(Parser); | ||
export { Block, GlobalParser, LocalParser, formatFontFace, formatImport }; | ||
export { Block, formatFontFace, formatImport, parseGlobalStyleSheet, parseLocalStyleSheet }; |
@@ -6,8 +6,8 @@ /** | ||
import Block from './Block'; | ||
import GlobalParser from './GlobalParser'; | ||
import LocalParser from './LocalParser'; | ||
import formatFontFace from './helpers/formatFontFace'; | ||
import formatImport from './helpers/formatImport'; | ||
import parseGlobalStyleSheet from './parseGlobalStyleSheet'; | ||
import parseLocalStyleSheet from './parseLocalStyleSheet'; | ||
export * from './types'; | ||
export { Block, GlobalParser, LocalParser, formatFontFace, formatImport }; | ||
export { Block, formatFontFace, formatImport, parseGlobalStyleSheet, parseLocalStyleSheet }; | ||
//# sourceMappingURL=index.d.ts.map |
696
lib/index.js
@@ -102,8 +102,2 @@ 'use strict'; | ||
function _inheritsLoose(subClass, superClass) { | ||
subClass.prototype = Object.create(superClass.prototype); | ||
subClass.prototype.constructor = subClass; | ||
subClass.__proto__ = superClass; | ||
} | ||
var FORMATS = { | ||
@@ -155,2 +149,79 @@ '.eot': 'embedded-opentype', | ||
function formatImport(value) { | ||
if (typeof value === 'string') { | ||
return value; | ||
} | ||
var path = "\"" + value.path + "\""; | ||
if (value.url) { | ||
path = "url(" + path + ")"; | ||
} | ||
if (value.media) { | ||
path += " " + value.media; | ||
} | ||
return path; | ||
} | ||
function validateDeclarations(block, name) { | ||
if (!utils.isObject(block)) { | ||
throw new Error(name + " must be a mapping of CSS " + (name === '@variables' ? 'variables' : 'declarations') + "."); | ||
} | ||
return true; | ||
} | ||
function parseVariables(parent, variables, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarations(variables, '@variables'); | ||
} | ||
utils.objectLoop(variables, function (value, prop) { | ||
var name = utils.hyphenate(prop); | ||
if (name.slice(0, 2) !== '--') { | ||
name = "--" + name; | ||
} | ||
if (parent) { | ||
parent.addVariable(name, value); | ||
events.onVariable == null ? void 0 : events.onVariable(parent, name, value); | ||
} else { | ||
events.onRootVariable == null ? void 0 : events.onRootVariable(name, value); | ||
} | ||
}); | ||
} | ||
function createQueue(events) { | ||
var items = []; | ||
return { | ||
add: function add(obj, key, callback) { | ||
var value = obj[key]; | ||
if (value !== undefined) { | ||
items.push(function () { | ||
return callback(value, events); | ||
}); | ||
} | ||
delete obj[key]; | ||
}, | ||
process: function process() { | ||
utils.arrayLoop(items, function (cb) { | ||
return cb(); | ||
}); | ||
} | ||
}; | ||
} | ||
function validateDeclarationBlock(block, name) { | ||
if (!utils.isObject(block)) { | ||
throw new TypeError("\"" + name + "\" must be a declaration object of CSS properties."); | ||
} | ||
return true; | ||
} | ||
function processCompoundProperty(property, object, processor, onProcess) { | ||
@@ -190,3 +261,3 @@ var value = ''; | ||
utils.objectLoop(object, function (value, key) { | ||
var longName = property + key.charAt(0).toUpperCase() + key.slice(1); | ||
var longName = property + key[0].toUpperCase() + key.slice(1); | ||
onProcess(longName, value); | ||
@@ -236,471 +307,276 @@ }); | ||
var SELECTOR = /^((\[[\x2Da-z\u017F\u212A]+\])|(::?[\x2Da-z\u017F\u212A]+))$/i; | ||
var EVENT_MAP = { | ||
onBlockAttribute: 'block:attribute', | ||
onBlockFallback: 'block:fallback', | ||
onBlockMedia: 'block:media', | ||
onBlockProperty: 'block:property', | ||
onBlockPseudo: 'block:pseudo', | ||
onBlockSelector: 'block:selector', | ||
onBlockSupports: 'block:supports', | ||
onBlockVariable: 'block:variable', | ||
onBlockVariant: 'block:variant', | ||
onFontFace: 'font-face' | ||
}; | ||
function parseFontFace(object, fontFamily, events) { | ||
var name = object.fontFamily || fontFamily || ''; | ||
var Parser = function () { | ||
function Parser(handlers) { | ||
var _this = this; | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarationBlock(object, name); | ||
} | ||
this.handlers = {}; | ||
var fontFace = formatFontFace(_extends({}, object, { | ||
fontFamily: name | ||
})); | ||
var block = parseBlock(new Block('@font-face'), fontFace, events); | ||
return (events.onFontFace == null ? void 0 : events.onFontFace(block, name, object.srcPaths)) || name; | ||
} | ||
this.parseFontFace = function (object, fontFamily) { | ||
var name = object.fontFamily || fontFamily || ''; | ||
function parseKeyframes(object, animationName, events) { | ||
var keyframes = new Block("@keyframes"); | ||
_this.validateDeclarationBlock(object, name); | ||
var fontFace = formatFontFace(_extends({}, object, { | ||
fontFamily: name | ||
})); | ||
return _this.emit('font-face', _this.parseBlock(new Block('@font-face'), fontFace), name, object.srcPaths); | ||
}; | ||
this.parseKeyframes = function (object, animationName) { | ||
var keyframes = new Block("@keyframes"); | ||
_this.validateDeclarationBlock(object, keyframes.selector); | ||
utils.objectLoop(object, function (value, key) { | ||
if (value !== undefined) { | ||
keyframes.addNested(_this.parseBlock(new Block(key), value)); | ||
} | ||
}); | ||
return _this.emit('keyframes', keyframes, animationName) || animationName || ''; | ||
}; | ||
if (handlers) { | ||
utils.objectLoop(handlers, function (handler, name) { | ||
_this.on(EVENT_MAP[name] || name.slice(2).toLowerCase(), handler); | ||
}); | ||
} | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarationBlock(object, keyframes.selector); | ||
} | ||
var _proto = Parser.prototype; | ||
_proto.parseBlock = function parseBlock(parent, object) { | ||
var _this2 = this; | ||
this.validateDeclarationBlock(object, parent.selector); | ||
utils.objectLoop(object, function (value, key) { | ||
if (value === undefined) { | ||
return; | ||
} | ||
var char = key.charAt(0); | ||
if (char === ':' || char === '[') { | ||
_this2.parseSelector(parent, key, value); | ||
} else if (char === '@') { | ||
parent.addNested(_this2.parseBlock(new Block(key), value)); | ||
} else { | ||
_this2.parseProperty(parent, key, value); | ||
} | ||
}); | ||
this.emit('block', parent); | ||
return parent; | ||
}; | ||
_proto.parseConditionalBlock = function parseConditionalBlock(parent, conditions, type) { | ||
var _this3 = this; | ||
this.validateDeclarations(conditions, "@" + type); | ||
utils.objectLoop(conditions, function (object, condition) { | ||
var nestedBlock = _this3.parseLocalBlock(new Block("@" + type + " " + condition), object); | ||
parent.addNested(nestedBlock); | ||
_this3.emit("block:" + type, parent, condition, nestedBlock); | ||
}); | ||
}; | ||
_proto.parseFallbackProperties = function parseFallbackProperties(parent, fallbacks) { | ||
var _this4 = this; | ||
this.validateDeclarationBlock(fallbacks, '@fallbacks'); | ||
utils.objectLoop(fallbacks, function (value, prop) { | ||
_this4.emit('block:fallback', parent, prop, utils.toArray(value)); | ||
}); | ||
}; | ||
_proto.parseLocalBlock = function parseLocalBlock(parent, object) { | ||
var _this5 = this; | ||
this.validateDeclarationBlock(object, parent.selector); | ||
var props = _extends({}, object); | ||
if (props['@fallbacks']) { | ||
this.parseFallbackProperties(parent, props['@fallbacks']); | ||
delete props['@fallbacks']; | ||
utils.objectLoop(object, function (value, key) { | ||
if (value !== undefined) { | ||
keyframes.addNested(parseBlock(new Block(key), value, events)); | ||
} | ||
}); | ||
return (events.onKeyframes == null ? void 0 : events.onKeyframes(keyframes, animationName)) || animationName || ''; | ||
} | ||
if (props['@media']) { | ||
this.parseConditionalBlock(parent, props['@media'], 'media'); | ||
delete props['@media']; | ||
} | ||
if (props['@selectors']) { | ||
this.validateDeclarations(props['@selectors'], '@selectors'); | ||
utils.objectLoop(props['@selectors'], function (value, key) { | ||
_this5.parseSelector(parent, key, value, true); | ||
}); | ||
delete props['@selectors']; | ||
} | ||
if (props['@supports']) { | ||
this.parseConditionalBlock(parent, props['@supports'], 'supports'); | ||
delete props['@supports']; | ||
} | ||
if (props['@variables']) { | ||
this.parseVariables(parent, props['@variables']); | ||
delete props['@variables']; | ||
} | ||
if (props['@variants']) { | ||
this.parseVariants(parent, props['@variants']); | ||
delete props['@variants']; | ||
} | ||
return this.parseBlock(parent, props); | ||
function parseProperty(parent, name, value, events) { | ||
var handler = function handler(n, v) { | ||
parent.addProperty(n, v); | ||
events.onProperty == null ? void 0 : events.onProperty(parent, n, v); | ||
}; | ||
_proto.parseProperty = function parseProperty(parent, name, value) { | ||
var _this6 = this; | ||
if (EXPANDED_PROPERTIES.has(name) && utils.isObject(value)) { | ||
processExpandedProperty(name, value, expandedProperties[name], handler); | ||
return; | ||
} | ||
var handler = function handler(n, v) { | ||
parent.addProperty(n, v); | ||
_this6.emit('block:property', parent, n, v); | ||
if (COMPOUND_PROPERTIES.has(name) && (utils.isObject(value) || Array.isArray(value))) { | ||
var compoundProperties = { | ||
animationName: function animationName(prop) { | ||
return parseKeyframes(prop, '', events); | ||
}, | ||
fontFamily: function fontFamily(prop) { | ||
return parseFontFace(prop, '', events); | ||
} | ||
}; | ||
processCompoundProperty(name, value, compoundProperties[name], handler); | ||
return; | ||
} | ||
if (EXPANDED_PROPERTIES.has(name) && utils.isObject(value)) { | ||
processExpandedProperty(name, value, expandedProperties[name], handler); | ||
return; | ||
} | ||
if (typeof value === 'number' || typeof value === 'string') { | ||
handler(name, value); | ||
} | ||
} | ||
if (COMPOUND_PROPERTIES.has(name) && (utils.isObject(value) || Array.isArray(value))) { | ||
var compoundProperties = { | ||
animationName: function animationName(prop) { | ||
return _this6.parseKeyframes(prop); | ||
}, | ||
fontFamily: function fontFamily(prop) { | ||
return _this6.parseFontFace(prop); | ||
} | ||
}; | ||
processCompoundProperty(name, value, compoundProperties[name], handler); | ||
return; | ||
} | ||
var SELECTOR = /^((\[[\x2Da-z\u017F\u212A]+\])|(::?[\x2Da-z\u017F\u212A]+))$/i; | ||
function parseSelector(parent, selector, object, inAtRule, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarationBlock(object, selector); | ||
if (typeof value === 'number' || typeof value === 'string') { | ||
handler(name, value); | ||
if ((selector.includes(',') || !selector.match(SELECTOR)) && !inAtRule) { | ||
throw new Error("Advanced selector \"" + selector + "\" must be nested within a @selectors block."); | ||
} | ||
}; | ||
} | ||
_proto.parseSelector = function parseSelector(parent, selector, object, inAtRule) { | ||
var _this7 = this; | ||
var block = parseLocalBlock(new Block(selector), object, events); | ||
utils.arrayLoop(selector.split(','), function (k) { | ||
var name = k.trim(); | ||
var specificity = 0; | ||
if (inAtRule === void 0) { | ||
inAtRule = false; | ||
while (name[0] === '&') { | ||
specificity += 1; | ||
name = name.slice(1); | ||
} | ||
this.validateDeclarationBlock(object, selector); | ||
var nestedBlock = block.clone(name); | ||
var args = [parent, name, nestedBlock, { | ||
specificity: specificity | ||
}]; | ||
parent.addNested(nestedBlock); | ||
if ("production" !== process.env.NODE_ENV) { | ||
if ((selector.includes(',') || !selector.match(SELECTOR)) && !inAtRule) { | ||
throw new Error("Advanced selector \"" + selector + "\" must be nested within a @selectors block."); | ||
} | ||
if (name[0] === ':') { | ||
events.onPseudo == null ? void 0 : events.onPseudo.apply(events, args); | ||
} else if (name[0] === '[') { | ||
events.onAttribute == null ? void 0 : events.onAttribute.apply(events, args); | ||
} else { | ||
events.onSelector == null ? void 0 : events.onSelector.apply(events, args); | ||
} | ||
}); | ||
} | ||
var block = this.parseLocalBlock(new Block(selector), object); | ||
utils.arrayLoop(selector.split(','), function (k) { | ||
var name = k.trim(); | ||
var type = 'block:selector'; | ||
var specificity = 0; | ||
function parseBlock(parent, object, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarationBlock(object, parent.selector); | ||
} | ||
while (name.charAt(0) === '&') { | ||
specificity += 1; | ||
name = name.slice(1); | ||
} | ||
if (name.charAt(0) === ':') { | ||
type = 'block:pseudo'; | ||
} else if (name.charAt(0) === '[') { | ||
type = 'block:attribute'; | ||
} | ||
var nestedBlock = block.clone(name); | ||
parent.addNested(nestedBlock); | ||
_this7.emit(type, parent, name, nestedBlock, { | ||
specificity: specificity | ||
}); | ||
}); | ||
}; | ||
_proto.parseVariables = function parseVariables(parent, variables) { | ||
var _this8 = this; | ||
this.validateDeclarations(variables, '@variables'); | ||
utils.objectLoop(variables, function (value, prop) { | ||
var name = utils.hyphenate(prop); | ||
if (name.slice(0, 2) !== '--') { | ||
name = "--" + name; | ||
} | ||
if (parent) { | ||
parent.addVariable(name, value); | ||
_this8.emit('block:variable', parent, name, value); | ||
} else { | ||
_this8.emit('variable', name, value); | ||
} | ||
}); | ||
}; | ||
_proto.parseVariants = function parseVariants(parent, variants) { | ||
var _this9 = this; | ||
this.validateDeclarations(variants, '@variants'); | ||
utils.objectLoop(variants, function (variant, parentType) { | ||
utils.objectLoop(variant, function (object, subType) { | ||
var type = parentType + "_" + subType; | ||
var block = _this9.parseLocalBlock(new Block(type), object); | ||
parent.addVariant(block); | ||
_this9.emit('block:variant', parent, type, block, { | ||
specificity: 0 | ||
}); | ||
}); | ||
}); | ||
}; | ||
_proto.emit = function emit(name) { | ||
var _this$handlers$name, _this$handlers; | ||
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = arguments[_key]; | ||
utils.objectLoop(object, function (value, key) { | ||
if (value === undefined) { | ||
return; | ||
} | ||
return (_this$handlers$name = (_this$handlers = this.handlers)[name]) == null ? void 0 : _this$handlers$name.call.apply(_this$handlers$name, [_this$handlers].concat(args)); | ||
}; | ||
_proto.on = function on(name, callback) { | ||
this.handlers[name] = callback; | ||
return this; | ||
}; | ||
_proto.validateDeclarationBlock = function validateDeclarationBlock(block, name) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
if (!utils.isObject(block)) { | ||
throw new TypeError("\"" + name + "\" must be a declaration object of CSS properties."); | ||
} | ||
if (key[0] === ':' || key[0] === '[') { | ||
parseSelector(parent, key, value, false, events); | ||
} else { | ||
parseProperty(parent, key, value, events); | ||
} | ||
}); | ||
events.onBlock == null ? void 0 : events.onBlock(parent); | ||
return parent; | ||
} | ||
return true; | ||
}; | ||
_proto.validateDeclarations = function validateDeclarations(block, name) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
if (!utils.isObject(block)) { | ||
throw new Error(name + " must be a mapping of CSS " + (name === '@variables' ? 'variables' : 'declarations') + "."); | ||
} | ||
} | ||
return true; | ||
}; | ||
return Parser; | ||
}(); | ||
function formatImport(value) { | ||
if (typeof value === 'string') { | ||
return value; | ||
function parseConditionalBlock(parent, conditions, type, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarations(conditions, "@" + type); | ||
} | ||
var path = "\"" + value.path + "\""; | ||
utils.objectLoop(conditions, function (object, condition) { | ||
var nestedBlock = parseLocalBlock(new Block("@" + type + " " + condition), object, events); | ||
parent.addNested(nestedBlock); | ||
if (value.url) { | ||
path = "url(" + path + ")"; | ||
} | ||
if (type === 'media') { | ||
events.onMedia == null ? void 0 : events.onMedia(parent, condition, nestedBlock); | ||
} else { | ||
events.onSupports == null ? void 0 : events.onSupports(parent, condition, nestedBlock); | ||
} | ||
}); | ||
} | ||
if (value.media) { | ||
path += " " + value.media; | ||
function parseFallbackProperties(parent, fallbacks, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarationBlock(fallbacks, '@fallbacks'); | ||
} | ||
return path; | ||
utils.objectLoop(fallbacks, function (value, prop) { | ||
events.onFallback == null ? void 0 : events.onFallback(parent, prop, utils.toArray(value)); | ||
}); | ||
} | ||
var GlobalParser = function (_Parser) { | ||
_inheritsLoose(GlobalParser, _Parser); | ||
function GlobalParser() { | ||
return _Parser.apply(this, arguments) || this; | ||
function parseVariants(parent, variants, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarations(variants, '@variants'); | ||
} | ||
var _proto = GlobalParser.prototype; | ||
_proto.parse = function parse(styleSheet) { | ||
this.parseFontFacesMap(styleSheet['@font-face']); | ||
this.parseImport(styleSheet['@import']); | ||
this.parseKeyframesMap(styleSheet['@keyframes']); | ||
this.parsePage(styleSheet['@page']); | ||
this.parseRoot(styleSheet['@root']); | ||
this.parseRootVariables(styleSheet['@variables']); | ||
this.parseViewport(styleSheet['@viewport']); | ||
}; | ||
_proto.parseFontFacesMap = function parseFontFacesMap(fontFaces) { | ||
var _this = this; | ||
if (!fontFaces) { | ||
return; | ||
} | ||
if ("production" !== process.env.NODE_ENV) { | ||
if (!utils.isObject(fontFaces)) { | ||
throw new Error('@font-face must be an object of font family names to font faces.'); | ||
} | ||
} | ||
utils.objectLoop(fontFaces, function (faces, name) { | ||
utils.arrayLoop(utils.toArray(faces), function (fontFace) { | ||
_this.parseFontFace(fontFace, name); | ||
utils.objectLoop(variants, function (variant, parentType) { | ||
utils.objectLoop(variant, function (object, subType) { | ||
var type = parentType + "_" + subType; | ||
var block = parseLocalBlock(new Block(type), object, events); | ||
parent.addVariant(block); | ||
events.onVariant == null ? void 0 : events.onVariant(parent, type, block, { | ||
specificity: 0 | ||
}); | ||
}); | ||
}; | ||
}); | ||
} | ||
_proto.parseImport = function parseImport(imports) { | ||
var _this2 = this; | ||
function parseLocalBlock(parent, object, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
validateDeclarationBlock(object, parent.selector); | ||
} | ||
if (!imports) { | ||
return; | ||
} | ||
var props = _extends({}, object); | ||
var queue = createQueue(events); | ||
queue.add(props, '@fallbacks', function (data) { | ||
return parseFallbackProperties(parent, data, events); | ||
}); | ||
queue.add(props, '@media', function (data) { | ||
return parseConditionalBlock(parent, data, 'media', events); | ||
}); | ||
queue.add(props, '@selectors', function (data) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
if (!Array.isArray(imports)) { | ||
throw new TypeError('@import must be an array of strings or import objects.'); | ||
} | ||
validateDeclarations(data, '@selectors'); | ||
} | ||
utils.arrayLoop(imports, function (value) { | ||
_this2.emit('import', formatImport(value)); | ||
utils.objectLoop(data, function (value, key) { | ||
parseSelector(parent, key, value, true, events); | ||
}); | ||
}; | ||
}); | ||
queue.add(props, '@supports', function (data) { | ||
return parseConditionalBlock(parent, data, 'supports', events); | ||
}); | ||
queue.add(props, '@variables', function (data) { | ||
return parseVariables(parent, data, events); | ||
}); | ||
queue.add(props, '@variants', function (data) { | ||
return parseVariants(parent, data, events); | ||
}); | ||
var block = parseBlock(parent, props, events); | ||
queue.process(); | ||
return block; | ||
} | ||
_proto.parseKeyframesMap = function parseKeyframesMap(keyframes) { | ||
var _this3 = this; | ||
if (!keyframes) { | ||
return; | ||
function parseFontFacesMap(fontFaces, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
if (!utils.isObject(fontFaces)) { | ||
throw new Error('@font-face must be an object of font family names to font faces.'); | ||
} | ||
} | ||
if ("production" !== process.env.NODE_ENV) { | ||
if (!utils.isObject(keyframes)) { | ||
throw new Error('@keyframes must be an object of animation names to keyframes.'); | ||
} | ||
} | ||
utils.objectLoop(keyframes, function (keyframe, name) { | ||
_this3.parseKeyframes(keyframe, name); | ||
utils.objectLoop(fontFaces, function (faces, name) { | ||
utils.arrayLoop(utils.toArray(faces), function (fontFace) { | ||
parseFontFace(fontFace, name, events); | ||
}); | ||
}; | ||
}); | ||
} | ||
_proto.parsePage = function parsePage(page) { | ||
var _this4 = this; | ||
if (!page) { | ||
return; | ||
function parseImport(imports, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
if (!Array.isArray(imports)) { | ||
throw new TypeError('@import must be an array of strings or import objects.'); | ||
} | ||
} | ||
this.validateDeclarationBlock(page, '@page'); | ||
utils.arrayLoop(imports, function (value) { | ||
events.onImport == null ? void 0 : events.onImport(formatImport(value)); | ||
}); | ||
} | ||
var object = _extends({}, page); | ||
var pseudos = [':blank', ':first', ':left', ':right']; | ||
pseudos.forEach(function (selector) { | ||
var value = object[selector]; | ||
if (value) { | ||
_this4.emit('page', _this4.parseBlock(new Block("@page " + selector), value)); | ||
delete object[selector]; | ||
} | ||
}); | ||
if (Object.keys(object).length > 0) { | ||
this.emit('page', this.parseBlock(new Block('@page'), object)); | ||
function parseKeyframesMap(keyframes, events) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
if (!utils.isObject(keyframes)) { | ||
throw new Error('@keyframes must be an object of animation names to keyframes.'); | ||
} | ||
}; | ||
} | ||
_proto.parseRoot = function parseRoot(globals) { | ||
if (globals) { | ||
this.emit('root', this.parseLocalBlock(new Block('@root'), globals)); | ||
} | ||
}; | ||
utils.objectLoop(keyframes, function (keyframe, name) { | ||
parseKeyframes(keyframe, name, events); | ||
}); | ||
} | ||
_proto.parseRootVariables = function parseRootVariables(variables) { | ||
if (variables) { | ||
this.parseVariables(null, variables); | ||
} | ||
}; | ||
function parseRoot(globals, events) { | ||
var block = parseLocalBlock(new Block('@root'), globals, events); | ||
events.onRoot == null ? void 0 : events.onRoot(block); | ||
} | ||
_proto.parseViewport = function parseViewport(viewport) { | ||
if (viewport) { | ||
this.emit('viewport', this.parseBlock(new Block('@viewport'), viewport)); | ||
} | ||
}; | ||
function parseRootVariables(variables, events) { | ||
parseVariables(null, variables, events); | ||
} | ||
return GlobalParser; | ||
}(Parser); | ||
function parseGlobalStyleSheet(styleSheet, events) { | ||
var queue = createQueue(events); | ||
queue.add(styleSheet, '@font-face', parseFontFacesMap); | ||
queue.add(styleSheet, '@import', parseImport); | ||
queue.add(styleSheet, '@keyframes', parseKeyframesMap); | ||
queue.add(styleSheet, '@root', parseRoot); | ||
queue.add(styleSheet, '@variables', parseRootVariables); | ||
queue.process(); | ||
} | ||
var CLASS_NAME = /^[a-z\u017F\u212A]{1}[\x2D0-9_a-z\u017F\u212A]+$/i; | ||
var LocalParser = function (_Parser) { | ||
_inheritsLoose(LocalParser, _Parser); | ||
function LocalParser() { | ||
return _Parser.apply(this, arguments) || this; | ||
} | ||
var _proto = LocalParser.prototype; | ||
_proto.parse = function parse(styleSheet) { | ||
var _this = this; | ||
utils.objectLoop(styleSheet, function (declaration, selector) { | ||
if (selector.charAt(0) === '@') { | ||
if ("production" !== process.env.NODE_ENV) { | ||
throw new SyntaxError("At-rules may not be defined at the root of a local block, found \"" + selector + "\"."); | ||
} | ||
} else if (typeof declaration === 'string' && declaration.match(CLASS_NAME)) { | ||
_this.emit('class', selector, declaration); | ||
} else if (utils.isObject(declaration)) { | ||
_this.emit('rule', selector, _this.parseLocalBlock(new Block(selector), declaration)); | ||
} else if ("production" !== process.env.NODE_ENV) { | ||
throw new Error("Invalid declaration for \"" + selector + "\". Must be an object (style declaration) or string (class name)."); | ||
function parseLocalStyleSheet(styleSheet, events) { | ||
utils.objectLoop(styleSheet, function (declaration, selector) { | ||
if (selector[0] === '@') { | ||
if ("production" !== process.env.NODE_ENV) { | ||
throw new SyntaxError("At-rules may not be defined at the root of a local block, found \"" + selector + "\"."); | ||
} | ||
}); | ||
}; | ||
} else if (typeof declaration === 'string' && declaration.match(CLASS_NAME)) { | ||
events.onClass == null ? void 0 : events.onClass(selector, declaration); | ||
} else if (utils.isObject(declaration)) { | ||
var block = parseLocalBlock(new Block(selector), declaration, events); | ||
events.onRule == null ? void 0 : events.onRule(selector, block); | ||
} else if ("production" !== process.env.NODE_ENV) { | ||
throw new Error("Invalid declaration for \"" + selector + "\". Must be an object (style declaration) or string (class name)."); | ||
} | ||
}); | ||
} | ||
return LocalParser; | ||
}(Parser); | ||
exports.Block = Block; | ||
exports.GlobalParser = GlobalParser; | ||
exports.LocalParser = LocalParser; | ||
exports.formatFontFace = formatFontFace; | ||
exports.formatImport = formatImport; | ||
exports.parseGlobalStyleSheet = parseGlobalStyleSheet; | ||
exports.parseLocalStyleSheet = parseLocalStyleSheet; |
@@ -124,2 +124,3 @@ import { CSST, FontFace as BaseFontFace, Keyframes as BaseKeyframes, Declarations, Property, Value, Variables } from '@aesthetic/types'; | ||
} | ||
export declare type FontFaceMap = Record<string, FontFace | FontFace[]>; | ||
export interface Import { | ||
@@ -130,16 +131,5 @@ path: string; | ||
} | ||
export declare type ImportList = (string | Import)[]; | ||
export declare type Keyframes = BaseKeyframes<Rule>; | ||
export declare type Viewport = CSST.AtRule.Viewport<Value>; | ||
export declare type PageMargins = '@top-left-corner' | '@top-left' | '@top-center' | '@top-right' | '@top-right-corner' | '@bottom-left-corner' | '@bottom-left' | '@bottom-center' | '@bottom-right' | '@bottom-right-corner' | '@left-top' | '@left-middle' | '@left-bottom' | '@right-top' | '@right-middle' | '@right-bottom'; | ||
export declare type PageBlock = Properties & { | ||
bleed?: string; | ||
marks?: string; | ||
size?: string; | ||
} & { | ||
[K in PageMargins]?: PageBlock; | ||
}; | ||
export declare type PagePseudos = ':blank' | ':first' | ':left' | ':right'; | ||
export declare type Page = PageBlock & { | ||
[K in PagePseudos]?: PageBlock; | ||
}; | ||
export declare type KeyframesMap = Record<string, Keyframes>; | ||
export declare type LocalAtRule = '@fallbacks' | '@media' | '@selectors' | '@supports' | '@variables' | '@variants'; | ||
@@ -163,11 +153,9 @@ export declare type LocalBlock = Rule & { | ||
}; | ||
export declare type GlobalAtRule = '@font-face' | '@import' | '@keyframes' | '@page' | '@root' | '@variables' | '@viewport'; | ||
export declare type GlobalAtRule = '@font-face' | '@import' | '@keyframes' | '@root' | '@variables'; | ||
export interface GlobalStyleSheet { | ||
'@font-face'?: Record<string, FontFace | FontFace[]>; | ||
'@import'?: (string | Import)[]; | ||
'@keyframes'?: Record<string, Keyframes>; | ||
'@page'?: Page; | ||
'@font-face'?: FontFaceMap; | ||
'@import'?: ImportList; | ||
'@keyframes'?: KeyframesMap; | ||
'@root'?: LocalBlock; | ||
'@variables'?: Variables; | ||
'@viewport'?: Viewport; | ||
} | ||
@@ -183,11 +171,9 @@ export declare type GlobalStyleSheetNeverize<T> = { | ||
export declare type Processor<T> = (value: T, onProcess: OnProcessProperty) => Value | undefined | void; | ||
export interface ProcessorMap { | ||
[key: string]: Processor<any>; | ||
} | ||
export declare type BlockConditionListener<T extends object> = (parent: Block<T>, condition: string, value: Block<T>) => void; | ||
export declare type BlockNestedListener<T extends object> = (parent: Block<T>, name: string, value: Block<T>, params: NestedBlockParams) => void; | ||
export declare type BlockPropertyListener<T extends object> = (parent: Block<T>, name: string, value: unknown) => void; | ||
export declare type ProcessorMap = Record<string, Processor<any>>; | ||
export declare type ConditionListener<T extends object> = (parent: Block<T>, condition: string, value: Block<T>) => void; | ||
export declare type NestedListener<T extends object> = (parent: Block<T>, name: string, value: Block<T>, params: NestedBlockParams) => void; | ||
export declare type PropertyListener<T extends object> = (parent: Block<T>, name: string, value: unknown) => void; | ||
export declare type BlockListener<T extends object> = (block: Block<T>) => void; | ||
export declare type ClassNameListener = (selector: string, className: string) => void; | ||
export declare type FontFaceListener<T extends object> = (fontFace: Block<T>, fontFamily: string, srcPaths: string[]) => void; | ||
export declare type FontFaceListener<T extends object> = (fontFace: Block<T>, fontFamily: string, srcPaths: string[]) => string; | ||
export declare type ImportListener = (path: string) => void; | ||
@@ -197,2 +183,21 @@ export declare type KeyframesListener<T extends object> = (keyframes: Block<T>, animationName: string | undefined) => string; | ||
export declare type VariableListener = (name: string, value: Value) => void; | ||
export interface Events<T extends object> { | ||
onAttribute?: NestedListener<T>; | ||
onBlock?: BlockListener<T>; | ||
onFallback?: PropertyListener<T>; | ||
onFontFace?: FontFaceListener<T>; | ||
onKeyframes?: KeyframesListener<T>; | ||
onMedia?: ConditionListener<T>; | ||
onProperty?: PropertyListener<T>; | ||
onPseudo?: NestedListener<T>; | ||
onSelector?: NestedListener<T>; | ||
onSupports?: ConditionListener<T>; | ||
onVariable?: PropertyListener<T>; | ||
onVariant?: NestedListener<T>; | ||
onClass?: ClassNameListener; | ||
onRule?: RuleListener<T>; | ||
onImport?: ImportListener; | ||
onRoot?: BlockListener<T>; | ||
onRootVariable?: VariableListener; | ||
} | ||
//# sourceMappingURL=types.d.ts.map |
{ | ||
"name": "@aesthetic/sss", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"description": "A strict, type-safe, and structure-safe component style sheet format.", | ||
@@ -29,5 +29,5 @@ "keywords": [ | ||
"@aesthetic/types": "^0.2.0", | ||
"@aesthetic/utils": "^0.3.0" | ||
"@aesthetic/utils": "^0.4.0" | ||
}, | ||
"gitHead": "4ad762397a9e6b7d3cc2b83d8fc7b3d1172a197b" | ||
"gitHead": "8297745d639624433c264a334304166344702cfc" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
54
69302
1238
33
+ Added@aesthetic/utils@0.4.5(transitive)
- Removed@aesthetic/utils@0.3.0(transitive)
Updated@aesthetic/utils@^0.4.0