Comparing version 4.0.1 to 4.1.0
850
dist/fela.js
@@ -38,2 +38,17 @@ (function (global, factory) { | ||
babelHelpers.defineProperty = function (obj, key, value) { | ||
if (key in obj) { | ||
Object.defineProperty(obj, key, { | ||
value: value, | ||
enumerable: true, | ||
configurable: true, | ||
writable: true | ||
}); | ||
} else { | ||
obj[key] = value; | ||
} | ||
return obj; | ||
}; | ||
babelHelpers.extends = Object.assign || function (target) { | ||
@@ -104,106 +119,2 @@ for (var i = 1; i < arguments.length; i++) { | ||
/* weak */ | ||
/** | ||
* generates a hashcode from a string | ||
* taken from http://stackoverflow.com/a/7616484 | ||
* | ||
* @param {string} str - str used to generate the unique hash code | ||
* @return {string} compressed content hash | ||
*/ | ||
function generateContentHash(str) { | ||
var hash = 0; | ||
var iterator = 0; | ||
var char = void 0; | ||
var length = str.length; | ||
// return a `s` for empty strings | ||
// to symbolize `static` | ||
if (length === 0) { | ||
return ''; | ||
} | ||
for (; iterator < length; ++iterator) { | ||
char = str.charCodeAt(iterator); | ||
hash = (hash << 5) - hash + char; | ||
hash |= 0; | ||
} | ||
return '-' + hash.toString(36); | ||
} | ||
/** | ||
* generates an unique reference hash | ||
* | ||
* @param {Object} style - style that get hashed | ||
* @return {string} hash - unique style hash | ||
*/ | ||
var generateStyleHash = (function (style) { | ||
return generateContentHash(JSON.stringify(style)); | ||
}); | ||
/* weak */ | ||
var formats = { | ||
'.woff': 'woff', | ||
'.eot': 'eot', | ||
'.ttf': 'truetype', | ||
'.svg': 'svg' | ||
}; | ||
// Returns the font format for a specific font source | ||
function getFontFormat(src) { | ||
return Object.keys(formats).reduce(function (format, extension) { | ||
if (src.indexOf(extension) > -1) { | ||
format = formats[extension]; | ||
} | ||
return format; // eslint-disable-line | ||
}, undefined); | ||
} | ||
/* weak */ | ||
/** | ||
* pipes a style object through a list of plugins | ||
* | ||
* @param {Object} style - style object to process | ||
* @param {Object} meta - additional meta data | ||
* @param {Function[]} plugins - plugins used to process style | ||
* @return {Object} processed style | ||
*/ | ||
function processStyle(style, meta, plugins) { | ||
return plugins.reduce(function (processedStyle, plugin) { | ||
return plugin(processedStyle, meta); | ||
}, style); | ||
} | ||
/** | ||
* diffs a style object against a base style object | ||
* | ||
* @param {Object} style - style object which is diffed | ||
* @param {Object?} base - base style object | ||
*/ | ||
function diffStyle(style) { | ||
var base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
return Object.keys(style).reduce(function (diff, property) { | ||
var value = style[property]; | ||
// recursive object iteration in order to render | ||
// pseudo class and media class declarations | ||
if (value instanceof Object && !Array.isArray(value)) { | ||
var nestedDiff = diffStyle(value, base[property]); | ||
if (Object.keys(nestedDiff).length > 0) { | ||
diff[property] = nestedDiff; | ||
} | ||
} else { | ||
// diff styles with the base styles to only extract dynamic styles | ||
if (value !== undefined && base[property] !== value) { | ||
// remove concatenated string values including `undefined` | ||
if (typeof value === 'string' && value.indexOf('undefined') > -1) { | ||
return diff; | ||
} | ||
diff[property] = value; | ||
} | ||
} | ||
return diff; | ||
}, {}); | ||
} | ||
var index$1 = __commonjs(function (module) { | ||
@@ -223,4 +134,8 @@ 'use strict'; | ||
var hypenateStyleName = (index$1 && typeof index$1 === 'object' && 'default' in index$1 ? index$1['default'] : index$1); | ||
var hyphenateStyleName = (index$1 && typeof index$1 === 'object' && 'default' in index$1 ? index$1['default'] : index$1); | ||
function generateCSSDeclaration(property, value) { | ||
return hyphenateStyleName(property) + ':' + value; | ||
} | ||
/* weak */ | ||
@@ -243,32 +158,24 @@ var warning = function warning() { | ||
/** | ||
* generates a valid CSS string containing style | ||
* | ||
* @param {Object} style - object containing CSS declarations | ||
* @returns {string} valid CSS string with dash cased properties | ||
*/ | ||
function cssifyObject(style) { | ||
return Object.keys(style).reduce(function (css, prop) { | ||
// warn if invalid values are rendered | ||
warning$1(typeof style[prop] === 'string' || typeof style[prop] === 'number', 'The invalid value `' + style[prop] + '` has been used as `' + prop + '`.'); | ||
var css = ''; | ||
for (var property in style) { | ||
warning$1(typeof style[property] === 'string' || typeof style[property] === 'number', 'The invalid value `' + style[property] + '` has been used as `' + property + '`.'); | ||
// prevents the semicolon after | ||
// the last rule declaration | ||
if (css.length > 0) { | ||
if (css) { | ||
css += ';'; | ||
} | ||
css += hypenateStyleName(prop) + ':' + style[prop]; | ||
return css; | ||
}, ''); | ||
css += generateCSSDeclaration(property, style[property]); | ||
} | ||
return css; | ||
} | ||
/** | ||
* renders keyframes into a CSS string with all prefixes | ||
* | ||
* @param {Object} frames - validated frame declarations | ||
* @param {string} animationName - animation reference naming | ||
* @param {string[]} prefixes - list of used vendor prefixes | ||
* @return {string} valid CSS string | ||
*/ | ||
function cssifyFontFace(fontFace) { | ||
return '@font-face{' + cssifyObject(fontFace) + '}'; | ||
} | ||
function cssifyKeyframe(frames, animationName) { | ||
@@ -286,12 +193,143 @@ var prefixes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ['']; | ||
/** | ||
* creates a new renderer instance | ||
* | ||
* @param {Object} config - renderer configuration | ||
* @return {Object} new renderer instance | ||
*/ | ||
/* weak */ | ||
function cssifyMediaQueryRules(mediaQuery, mediaQueryRules) { | ||
return '@media ' + mediaQuery + '{' + mediaQueryRules + '}'; | ||
} | ||
/* weak */ | ||
function generateAnimationName(id) { | ||
return 'k' + id; | ||
} | ||
/* weak */ | ||
var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; | ||
function generateClassName(id) { | ||
var className = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; | ||
if (id <= 52) { | ||
return chars[id - 1] + className; | ||
} | ||
// Bitwise floor as safari performs much faster https://jsperf.com/math-floor-vs-math-round-vs-parseint/55 | ||
return generateClassName(id / 52 | 0, chars[id % 52] + className); | ||
} | ||
/* weak */ | ||
function generateCombinedMediaQuery(currentMediaQuery, nestedMediaQuery) { | ||
if (currentMediaQuery.length === 0) { | ||
return nestedMediaQuery; | ||
} | ||
return currentMediaQuery + ' and ' + nestedMediaQuery; | ||
} | ||
/* weak */ | ||
function generateCSSRule(selector, cssDeclaration) { | ||
return selector + '{' + cssDeclaration + '}'; | ||
} | ||
/* weak */ | ||
function getCSSSelector(className) { | ||
var pseudo = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; | ||
return '.' + className + pseudo; | ||
} | ||
/* weak */ | ||
function minifyCSSString(style) { | ||
return style.replace(/\s{2,}/g, ''); | ||
} | ||
/* weak */ | ||
function processStyleWithPlugins(style, plugins, type) { | ||
for (var i = 0; i < plugins.length; ++i) { | ||
style = plugins[i](style, type); | ||
} | ||
return style; | ||
} | ||
/* weak */ | ||
var RULE_TYPE = 1; | ||
var KEYFRAME_TYPE = 2; | ||
var FONT_TYPE = 3; | ||
var STATIC_TYPE = 4; | ||
var CLEAR_TYPE = 5; | ||
function cssifyStaticStyle(staticStyle, plugins) { | ||
if (typeof staticStyle === 'string') { | ||
return minifyCSSString(staticStyle); | ||
} | ||
var processedStaticStyle = processStyleWithPlugins(staticStyle, plugins, STATIC_TYPE); | ||
return cssifyObject(processedStaticStyle); | ||
} | ||
/* weak */ | ||
function generateStaticReference(style, selector) { | ||
if (typeof style === 'string') { | ||
return style; | ||
} | ||
return selector + JSON.stringify(style); | ||
} | ||
/* weak */ | ||
function isAttributeSelector(property) { | ||
return property.charAt(0) === '['; | ||
} | ||
/* weak */ | ||
function isPseudoSelector(property) { | ||
return property.charAt(0) === ':'; | ||
} | ||
/* weak */ | ||
function isMediaQuery(property) { | ||
return property.substr(0, 6) === '@media'; | ||
} | ||
/* weak */ | ||
function applyMediaRulesInOrder(order) { | ||
var mediaRules = {}; | ||
for (var i = 0, len = order.length; i < len; ++i) { | ||
mediaRules[order[i]] = ''; | ||
} | ||
return mediaRules; | ||
} | ||
/* weak */ | ||
function toCSSString(value) { | ||
if (value.charAt(0) === '"') { | ||
return value; | ||
} | ||
return '"' + value + '"'; | ||
} | ||
/* weak */ | ||
var formats = { | ||
'.woff': 'woff', | ||
'.eot': 'eot', | ||
'.ttf': 'truetype', | ||
'.svg': 'svg' | ||
}; | ||
var extensions = Object.keys(formats); | ||
function checkFontFormat(src) { | ||
for (var i = 0, len = extensions.length; i < len; ++i) { | ||
var extension = extensions[i]; | ||
if (src.indexOf(extension) !== -1) { | ||
return formats[extension]; | ||
} | ||
} | ||
// TODO: warning: wrong font format | ||
} | ||
function createRenderer() { | ||
var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
// the renderer is the key | ||
var renderer = { | ||
@@ -302,10 +340,6 @@ listeners: [], | ||
// try and use readable selectors when | ||
// prettySelectors is on and not in a prod environment | ||
prettySelectors: config.prettySelectors && true, | ||
// prettySelectors is currently useless, might reimplement better DX classNames later | ||
// prettySelectors: config.prettySelectors && process.env.NODE_ENV !== 'production', | ||
mediaQueryOrder: config.mediaQueryOrder || [], | ||
/** | ||
* clears the sheet's cache but keeps all listeners | ||
*/ | ||
clear: function clear() { | ||
@@ -316,272 +350,158 @@ renderer.fontFaces = ''; | ||
renderer.rules = ''; | ||
renderer.mediaRules = renderer.mediaQueryOrder.reduce(function (rules, media) { | ||
rules[media] = ''; | ||
return rules; | ||
}, {}); | ||
// apply media rules in an explicit order to ensure | ||
// correct media query execution order | ||
renderer.mediaRules = applyMediaRulesInOrder(renderer.mediaQueryOrder); | ||
renderer.rendered = []; | ||
renderer.uniqueRuleIdentifier = 0; | ||
renderer.uniqueKeyframeIdentifier = 0; | ||
// use a flat cache object with pure string references | ||
// to achieve maximal lookup performance and memoization speed | ||
renderer.cache = {}; | ||
renderer.rendered = {}; | ||
renderer.base = []; | ||
renderer.ids = []; | ||
renderer.baseClassName = {}; | ||
renderer.callStack = []; | ||
// emit changes to notify subscribers | ||
renderer._emitChange({ type: 'clear' }); | ||
// initial change emit to enforce a clear start | ||
renderer._emitChange({ type: CLEAR_TYPE }); | ||
}, | ||
/** | ||
* renders a new rule variation and caches the result | ||
* | ||
* @param {Function} rule - rule which gets rendered | ||
* @param {Object?} props - properties used to render | ||
* @param {Object?} defaultProps - properties used to render the static style | ||
* @return {string} className to reference the rendered rule | ||
*/ | ||
renderRule: function renderRule(rule) { | ||
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var defaultProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
// rendering a rule for the first time | ||
// will create an ID reference | ||
if (renderer.ids.indexOf(rule) === -1) { | ||
renderer.ids.push(rule); | ||
var processedStyle = processStyleWithPlugins(rule(props), renderer.plugins, RULE_TYPE); | ||
return renderer._renderStyleToClassNames(processedStyle).slice(1); | ||
}, | ||
_renderStyleToClassNames: function _renderStyleToClassNames(style) { | ||
var pseudo = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; | ||
var media = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; | ||
// directly render the static base style to be able | ||
// to diff future dynamic style with those | ||
try { | ||
renderer.renderRule(rule, defaultProps, defaultProps); | ||
} catch (error) { | ||
warning$1(false, 'Nested props have been used without passing \'defaultProps\'. This will disable static style splitting for \'' + (rule.name ? rule.name : 'unkown_rule') + '\'.'); | ||
} | ||
} | ||
var classNames = ''; | ||
var ruleProps = babelHelpers.extends({}, defaultProps, props); | ||
for (var property in style) { | ||
var value = style[property]; | ||
if (value instanceof Object) { | ||
if (isPseudoSelector(property) || isAttributeSelector(property)) { | ||
classNames += renderer._renderStyleToClassNames(value, pseudo + property, media); | ||
} else if (isMediaQuery(property)) { | ||
var combinedMediaQuery = generateCombinedMediaQuery(media, property.slice(6).trim()); | ||
classNames += renderer._renderStyleToClassNames(value, pseudo, combinedMediaQuery); | ||
} else { | ||
// TODO: warning | ||
} | ||
} else { | ||
var delcarationReference = media + pseudo + property + value; | ||
if (!renderer.cache[delcarationReference]) { | ||
var className = generateClassName(++renderer.uniqueRuleIdentifier); | ||
var style = rule(ruleProps); | ||
var styleId = renderer._generateStyleId(style); | ||
renderer.cache[delcarationReference] = className; | ||
var className = 'c' + styleId; | ||
var cssDeclaration = generateCSSDeclaration(property, value); | ||
var selector = getCSSSelector(className, pseudo); | ||
var cssRule = generateCSSRule(selector, cssDeclaration); | ||
// extend the className with prefixes in development | ||
// this enables better debugging and className readability | ||
if (true) { | ||
className = (renderer._selectorPrefix ? renderer._selectorPrefix + '__' : '') + (renderer.prettySelectors && rule.name ? rule.name + '__' : '') + className; | ||
} | ||
if (media) { | ||
if (!renderer.mediaRules.hasOwnProperty(media)) { | ||
renderer.mediaRules[media] = ''; | ||
} | ||
renderer.mediaRules[media] += cssRule; | ||
} else { | ||
renderer.rules += cssRule; | ||
} | ||
// only if the rule has not already been rendered | ||
// with a specific set of properties it actually renders | ||
if (!renderer.rendered.hasOwnProperty(className)) { | ||
// process style using each plugin | ||
var processedStyle = processStyle(style, { | ||
type: 'rule', | ||
className: className, | ||
props: ruleProps, | ||
rule: rule | ||
}, renderer.plugins); | ||
renderer._emitChange({ | ||
selector: selector, | ||
declaration: cssDeclaration, | ||
media: media, | ||
type: RULE_TYPE | ||
}); | ||
} | ||
var ruleId = renderer.ids.indexOf(rule); | ||
// diff style objects with base styles | ||
var diffedStyle = diffStyle(processedStyle, renderer.base[ruleId]); | ||
renderer.rendered[className] = false; | ||
if (Object.keys(diffedStyle).length > 0) { | ||
renderer._renderStyle(className, diffedStyle); | ||
classNames += ' ' + renderer.cache[delcarationReference]; | ||
} | ||
renderer.callStack.push(renderer.renderRule.bind(renderer, rule, props, defaultProps)); | ||
// keep static style to diff dynamic onces later on | ||
if (props === defaultProps) { | ||
renderer.base[ruleId] = diffedStyle; | ||
renderer.baseClassName[ruleId] = className; | ||
return renderer.rendered[className] ? className : ''; | ||
} else { | ||
renderer.baseClassName[styleId] = renderer.baseClassName[ruleId]; | ||
} | ||
} | ||
var baseClassName = renderer.baseClassName[styleId]; | ||
// if current className is empty | ||
// return either the static class or empty string | ||
if (!renderer.rendered[className]) { | ||
return renderer.rendered[baseClassName] ? baseClassName : ''; | ||
} | ||
// if the current className is a dynamic rule | ||
// return both classNames if static subset is not empty | ||
if (className !== baseClassName) { | ||
return (renderer.rendered[baseClassName] ? baseClassName + ' ' : '') + className; | ||
} | ||
return className; | ||
return classNames; | ||
}, | ||
/** | ||
* renders a new keyframe variation and caches the result | ||
* | ||
* @param {Keyframe} keyframe - Keyframe which gets rendered | ||
* @param {Object?} props - properties used to render | ||
* @return {string} animationName to reference the rendered keyframe | ||
*/ | ||
renderKeyframe: function renderKeyframe(keyframe) { | ||
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var style = keyframe(props); | ||
var styleId = renderer._generateStyleId(style); | ||
var resolvedKeyframe = keyframe(props); | ||
var keyframeReference = JSON.stringify(resolvedKeyframe); | ||
var animationName = 'k' + styleId; | ||
if (!renderer.cache[keyframeReference]) { | ||
// use another unique identifier to ensure minimal css markup | ||
var animationName = generateAnimationName(++renderer.uniqueKeyframeIdentifier); | ||
// extend the animationName with prefixes in development | ||
// this enables better debugging and className readability | ||
if (true) { | ||
animationName = (renderer.prettySelectors && keyframe.name ? keyframe.name + '__' : '') + animationName; | ||
} | ||
var processedKeyframe = processStyleWithPlugins(resolvedKeyframe, renderer.plugins, KEYFRAME_TYPE); | ||
var cssKeyframe = cssifyKeyframe(processedKeyframe, animationName, renderer.keyframePrefixes); | ||
renderer.cache[keyframeReference] = animationName; | ||
renderer.keyframes += cssKeyframe; | ||
// only if the keyframe has not already been rendered | ||
// with a specific set of properties it actually renders | ||
if (!renderer.rendered.hasOwnProperty(animationName)) { | ||
var processedKeyframe = processStyle(style, { | ||
type: 'keyframe', | ||
keyframe: keyframe, | ||
props: props, | ||
animationName: animationName | ||
}, renderer.plugins); | ||
var css = cssifyKeyframe(processedKeyframe, animationName, renderer.keyframePrefixes); | ||
renderer.rendered[animationName] = true; | ||
renderer.keyframes += css; | ||
renderer.callStack.push(renderer.renderKeyframe.bind(renderer, keyframe, props)); | ||
renderer._emitChange({ | ||
name: animationName, | ||
style: processedKeyframe, | ||
css: css, | ||
type: 'keyframe' | ||
keyframe: cssKeyframe, | ||
type: KEYFRAME_TYPE | ||
}); | ||
} | ||
return animationName; | ||
return renderer.cache[keyframeReference]; | ||
}, | ||
/** | ||
* renders a new font-face and caches it | ||
* | ||
* @param {FontFace} fontFace - fontFace which gets rendered | ||
* @return {string} fontFamily reference | ||
*/ | ||
renderFont: function renderFont(family, files) { | ||
var properties = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
var key = family + generateStyleHash(properties); | ||
var fontReference = family + JSON.stringify(properties); | ||
if (!renderer.rendered.hasOwnProperty(key)) { | ||
(function () { | ||
var fontFace = { | ||
fontFamily: '\'' + family + '\'', | ||
src: files.map(function (src) { | ||
return 'url(\'' + src + '\') format(\'' + getFontFormat(src) + '\')'; | ||
}).join(',') | ||
}; | ||
if (!renderer.cache[fontReference]) { | ||
var fontFamily = toCSSString(family); | ||
var fontProperties = ['fontVariant', 'fontWeight', 'fontStretch', 'fontStyle', 'unicodeRange']; | ||
Object.keys(properties).filter(function (prop) { | ||
return fontProperties.indexOf(prop) > -1; | ||
}).forEach(function (fontProp) { | ||
return fontFace[fontProp] = properties[fontProp]; | ||
}); | ||
// TODO: proper font family generation with error proofing | ||
var fontFace = babelHelpers.extends({}, properties, { | ||
src: files.map(function (src) { | ||
return 'url(\'' + src + '\') format(\'' + checkFontFormat(src) + '\')'; | ||
}).join(','), | ||
fontFamily: fontFamily | ||
}); | ||
var css = '@font-face{' + cssifyObject(fontFace) + '}'; | ||
var cssFontFace = cssifyFontFace(fontFace); | ||
renderer.cache[fontReference] = fontFamily; | ||
renderer.fontFaces += cssFontFace; | ||
renderer.rendered[key] = true; | ||
renderer.fontFaces += css; | ||
renderer.callStack.push(renderer.renderFont.bind(renderer, family, files, properties)); | ||
renderer._emitChange({ | ||
fontFamily: family, | ||
fontFace: fontFace, | ||
css: css, | ||
type: 'font' | ||
}); | ||
})(); | ||
renderer._emitChange({ | ||
fontFamily: fontFamily, | ||
fontFace: cssFontFace, | ||
type: FONT_TYPE | ||
}); | ||
} | ||
return family; | ||
return renderer.cache[fontReference]; | ||
}, | ||
renderStatic: function renderStatic(staticStyle, selector) { | ||
var staticReference = generateStaticReference(staticStyle, selector); | ||
if (!renderer.cache[staticReference]) { | ||
var cssDeclarations = cssifyStaticStyle(staticStyle, renderer.plugins); | ||
renderer.cache[staticReference] = true; | ||
/** | ||
* renders static style and caches them | ||
* | ||
* @param {string|Object} style - static style to be rendered | ||
* @param {string?} selector - selector used to render the styles | ||
* @return {string} rendered CSS output | ||
*/ | ||
renderStatic: function renderStatic(style, selector) { | ||
var reference = typeof style === 'string' ? style : selector + JSON.stringify(style); | ||
if (!renderer.rendered.hasOwnProperty(reference)) { | ||
if (typeof style === 'string') { | ||
var css = style.replace(/\s{2,}/g, ''); | ||
// remove new lines from template strings | ||
renderer.statics += css; | ||
if (typeof staticStyle === 'string') { | ||
renderer.statics += cssDeclarations; | ||
renderer._emitChange({ | ||
selector: selector, | ||
type: 'static', | ||
css: css | ||
type: STATIC_TYPE, | ||
css: cssDeclarations | ||
}); | ||
} else { | ||
var processedStyle = processStyle(style, { | ||
selector: selector, | ||
type: 'static' | ||
}, renderer.plugins); | ||
var _css = cssifyObject(processedStyle); | ||
renderer.statics += selector + '{' + _css + '}'; | ||
renderer.callStack.push(renderer.renderStatic.bind(renderer, style, selector)); | ||
renderer.statics += generateCSSRule(selector, cssDeclarations); | ||
renderer._emitChange({ | ||
selector: selector, | ||
style: processedStyle, | ||
css: _css, | ||
type: 'rule' | ||
declaration: cssDeclarations, | ||
type: RULE_TYPE, | ||
media: '' | ||
}); | ||
} | ||
renderer.rendered[reference] = true; | ||
} | ||
}, | ||
/** | ||
* renders all cached styles into a single valid CSS string | ||
* clusters media query styles into groups to reduce output size | ||
* @return single concatenated CSS string | ||
*/ | ||
renderToString: function renderToString() { | ||
var css = renderer.fontFaces + renderer.statics + renderer.rules; | ||
var css = renderer.fontFaces + renderer.statics + renderer.keyframes + renderer.rules; | ||
for (var media in renderer.mediaRules) { | ||
var rules = renderer.mediaRules[media]; | ||
if (rules.length > 0) { | ||
css += '@media ' + media + '{' + rules + '}'; | ||
} | ||
css += cssifyMediaQueryRules(media, renderer.mediaRules[media]); | ||
} | ||
return css + renderer.keyframes; | ||
return css; | ||
}, | ||
/** | ||
* Adds a new subscription to get notified on every rerender | ||
* | ||
* @param {Function} callback - callback function which will be executed | ||
* @return {Object} equivalent unsubscribe method | ||
*/ | ||
subscribe: function subscribe(callback) { | ||
@@ -595,107 +515,5 @@ renderer.listeners.push(callback); | ||
}, | ||
/** | ||
* rehydrates the whole cache using the callStack | ||
*/ | ||
rehydrate: function rehydrate() { | ||
var callStack = renderer.callStack.slice(0); | ||
// clears the current callStack | ||
renderer.clear(); | ||
renderer._emitChange({ type: 'rehydrate', done: false }); | ||
callStack.forEach(function (fn) { | ||
return fn(); | ||
}); | ||
renderer._emitChange({ type: 'rehydrate', done: true }); | ||
}, | ||
/** | ||
* generates a unique style id | ||
* | ||
* @param {Object} style - style object | ||
* @return {string} minimal string id | ||
*/ | ||
_generateStyleId: function _generateStyleId(style) { | ||
var styleHash = generateStyleHash(style); | ||
if (renderer.ids.indexOf(styleHash) === -1) { | ||
renderer.ids.push(styleHash); | ||
} | ||
return renderer.ids.indexOf(styleHash).toString(36); | ||
}, | ||
/** | ||
* calls each listener with a change object | ||
* gets only called if something actually changes | ||
* | ||
* @param {Function} callback - callback function which will be executed | ||
* @return {Object} equivalent unsubscribe method | ||
*/ | ||
_emitChange: function _emitChange(change) { | ||
renderer.listeners.forEach(function (listener) { | ||
return listener(change, renderer); | ||
}); | ||
}, | ||
/** | ||
* iterates a style object and renders each rule to the cache | ||
* | ||
* @param {string} className - className reference to be rendered to | ||
* @param {Object} style - style object which is rendered | ||
*/ | ||
_renderStyle: function _renderStyle(className, style) { | ||
var pseudo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; | ||
var media = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ''; | ||
var ruleset = Object.keys(style).reduce(function (ruleset, property) { | ||
var value = style[property]; | ||
// recursive object iteration in order to render | ||
// pseudo class and media class declarations | ||
if (value instanceof Object && !Array.isArray(value)) { | ||
// allow pseudo classes, attribute selectors and the child selector | ||
if (property.match(/^(:|\[|>)/) !== null) { | ||
renderer._renderStyle(className, value, pseudo + property, media); | ||
} else if (property.substr(0, 6) === '@media') { | ||
// combine media query rules with an `and` | ||
var query = property.slice(6).trim(); | ||
var combinedMedia = media.length > 0 ? media + ' and ' + query : query; | ||
renderer._renderStyle(className, value, pseudo, combinedMedia); | ||
} | ||
} else { | ||
ruleset[property] = value; | ||
} | ||
return ruleset; | ||
}, {}); | ||
// add styles to the cache | ||
if (Object.keys(ruleset).length > 0) { | ||
renderer.rendered[className] = true; | ||
var css = cssifyObject(ruleset); | ||
var selector = '.' + className + pseudo; | ||
var cssRule = selector + '{' + css + '}'; | ||
if (media.length > 0) { | ||
if (!renderer.mediaRules.hasOwnProperty(media)) { | ||
renderer.mediaRules[media] = ''; | ||
} | ||
renderer.mediaRules[media] += cssRule; | ||
} else { | ||
renderer.rules += cssRule; | ||
} | ||
renderer._emitChange({ | ||
selector: selector, | ||
style: ruleset, | ||
css: css, | ||
media: media, | ||
type: 'rule' | ||
}); | ||
for (var i = 0, len = renderer.listeners.length; i < len; ++i) { | ||
renderer.listeners[i](change); | ||
} | ||
@@ -709,7 +527,6 @@ } | ||
// enhance renderer with passed set of enhancers | ||
if (config.enhancers) { | ||
config.enhancers.forEach(function (enhancer) { | ||
return renderer = enhancer(renderer); | ||
}); | ||
for (var i = 0, len = config.enhancers.length; i < len; ++i) { | ||
renderer = config.enhancers[i](renderer); | ||
} | ||
} | ||
@@ -722,17 +539,21 @@ | ||
function assign(base) { | ||
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = arguments[_key]; | ||
for (var _len = arguments.length, extendingStyles = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
extendingStyles[_key - 1] = arguments[_key]; | ||
} | ||
return args.reduce(function (extend, obj) { | ||
for (var property in obj) { | ||
var value = obj[property]; | ||
if (extend[property] instanceof Object && value instanceof Object) { | ||
extend[property] = assign({}, extend[property], value); | ||
for (var i = 0, len = extendingStyles.length; i < len; ++i) { | ||
var style = extendingStyles[i]; | ||
for (var property in style) { | ||
var value = style[property]; | ||
if (base[property] instanceof Object && value instanceof Object) { | ||
base[property] = assign({}, base[property], value); | ||
} else { | ||
extend[property] = value; | ||
base[property] = value; | ||
} | ||
} | ||
return extend; | ||
}, base); | ||
} | ||
return base; | ||
} | ||
@@ -745,6 +566,10 @@ | ||
return function combined(props) { | ||
return rules.reduce(function (style, rule) { | ||
return assign(style, rule(props)); | ||
}, {}); | ||
return function (props) { | ||
var style = {}; | ||
for (var i = 0, len = rules.length; i < len; ++i) { | ||
assign(style, rules[i](props)); | ||
} | ||
return style; | ||
}; | ||
@@ -760,6 +585,10 @@ } | ||
return function (createRenderer) { | ||
return function () { | ||
return enhancers.reduce(function (renderer, enhancer) { | ||
return enhancer(renderer); | ||
}, createRenderer.apply(undefined, arguments)); | ||
return function (config) { | ||
var renderer = createRenderer(config); | ||
for (var i = 0, len = enhancers.length; i < len; ++i) { | ||
renderer = enhancers[i](renderer); | ||
} | ||
return renderer; | ||
}; | ||
@@ -769,45 +598,20 @@ }; | ||
/* weak */ | ||
function createDOMInterface(renderer, node) { | ||
var isHydrating = false; | ||
var DOMInterface = { | ||
/** | ||
* updates DOM node styles performantly | ||
* | ||
* @param {Function} node - DOM node | ||
* @param {Object} change - object describing the changes | ||
* @param {Object} renderer - the renderer which triggered the change | ||
*/ | ||
updateNode: function updateNode() { | ||
var change = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
// setting the hydration flag to prevent DOM updates will immediately | ||
// get unset as soon as the rehydration process is done | ||
if (change.type === 'hydrate') { | ||
isHydrating = !change.done; | ||
} | ||
// only update DOM if the renderer is not hydrating at the moment | ||
if (!isHydrating) { | ||
// only use insertRule in production as browser devtools might have | ||
// weird behavior if used together with insertRule at runtime | ||
if (change.type === 'rule' && !change.media && false) { | ||
var sheet = node.sheet; | ||
// directly append new rules before media rules | ||
sheet.insertRule(change.selector + '{' + change.css + '}', sheet.cssRules.length); | ||
} else { | ||
node.textContent = renderer.renderToString(); | ||
} | ||
} | ||
return function (change) { | ||
// only use insertRule in production as browser devtools might have | ||
// weird behavior if used together with insertRule at runtime | ||
if (false && change.type === RULE_TYPE && !change.media) {} else { | ||
node.textContent = renderer.renderToString(); | ||
} | ||
}; | ||
} | ||
return DOMInterface; | ||
function isValidHTMLElement(mountNode) { | ||
return mountNode && mountNode.nodeType === 1; | ||
} | ||
function render(renderer, mountNode) { | ||
// check if the passed node is a valid element node which allows | ||
// setting the `textContent` property to update the node's content | ||
if (!mountNode || mountNode.nodeType !== 1) { | ||
// mountNode must be a valid HTML element to be able | ||
// to set mountNode.textContent later on | ||
if (!isValidHTMLElement(mountNode)) { | ||
throw new Error('You need to specify a valid element node (nodeType = 1) to render into.'); | ||
@@ -824,10 +628,9 @@ } | ||
var DOMInterface = createDOMInterface(renderer, mountNode); | ||
renderer.subscribe(DOMInterface.updateNode); | ||
var updateNode = createDOMInterface(renderer, mountNode); | ||
renderer.subscribe(updateNode); | ||
// render currently rendered styles to the DOM once | ||
// if it is not already in DOM | ||
var css = renderer.renderToString(); | ||
if (mountNode.textContent !== css) { | ||
// render currently rendered styles to the DOM once | ||
mountNode.textContent = css; | ||
@@ -837,2 +640,7 @@ } | ||
function deprecatedRender(renderer, mountNode) { | ||
console.warn('Importing `render` from `fela` is deprecated. Use `fela-dom` to import `render` instead.'); // eslint-disable-line | ||
return render(renderer, mountNode); | ||
} | ||
var index = { | ||
@@ -842,3 +650,3 @@ createRenderer: createRenderer, | ||
enhance: enhance, | ||
render: render | ||
render: deprecatedRender | ||
}; | ||
@@ -845,0 +653,0 @@ |
@@ -1,1 +0,1 @@ | ||
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):e.Fela=r()}(this,function(){"use strict";function e(e,r){return r={exports:{}},e(r,r.exports),r.exports}function r(e){var r=0,t=0,n=void 0,o=e.length;if(0===o)return"";for(;t<o;++t)n=e.charCodeAt(t),r=(r<<5)-r+n,r|=0;return"-"+r.toString(36)}function t(e){return Object.keys(h).reduce(function(r,t){return e.indexOf(t)>-1&&(r=h[t]),r},void 0)}function n(e,r,t){return t.reduce(function(e,t){return t(e,r)},e)}function o(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return Object.keys(e).reduce(function(t,n){var i=e[n];if(i instanceof Object&&!Array.isArray(i)){var a=o(i,r[n]);Object.keys(a).length>0&&(t[n]=a)}else if(void 0!==i&&r[n]!==i){if("string"==typeof i&&i.indexOf("undefined")>-1)return t;t[n]=i}return t},{})}function i(e){return Object.keys(e).reduce(function(r,t){return r.length>0&&(r+=";"),r+=v(t)+":"+e[t]},"")}function a(e,r){var t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[""],n=Object.keys(e).reduce(function(r,t){return r+t+"{"+i(e[t])+"}"},"");return t.reduce(function(e,t){return e+"@"+t+"keyframes "+r+"{"+n+"}"},"")}function u(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r={listeners:[],keyframePrefixes:e.keyframePrefixes||["-webkit-","-moz-"],plugins:e.plugins||[],prettySelectors:e.prettySelectors&&!1,mediaQueryOrder:e.mediaQueryOrder||[],clear:function(){r.fontFaces="",r.keyframes="",r.statics="",r.rules="",r.mediaRules=r.mediaQueryOrder.reduce(function(e,r){return e[r]="",e},{}),r.rendered={},r.base=[],r.ids=[],r.baseClassName={},r.callStack=[],r._emitChange({type:"clear"})},renderRule:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(r.ids.indexOf(e)===-1){r.ids.push(e);try{r.renderRule(e,i,i)}catch(e){}}var a=y.extends({},i,t),u=e(a),s=r._generateStyleId(u),c="c"+s;if(!r.rendered.hasOwnProperty(c)){var f=n(u,{type:"rule",className:c,props:a,rule:e},r.plugins),l=r.ids.indexOf(e),d=o(f,r.base[l]);if(r.rendered[c]=!1,Object.keys(d).length>0&&r._renderStyle(c,d),r.callStack.push(r.renderRule.bind(r,e,t,i)),t===i)return r.base[l]=d,r.baseClassName[l]=c,r.rendered[c]?c:"";r.baseClassName[s]=r.baseClassName[l]}var p=r.baseClassName[s];return r.rendered[c]?c!==p?(r.rendered[p]?p+" ":"")+c:c:r.rendered[p]?p:""},renderKeyframe:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=e(t),i=r._generateStyleId(o),u="k"+i;if(!r.rendered.hasOwnProperty(u)){var s=n(o,{type:"keyframe",keyframe:e,props:t,animationName:u},r.plugins),c=a(s,u,r.keyframePrefixes);r.rendered[u]=!0,r.keyframes+=c,r.callStack.push(r.renderKeyframe.bind(r,e,t)),r._emitChange({name:u,style:s,css:c,type:"keyframe"})}return u},renderFont:function(e,n){var o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},a=e+p(o);return r.rendered.hasOwnProperty(a)||!function(){var u={fontFamily:"'"+e+"'",src:n.map(function(e){return"url('"+e+"') format('"+t(e)+"')"}).join(",")},s=["fontVariant","fontWeight","fontStretch","fontStyle","unicodeRange"];Object.keys(o).filter(function(e){return s.indexOf(e)>-1}).forEach(function(e){return u[e]=o[e]});var c="@font-face{"+i(u)+"}";r.rendered[a]=!0,r.fontFaces+=c,r.callStack.push(r.renderFont.bind(r,e,n,o)),r._emitChange({fontFamily:e,fontFace:u,css:c,type:"font"})}(),e},renderStatic:function(e,t){var o="string"==typeof e?e:t+JSON.stringify(e);if(!r.rendered.hasOwnProperty(o)){if("string"==typeof e){var a=e.replace(/\s{2,}/g,"");r.statics+=a,r._emitChange({selector:t,type:"static",css:a})}else{var u=n(e,{selector:t,type:"static"},r.plugins),s=i(u);r.statics+=t+"{"+s+"}",r.callStack.push(r.renderStatic.bind(r,e,t)),r._emitChange({selector:t,style:u,css:s,type:"rule"})}r.rendered[o]=!0}},renderToString:function(){var e=r.fontFaces+r.statics+r.rules;for(var t in r.mediaRules){var n=r.mediaRules[t];n.length>0&&(e+="@media "+t+"{"+n+"}")}return e+r.keyframes},subscribe:function(e){return r.listeners.push(e),{unsubscribe:function(){return r.listeners.splice(r.listeners.indexOf(e),1)}}},rehydrate:function(){var e=r.callStack.slice(0);r.clear(),r._emitChange({type:"rehydrate",done:!1}),e.forEach(function(e){return e()}),r._emitChange({type:"rehydrate",done:!0})},_generateStyleId:function(e){var t=p(e);return r.ids.indexOf(t)===-1&&r.ids.push(t),r.ids.indexOf(t).toString(36)},_emitChange:function(e){r.listeners.forEach(function(t){return t(e,r)})},_renderStyle:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"",a=Object.keys(t).reduce(function(i,a){var u=t[a];if(u instanceof Object&&!Array.isArray(u)){if(null!==a.match(/^(:|\[|>)/))r._renderStyle(e,u,n+a,o);else if("@media"===a.substr(0,6)){var s=a.slice(6).trim(),c=o.length>0?o+" and "+s:s;r._renderStyle(e,u,n,c)}}else i[a]=u;return i},{});if(Object.keys(a).length>0){r.rendered[e]=!0;var u=i(a),s="."+e+n,c=s+"{"+u+"}";o.length>0?(r.mediaRules.hasOwnProperty(o)||(r.mediaRules[o]=""),r.mediaRules[o]+=c):r.rules+=c,r._emitChange({selector:s,style:a,css:u,media:o,type:"rule"})}}};return r.keyframePrefixes.push(""),r.clear(),e.enhancers&&e.enhancers.forEach(function(e){return r=e(r)}),r}function s(e){for(var r=arguments.length,t=Array(r>1?r-1:0),n=1;n<r;n++)t[n-1]=arguments[n];return t.reduce(function(e,r){for(var t in r){var n=r[t];e[t]instanceof Object&&n instanceof Object?e[t]=s({},e[t],n):e[t]=n}return e},e)}function c(){for(var e=arguments.length,r=Array(e),t=0;t<e;t++)r[t]=arguments[t];return function(e){return r.reduce(function(r,t){return s(r,t(e))},{})}}function f(){for(var e=arguments.length,r=Array(e),t=0;t<e;t++)r[t]=arguments[t];return function(e){return function(){return r.reduce(function(e,r){return r(e)},e.apply(void 0,arguments))}}}function l(e,r){var t=!1,n={updateNode:function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if("hydrate"===n.type&&(t=!n.done),!t)if("rule"!==n.type||n.media)r.textContent=e.renderToString();else{var o=r.sheet;o.insertRule(n.selector+"{"+n.css+"}",o.cssRules.length)}}};return n}function d(e,r){if(!r||1!==r.nodeType)throw new Error("You need to specify a valid element node (nodeType = 1) to render into.");r.setAttribute("data-fela-stylesheet","");var t=l(e,r);e.subscribe(t.updateNode);var n=e.renderToString();r.textContent!==n&&(r.textContent=n)}var y={};y.typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},y.classCallCheck=function(e,r){if(!(e instanceof r))throw new TypeError("Cannot call a class as a function")},y.createClass=function(){function e(e,r){for(var t=0;t<r.length;t++){var n=r[t];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(r,t,n){return t&&e(r.prototype,t),n&&e(r,n),r}}(),y.extends=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e},y.inherits=function(e,r){if("function"!=typeof r&&null!==r)throw new TypeError("Super expression must either be null or a function, not "+typeof r);e.prototype=Object.create(r&&r.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),r&&(Object.setPrototypeOf?Object.setPrototypeOf(e,r):e.__proto__=r)},y.objectWithoutProperties=function(e,r){var t={};for(var n in e)r.indexOf(n)>=0||Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t},y.possibleConstructorReturn=function(e,r){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!r||"object"!=typeof r&&"function"!=typeof r?e:r},y.toConsumableArray=function(e){if(Array.isArray(e)){for(var r=0,t=Array(e.length);r<e.length;r++)t[r]=e[r];return t}return Array.from(e)};var p=function(e){return r(JSON.stringify(e))},h={".woff":"woff",".eot":"eot",".ttf":"truetype",".svg":"svg"},m=e(function(e){function r(e){return e in o?o[e]:o[e]=e.replace(t,"-$&").toLowerCase().replace(n,"-ms-")}var t=/[A-Z]/g,n=/^ms-/,o={};e.exports=r}),v=m&&"object"==typeof m&&"default"in m?m.default:m,b={createRenderer:u,combineRules:c,enhance:f,render:d};return b}); | ||
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):e.Fela=r()}(this,function(){"use strict";function e(e,r){return r={exports:{}},e(r,r.exports),r.exports}function r(e,r){return T(e)+":"+r}function n(e){var n="";for(var t in e)n&&(n+=";"),n+=r(t,e[t]);return n}function t(e){return"@font-face{"+n(e)+"}"}function o(e,r){var t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[""],o=Object.keys(e).reduce(function(r,t){return r+t+"{"+n(e[t])+"}"},"");return t.reduce(function(e,n){return e+"@"+n+"keyframes "+r+"{"+o+"}"},"")}function i(e,r){return"@media "+e+"{"+r+"}"}function a(e){return"k"+e}function u(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return e<=52?F[e-1]+r:u(e/52|0,F[e%52]+r)}function f(e,r){return 0===e.length?r:e+" and "+r}function c(e,r){return e+"{"+r+"}"}function s(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return"."+e+r}function l(e){return e.replace(/\s{2,}/g,"")}function y(e,r,n){for(var t=0;t<r.length;++t)e=r[t](e,n);return e}function d(e,r){if("string"==typeof e)return l(e);var t=y(e,r,E);return n(t)}function p(e,r){return"string"==typeof e?e:r+JSON.stringify(e)}function h(e){return"["===e.charAt(0)}function m(e){return":"===e.charAt(0)}function v(e){return"@media"===e.substr(0,6)}function g(e){for(var r={},n=0,t=e.length;n<t;++n)r[e[n]]="";return r}function b(e){return'"'===e.charAt(0)?e:'"'+e+'"'}function O(e){for(var r=0,n=Q.length;r<n;++r){var t=Q[r];if(e.indexOf(t)!==-1)return K[t]}}function C(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n={listeners:[],keyframePrefixes:e.keyframePrefixes||["-webkit-","-moz-"],plugins:e.plugins||[],mediaQueryOrder:e.mediaQueryOrder||[],clear:function(){n.fontFaces="",n.keyframes="",n.statics="",n.rules="",n.mediaRules=g(n.mediaQueryOrder),n.rendered=[],n.uniqueRuleIdentifier=0,n.uniqueKeyframeIdentifier=0,n.cache={},n._emitChange({type:J})},renderRule:function(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},t=y(e(r),n.plugins,N);return n._renderStyleToClassNames(t).slice(1)},_renderStyleToClassNames:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",i="";for(var a in e){var l=e[a];if(l instanceof Object){if(m(a)||h(a))i+=n._renderStyleToClassNames(l,t+a,o);else if(v(a)){var y=f(o,a.slice(6).trim());i+=n._renderStyleToClassNames(l,t,y)}}else{var d=o+t+a+l;if(!n.cache[d]){var p=u(++n.uniqueRuleIdentifier);n.cache[d]=p;var g=r(a,l),b=s(p,t),O=c(b,g);o?(n.mediaRules.hasOwnProperty(o)||(n.mediaRules[o]=""),n.mediaRules[o]+=O):n.rules+=O,n._emitChange({selector:b,declaration:g,media:o,type:N})}i+=" "+n.cache[d]}}return i},renderKeyframe:function(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},t=e(r),i=JSON.stringify(t);if(!n.cache[i]){var u=a(++n.uniqueKeyframeIdentifier),f=y(t,n.plugins,I),c=o(f,u,n.keyframePrefixes);n.cache[i]=u,n.keyframes+=c,n._emitChange({name:u,keyframe:c,type:I})}return n.cache[i]},renderFont:function(e,r){var o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},i=e+JSON.stringify(o);if(!n.cache[i]){var a=b(e),u=A.extends({},o,{src:r.map(function(e){return"url('"+e+"') format('"+O(e)+"')"}).join(","),fontFamily:a}),f=t(u);n.cache[i]=a,n.fontFaces+=f,n._emitChange({fontFamily:a,fontFace:f,type:q})}return n.cache[i]},renderStatic:function(e,r){var t=p(e,r);if(!n.cache[t]){var o=d(e,n.plugins);n.cache[t]=!0,"string"==typeof e?(n.statics+=o,n._emitChange({type:E,css:o})):(n.statics+=c(r,o),n._emitChange({selector:r,declaration:o,type:N,media:""}))}},renderToString:function(){var e=n.fontFaces+n.statics+n.keyframes+n.rules;for(var r in n.mediaRules)e+=i(r,n.mediaRules[r]);return e},subscribe:function(e){return n.listeners.push(e),{unsubscribe:function(){return n.listeners.splice(n.listeners.indexOf(e),1)}}},_emitChange:function(e){for(var r=0,t=n.listeners.length;r<t;++r)n.listeners[r](e)}};if(n.keyframePrefixes.push(""),n.clear(),e.enhancers)for(var l=0,C=e.enhancers.length;l<C;++l)n=e.enhancers[l](n);return n}function w(e){for(var r=arguments.length,n=Array(r>1?r-1:0),t=1;t<r;t++)n[t-1]=arguments[t];for(var o=0,i=n.length;o<i;++o){var a=n[o];for(var u in a){var f=a[u];e[u]instanceof Object&&f instanceof Object?e[u]=w({},e[u],f):e[u]=f}}return e}function x(){for(var e=arguments.length,r=Array(e),n=0;n<e;n++)r[n]=arguments[n];return function(e){for(var n={},t=0,o=r.length;t<o;++t)w(n,r[t](e));return n}}function j(){for(var e=arguments.length,r=Array(e),n=0;n<e;n++)r[n]=arguments[n];return function(e){return function(n){for(var t=e(n),o=0,i=r.length;o<i;++o)t=r[o](t);return t}}}function S(e,r){return function(n){n.type!==N||n.media?r.textContent=e.renderToString():r.sheet.insertRule(n.selector+"{"+n.declaration+"}",r.sheet.cssRules.length)}}function k(e){return e&&1===e.nodeType}function R(e,r){if(!k(r))throw new Error("You need to specify a valid element node (nodeType = 1) to render into.");r.setAttribute("data-fela-stylesheet","");var n=S(e,r);e.subscribe(n);var t=e.renderToString();r.textContent!==t&&(r.textContent=t)}function _(e,r){return console.warn("Importing `render` from `fela` is deprecated. Use `fela-dom` to import `render` instead."),R(e,r)}var A={};A.typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},A.classCallCheck=function(e,r){if(!(e instanceof r))throw new TypeError("Cannot call a class as a function")},A.createClass=function(){function e(e,r){for(var n=0;n<r.length;n++){var t=r[n];t.enumerable=t.enumerable||!1,t.configurable=!0,"value"in t&&(t.writable=!0),Object.defineProperty(e,t.key,t)}}return function(r,n,t){return n&&e(r.prototype,n),t&&e(r,t),r}}(),A.defineProperty=function(e,r,n){return r in e?Object.defineProperty(e,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[r]=n,e},A.extends=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var n=arguments[r];for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(e[t]=n[t])}return e},A.inherits=function(e,r){if("function"!=typeof r&&null!==r)throw new TypeError("Super expression must either be null or a function, not "+typeof r);e.prototype=Object.create(r&&r.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),r&&(Object.setPrototypeOf?Object.setPrototypeOf(e,r):e.__proto__=r)},A.objectWithoutProperties=function(e,r){var n={};for(var t in e)r.indexOf(t)>=0||Object.prototype.hasOwnProperty.call(e,t)&&(n[t]=e[t]);return n},A.possibleConstructorReturn=function(e,r){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!r||"object"!=typeof r&&"function"!=typeof r?e:r},A.toConsumableArray=function(e){if(Array.isArray(e)){for(var r=0,n=Array(e.length);r<e.length;r++)n[r]=e[r];return n}return Array.from(e)};var P=e(function(e){function r(e){return e in o?o[e]:o[e]=e.replace(n,"-$&").toLowerCase().replace(t,"-ms-")}var n=/[A-Z]/g,t=/^ms-/,o={};e.exports=r}),T=P&&"object"==typeof P&&"default"in P?P.default:P,F="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",N=1,I=2,q=3,E=4,J=5,K={".woff":"woff",".eot":"eot",".ttf":"truetype",".svg":"svg"},Q=Object.keys(K),z={createRenderer:C,combineRules:x,enhance:j,render:_};return z}); |
@@ -14,2 +14,1 @@ export interface Renderer { | ||
export declare function enhance(...enhancers:any[]): Function; | ||
export declare function render(renderer:Renderer, mountNode:HTMLElement): void; |
@@ -48,9 +48,3 @@ 'use strict'; | ||
// invoke the component name for better CSS debugging | ||
if (process.env.NODE_ENV !== 'production') { | ||
this.context.renderer._selectorPrefix = Comp.displayName || Comp.name || 'ConnectedFelaComponent'; | ||
} | ||
// invoke props and renderer to render all styles | ||
var styles = mapStylesToProps(_extends({}, this.props, { | ||
@@ -60,7 +54,2 @@ theme: theme || {} | ||
// remove the component name after rendering | ||
if (process.env.NODE_ENV !== 'production') { | ||
this.context.renderer._selectorPrefix = undefined; | ||
} | ||
return _react2.default.createElement(Comp, _extends({}, this.props, { styles: styles })); | ||
@@ -67,0 +56,0 @@ } |
@@ -18,3 +18,2 @@ 'use strict'; | ||
var passThroughProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; | ||
var defaultProps = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; | ||
@@ -41,6 +40,5 @@ var FelaComponent = function FelaComponent(_ref, _ref2) { | ||
var cls = className ? className + ' ' : ''; | ||
defaultProps.theme = theme || {}; | ||
ruleProps.theme = theme || {}; | ||
componentProps.className = cls + renderer.renderRule(rule, ruleProps, defaultProps); | ||
componentProps.className = cls + renderer.renderRule(rule, ruleProps); | ||
return (0, _react.createElement)(type, componentProps, children); | ||
@@ -47,0 +45,0 @@ }; |
@@ -11,3 +11,3 @@ 'use strict'; | ||
var _render = require('../../render'); | ||
var _render = require('../../dom/render'); | ||
@@ -14,0 +14,0 @@ var _render2 = _interopRequireDefault(_render); |
@@ -32,4 +32,10 @@ 'use strict'; | ||
value: function getChildContext() { | ||
var _props = this.props, | ||
overwrite = _props.overwrite, | ||
theme = _props.theme; | ||
var previousTheme = this.context.theme; | ||
return { | ||
theme: _extends({}, !this.props.overwrite && this.context.theme || {}, this.props.theme) | ||
theme: _extends({}, !overwrite && previousTheme || {}, theme) | ||
}; | ||
@@ -36,0 +42,0 @@ } |
@@ -19,8 +19,12 @@ 'use strict'; | ||
return function combined(props) { | ||
return rules.reduce(function (style, rule) { | ||
return (0, _assign2.default)(style, rule(props)); | ||
}, {}); | ||
return function (props) { | ||
var style = {}; | ||
for (var i = 0, len = rules.length; i < len; ++i) { | ||
(0, _assign2.default)(style, rules[i](props)); | ||
} | ||
return style; | ||
}; | ||
} /* weak */ | ||
module.exports = exports['default']; |
@@ -12,42 +12,81 @@ 'use strict'; | ||
var _generateStyleHash = require('./utils/generateStyleHash'); | ||
var _cssifyFontFace = require('./utils/cssifyFontFace'); | ||
var _generateStyleHash2 = _interopRequireDefault(_generateStyleHash); | ||
var _cssifyFontFace2 = _interopRequireDefault(_cssifyFontFace); | ||
var _getFontFormat = require('./utils/getFontFormat'); | ||
var _cssifyKeyframe = require('./utils/cssifyKeyframe'); | ||
var _getFontFormat2 = _interopRequireDefault(_getFontFormat); | ||
var _cssifyKeyframe2 = _interopRequireDefault(_cssifyKeyframe); | ||
var _processStyle = require('./utils/processStyle'); | ||
var _cssifyMediaQueryRules = require('./utils/cssifyMediaQueryRules'); | ||
var _processStyle2 = _interopRequireDefault(_processStyle); | ||
var _cssifyMediaQueryRules2 = _interopRequireDefault(_cssifyMediaQueryRules); | ||
var _diffStyle = require('./utils/diffStyle'); | ||
var _generateAnimationName = require('./utils/generateAnimationName'); | ||
var _diffStyle2 = _interopRequireDefault(_diffStyle); | ||
var _generateAnimationName2 = _interopRequireDefault(_generateAnimationName); | ||
var _cssifyKeyframe = require('./utils/cssifyKeyframe'); | ||
var _generateClassName = require('./utils/generateClassName'); | ||
var _cssifyKeyframe2 = _interopRequireDefault(_cssifyKeyframe); | ||
var _generateClassName2 = _interopRequireDefault(_generateClassName); | ||
var _cssifyObject = require('./utils/cssifyObject'); | ||
var _generateCombinedMediaQuery = require('./utils/generateCombinedMediaQuery'); | ||
var _cssifyObject2 = _interopRequireDefault(_cssifyObject); | ||
var _generateCombinedMediaQuery2 = _interopRequireDefault(_generateCombinedMediaQuery); | ||
var _warning = require('./utils/warning'); | ||
var _generateCSSDeclaration = require('./utils/generateCSSDeclaration'); | ||
var _warning2 = _interopRequireDefault(_warning); | ||
var _generateCSSDeclaration2 = _interopRequireDefault(_generateCSSDeclaration); | ||
var _generateCSSRule = require('./utils/generateCSSRule'); | ||
var _generateCSSRule2 = _interopRequireDefault(_generateCSSRule); | ||
var _generateCSSSelector = require('./utils/generateCSSSelector'); | ||
var _generateCSSSelector2 = _interopRequireDefault(_generateCSSSelector); | ||
var _cssifyStaticStyle = require('./utils/cssifyStaticStyle'); | ||
var _cssifyStaticStyle2 = _interopRequireDefault(_cssifyStaticStyle); | ||
var _generateStaticReference = require('./utils/generateStaticReference'); | ||
var _generateStaticReference2 = _interopRequireDefault(_generateStaticReference); | ||
var _isAttributeSelector = require('./utils/isAttributeSelector'); | ||
var _isAttributeSelector2 = _interopRequireDefault(_isAttributeSelector); | ||
var _isPseudoSelector = require('./utils/isPseudoSelector'); | ||
var _isPseudoSelector2 = _interopRequireDefault(_isPseudoSelector); | ||
var _isMediaQuery = require('./utils/isMediaQuery'); | ||
var _isMediaQuery2 = _interopRequireDefault(_isMediaQuery); | ||
var _applyMediaRulesInOrder = require('./utils/applyMediaRulesInOrder'); | ||
var _applyMediaRulesInOrder2 = _interopRequireDefault(_applyMediaRulesInOrder); | ||
var _processStyleWithPlugins = require('./utils/processStyleWithPlugins'); | ||
var _processStyleWithPlugins2 = _interopRequireDefault(_processStyleWithPlugins); | ||
var _toCSSString = require('./utils/toCSSString'); | ||
var _toCSSString2 = _interopRequireDefault(_toCSSString); | ||
var _checkFontFormat = require('./utils/checkFontFormat'); | ||
var _checkFontFormat2 = _interopRequireDefault(_checkFontFormat); | ||
var _styleTypes = require('./utils/styleTypes'); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
/** | ||
* creates a new renderer instance | ||
* | ||
* @param {Object} config - renderer configuration | ||
* @return {Object} new renderer instance | ||
*/ | ||
function createRenderer() { | ||
var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
// the renderer is the key | ||
var renderer = { | ||
@@ -58,10 +97,6 @@ listeners: [], | ||
// try and use readable selectors when | ||
// prettySelectors is on and not in a prod environment | ||
prettySelectors: config.prettySelectors && process.env.NODE_ENV !== 'production', | ||
// prettySelectors is currently useless, might reimplement better DX classNames later | ||
// prettySelectors: config.prettySelectors && process.env.NODE_ENV !== 'production', | ||
mediaQueryOrder: config.mediaQueryOrder || [], | ||
/** | ||
* clears the sheet's cache but keeps all listeners | ||
*/ | ||
clear: function clear() { | ||
@@ -72,272 +107,158 @@ renderer.fontFaces = ''; | ||
renderer.rules = ''; | ||
renderer.mediaRules = renderer.mediaQueryOrder.reduce(function (rules, media) { | ||
rules[media] = ''; | ||
return rules; | ||
}, {}); | ||
// apply media rules in an explicit order to ensure | ||
// correct media query execution order | ||
renderer.mediaRules = (0, _applyMediaRulesInOrder2.default)(renderer.mediaQueryOrder); | ||
renderer.rendered = []; | ||
renderer.uniqueRuleIdentifier = 0; | ||
renderer.uniqueKeyframeIdentifier = 0; | ||
// use a flat cache object with pure string references | ||
// to achieve maximal lookup performance and memoization speed | ||
renderer.cache = {}; | ||
renderer.rendered = {}; | ||
renderer.base = []; | ||
renderer.ids = []; | ||
renderer.baseClassName = {}; | ||
renderer.callStack = []; | ||
// emit changes to notify subscribers | ||
renderer._emitChange({ type: 'clear' }); | ||
// initial change emit to enforce a clear start | ||
renderer._emitChange({ type: _styleTypes.CLEAR_TYPE }); | ||
}, | ||
/** | ||
* renders a new rule variation and caches the result | ||
* | ||
* @param {Function} rule - rule which gets rendered | ||
* @param {Object?} props - properties used to render | ||
* @param {Object?} defaultProps - properties used to render the static style | ||
* @return {string} className to reference the rendered rule | ||
*/ | ||
renderRule: function renderRule(rule) { | ||
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var defaultProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
// rendering a rule for the first time | ||
// will create an ID reference | ||
if (renderer.ids.indexOf(rule) === -1) { | ||
renderer.ids.push(rule); | ||
var processedStyle = (0, _processStyleWithPlugins2.default)(rule(props), renderer.plugins, _styleTypes.RULE_TYPE); | ||
return renderer._renderStyleToClassNames(processedStyle).slice(1); | ||
}, | ||
_renderStyleToClassNames: function _renderStyleToClassNames(style) { | ||
var pseudo = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; | ||
var media = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; | ||
// directly render the static base style to be able | ||
// to diff future dynamic style with those | ||
try { | ||
renderer.renderRule(rule, defaultProps, defaultProps); | ||
} catch (error) { | ||
process.env.NODE_ENV !== "production" ? (0, _warning2.default)(false, 'Nested props have been used without passing \'defaultProps\'. This will disable static style splitting for \'' + (rule.name ? rule.name : 'unkown_rule') + '\'.') : void 0; | ||
} | ||
} | ||
var classNames = ''; | ||
var ruleProps = _extends({}, defaultProps, props); | ||
for (var property in style) { | ||
var value = style[property]; | ||
if (value instanceof Object) { | ||
if ((0, _isPseudoSelector2.default)(property) || (0, _isAttributeSelector2.default)(property)) { | ||
classNames += renderer._renderStyleToClassNames(value, pseudo + property, media); | ||
} else if ((0, _isMediaQuery2.default)(property)) { | ||
var combinedMediaQuery = (0, _generateCombinedMediaQuery2.default)(media, property.slice(6).trim()); | ||
classNames += renderer._renderStyleToClassNames(value, pseudo, combinedMediaQuery); | ||
} else { | ||
// TODO: warning | ||
} | ||
} else { | ||
var delcarationReference = media + pseudo + property + value; | ||
if (!renderer.cache[delcarationReference]) { | ||
var className = (0, _generateClassName2.default)(++renderer.uniqueRuleIdentifier); | ||
var style = rule(ruleProps); | ||
var styleId = renderer._generateStyleId(style); | ||
renderer.cache[delcarationReference] = className; | ||
var className = 'c' + styleId; | ||
var cssDeclaration = (0, _generateCSSDeclaration2.default)(property, value); | ||
var selector = (0, _generateCSSSelector2.default)(className, pseudo); | ||
var cssRule = (0, _generateCSSRule2.default)(selector, cssDeclaration); | ||
// extend the className with prefixes in development | ||
// this enables better debugging and className readability | ||
if (process.env.NODE_ENV !== 'production') { | ||
className = (renderer._selectorPrefix ? renderer._selectorPrefix + '__' : '') + (renderer.prettySelectors && rule.name ? rule.name + '__' : '') + className; | ||
} | ||
if (media) { | ||
if (!renderer.mediaRules.hasOwnProperty(media)) { | ||
renderer.mediaRules[media] = ''; | ||
} | ||
renderer.mediaRules[media] += cssRule; | ||
} else { | ||
renderer.rules += cssRule; | ||
} | ||
// only if the rule has not already been rendered | ||
// with a specific set of properties it actually renders | ||
if (!renderer.rendered.hasOwnProperty(className)) { | ||
// process style using each plugin | ||
var processedStyle = (0, _processStyle2.default)(style, { | ||
type: 'rule', | ||
className: className, | ||
props: ruleProps, | ||
rule: rule | ||
}, renderer.plugins); | ||
renderer._emitChange({ | ||
selector: selector, | ||
declaration: cssDeclaration, | ||
media: media, | ||
type: _styleTypes.RULE_TYPE | ||
}); | ||
} | ||
var ruleId = renderer.ids.indexOf(rule); | ||
// diff style objects with base styles | ||
var diffedStyle = (0, _diffStyle2.default)(processedStyle, renderer.base[ruleId]); | ||
renderer.rendered[className] = false; | ||
if (Object.keys(diffedStyle).length > 0) { | ||
renderer._renderStyle(className, diffedStyle); | ||
classNames += ' ' + renderer.cache[delcarationReference]; | ||
} | ||
renderer.callStack.push(renderer.renderRule.bind(renderer, rule, props, defaultProps)); | ||
// keep static style to diff dynamic onces later on | ||
if (props === defaultProps) { | ||
renderer.base[ruleId] = diffedStyle; | ||
renderer.baseClassName[ruleId] = className; | ||
return renderer.rendered[className] ? className : ''; | ||
} else { | ||
renderer.baseClassName[styleId] = renderer.baseClassName[ruleId]; | ||
} | ||
} | ||
var baseClassName = renderer.baseClassName[styleId]; | ||
// if current className is empty | ||
// return either the static class or empty string | ||
if (!renderer.rendered[className]) { | ||
return renderer.rendered[baseClassName] ? baseClassName : ''; | ||
} | ||
// if the current className is a dynamic rule | ||
// return both classNames if static subset is not empty | ||
if (className !== baseClassName) { | ||
return (renderer.rendered[baseClassName] ? baseClassName + ' ' : '') + className; | ||
} | ||
return className; | ||
return classNames; | ||
}, | ||
/** | ||
* renders a new keyframe variation and caches the result | ||
* | ||
* @param {Keyframe} keyframe - Keyframe which gets rendered | ||
* @param {Object?} props - properties used to render | ||
* @return {string} animationName to reference the rendered keyframe | ||
*/ | ||
renderKeyframe: function renderKeyframe(keyframe) { | ||
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var style = keyframe(props); | ||
var styleId = renderer._generateStyleId(style); | ||
var resolvedKeyframe = keyframe(props); | ||
var keyframeReference = JSON.stringify(resolvedKeyframe); | ||
var animationName = 'k' + styleId; | ||
if (!renderer.cache[keyframeReference]) { | ||
// use another unique identifier to ensure minimal css markup | ||
var animationName = (0, _generateAnimationName2.default)(++renderer.uniqueKeyframeIdentifier); | ||
// extend the animationName with prefixes in development | ||
// this enables better debugging and className readability | ||
if (process.env.NODE_ENV !== 'production') { | ||
animationName = (renderer.prettySelectors && keyframe.name ? keyframe.name + '__' : '') + animationName; | ||
} | ||
var processedKeyframe = (0, _processStyleWithPlugins2.default)(resolvedKeyframe, renderer.plugins, _styleTypes.KEYFRAME_TYPE); | ||
var cssKeyframe = (0, _cssifyKeyframe2.default)(processedKeyframe, animationName, renderer.keyframePrefixes); | ||
renderer.cache[keyframeReference] = animationName; | ||
renderer.keyframes += cssKeyframe; | ||
// only if the keyframe has not already been rendered | ||
// with a specific set of properties it actually renders | ||
if (!renderer.rendered.hasOwnProperty(animationName)) { | ||
var processedKeyframe = (0, _processStyle2.default)(style, { | ||
type: 'keyframe', | ||
keyframe: keyframe, | ||
props: props, | ||
animationName: animationName | ||
}, renderer.plugins); | ||
var css = (0, _cssifyKeyframe2.default)(processedKeyframe, animationName, renderer.keyframePrefixes); | ||
renderer.rendered[animationName] = true; | ||
renderer.keyframes += css; | ||
renderer.callStack.push(renderer.renderKeyframe.bind(renderer, keyframe, props)); | ||
renderer._emitChange({ | ||
name: animationName, | ||
style: processedKeyframe, | ||
css: css, | ||
type: 'keyframe' | ||
keyframe: cssKeyframe, | ||
type: _styleTypes.KEYFRAME_TYPE | ||
}); | ||
} | ||
return animationName; | ||
return renderer.cache[keyframeReference]; | ||
}, | ||
/** | ||
* renders a new font-face and caches it | ||
* | ||
* @param {FontFace} fontFace - fontFace which gets rendered | ||
* @return {string} fontFamily reference | ||
*/ | ||
renderFont: function renderFont(family, files) { | ||
var properties = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
var key = family + (0, _generateStyleHash2.default)(properties); | ||
var fontReference = family + JSON.stringify(properties); | ||
if (!renderer.rendered.hasOwnProperty(key)) { | ||
(function () { | ||
var fontFace = { | ||
fontFamily: '\'' + family + '\'', | ||
src: files.map(function (src) { | ||
return 'url(\'' + src + '\') format(\'' + (0, _getFontFormat2.default)(src) + '\')'; | ||
}).join(',') | ||
}; | ||
if (!renderer.cache[fontReference]) { | ||
var fontFamily = (0, _toCSSString2.default)(family); | ||
var fontProperties = ['fontVariant', 'fontWeight', 'fontStretch', 'fontStyle', 'unicodeRange']; | ||
Object.keys(properties).filter(function (prop) { | ||
return fontProperties.indexOf(prop) > -1; | ||
}).forEach(function (fontProp) { | ||
return fontFace[fontProp] = properties[fontProp]; | ||
}); | ||
// TODO: proper font family generation with error proofing | ||
var fontFace = _extends({}, properties, { | ||
src: files.map(function (src) { | ||
return 'url(\'' + src + '\') format(\'' + (0, _checkFontFormat2.default)(src) + '\')'; | ||
}).join(','), | ||
fontFamily: fontFamily | ||
}); | ||
var css = '@font-face{' + (0, _cssifyObject2.default)(fontFace) + '}'; | ||
var cssFontFace = (0, _cssifyFontFace2.default)(fontFace); | ||
renderer.cache[fontReference] = fontFamily; | ||
renderer.fontFaces += cssFontFace; | ||
renderer.rendered[key] = true; | ||
renderer.fontFaces += css; | ||
renderer.callStack.push(renderer.renderFont.bind(renderer, family, files, properties)); | ||
renderer._emitChange({ | ||
fontFamily: family, | ||
fontFace: fontFace, | ||
css: css, | ||
type: 'font' | ||
}); | ||
})(); | ||
renderer._emitChange({ | ||
fontFamily: fontFamily, | ||
fontFace: cssFontFace, | ||
type: _styleTypes.FONT_TYPE | ||
}); | ||
} | ||
return family; | ||
return renderer.cache[fontReference]; | ||
}, | ||
renderStatic: function renderStatic(staticStyle, selector) { | ||
var staticReference = (0, _generateStaticReference2.default)(staticStyle, selector); | ||
if (!renderer.cache[staticReference]) { | ||
var cssDeclarations = (0, _cssifyStaticStyle2.default)(staticStyle, renderer.plugins); | ||
renderer.cache[staticReference] = true; | ||
/** | ||
* renders static style and caches them | ||
* | ||
* @param {string|Object} style - static style to be rendered | ||
* @param {string?} selector - selector used to render the styles | ||
* @return {string} rendered CSS output | ||
*/ | ||
renderStatic: function renderStatic(style, selector) { | ||
var reference = typeof style === 'string' ? style : selector + JSON.stringify(style); | ||
if (!renderer.rendered.hasOwnProperty(reference)) { | ||
if (typeof style === 'string') { | ||
var css = style.replace(/\s{2,}/g, ''); | ||
// remove new lines from template strings | ||
renderer.statics += css; | ||
if (typeof staticStyle === 'string') { | ||
renderer.statics += cssDeclarations; | ||
renderer._emitChange({ | ||
selector: selector, | ||
type: 'static', | ||
css: css | ||
type: _styleTypes.STATIC_TYPE, | ||
css: cssDeclarations | ||
}); | ||
} else { | ||
var processedStyle = (0, _processStyle2.default)(style, { | ||
selector: selector, | ||
type: 'static' | ||
}, renderer.plugins); | ||
var _css = (0, _cssifyObject2.default)(processedStyle); | ||
renderer.statics += selector + '{' + _css + '}'; | ||
renderer.callStack.push(renderer.renderStatic.bind(renderer, style, selector)); | ||
renderer.statics += (0, _generateCSSRule2.default)(selector, cssDeclarations); | ||
renderer._emitChange({ | ||
selector: selector, | ||
style: processedStyle, | ||
css: _css, | ||
type: 'rule' | ||
declaration: cssDeclarations, | ||
type: _styleTypes.RULE_TYPE, | ||
media: '' | ||
}); | ||
} | ||
renderer.rendered[reference] = true; | ||
} | ||
}, | ||
/** | ||
* renders all cached styles into a single valid CSS string | ||
* clusters media query styles into groups to reduce output size | ||
* @return single concatenated CSS string | ||
*/ | ||
renderToString: function renderToString() { | ||
var css = renderer.fontFaces + renderer.statics + renderer.rules; | ||
var css = renderer.fontFaces + renderer.statics + renderer.keyframes + renderer.rules; | ||
for (var media in renderer.mediaRules) { | ||
var rules = renderer.mediaRules[media]; | ||
if (rules.length > 0) { | ||
css += '@media ' + media + '{' + rules + '}'; | ||
} | ||
css += (0, _cssifyMediaQueryRules2.default)(media, renderer.mediaRules[media]); | ||
} | ||
return css + renderer.keyframes; | ||
return css; | ||
}, | ||
/** | ||
* Adds a new subscription to get notified on every rerender | ||
* | ||
* @param {Function} callback - callback function which will be executed | ||
* @return {Object} equivalent unsubscribe method | ||
*/ | ||
subscribe: function subscribe(callback) { | ||
@@ -351,107 +272,5 @@ renderer.listeners.push(callback); | ||
}, | ||
/** | ||
* rehydrates the whole cache using the callStack | ||
*/ | ||
rehydrate: function rehydrate() { | ||
var callStack = renderer.callStack.slice(0); | ||
// clears the current callStack | ||
renderer.clear(); | ||
renderer._emitChange({ type: 'rehydrate', done: false }); | ||
callStack.forEach(function (fn) { | ||
return fn(); | ||
}); | ||
renderer._emitChange({ type: 'rehydrate', done: true }); | ||
}, | ||
/** | ||
* generates a unique style id | ||
* | ||
* @param {Object} style - style object | ||
* @return {string} minimal string id | ||
*/ | ||
_generateStyleId: function _generateStyleId(style) { | ||
var styleHash = (0, _generateStyleHash2.default)(style); | ||
if (renderer.ids.indexOf(styleHash) === -1) { | ||
renderer.ids.push(styleHash); | ||
} | ||
return renderer.ids.indexOf(styleHash).toString(36); | ||
}, | ||
/** | ||
* calls each listener with a change object | ||
* gets only called if something actually changes | ||
* | ||
* @param {Function} callback - callback function which will be executed | ||
* @return {Object} equivalent unsubscribe method | ||
*/ | ||
_emitChange: function _emitChange(change) { | ||
renderer.listeners.forEach(function (listener) { | ||
return listener(change, renderer); | ||
}); | ||
}, | ||
/** | ||
* iterates a style object and renders each rule to the cache | ||
* | ||
* @param {string} className - className reference to be rendered to | ||
* @param {Object} style - style object which is rendered | ||
*/ | ||
_renderStyle: function _renderStyle(className, style) { | ||
var pseudo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; | ||
var media = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ''; | ||
var ruleset = Object.keys(style).reduce(function (ruleset, property) { | ||
var value = style[property]; | ||
// recursive object iteration in order to render | ||
// pseudo class and media class declarations | ||
if (value instanceof Object && !Array.isArray(value)) { | ||
// allow pseudo classes, attribute selectors and the child selector | ||
if (property.match(/^(:|\[|>)/) !== null) { | ||
renderer._renderStyle(className, value, pseudo + property, media); | ||
} else if (property.substr(0, 6) === '@media') { | ||
// combine media query rules with an `and` | ||
var query = property.slice(6).trim(); | ||
var combinedMedia = media.length > 0 ? media + ' and ' + query : query; | ||
renderer._renderStyle(className, value, pseudo, combinedMedia); | ||
} | ||
} else { | ||
ruleset[property] = value; | ||
} | ||
return ruleset; | ||
}, {}); | ||
// add styles to the cache | ||
if (Object.keys(ruleset).length > 0) { | ||
renderer.rendered[className] = true; | ||
var css = (0, _cssifyObject2.default)(ruleset); | ||
var selector = '.' + className + pseudo; | ||
var cssRule = selector + '{' + css + '}'; | ||
if (media.length > 0) { | ||
if (!renderer.mediaRules.hasOwnProperty(media)) { | ||
renderer.mediaRules[media] = ''; | ||
} | ||
renderer.mediaRules[media] += cssRule; | ||
} else { | ||
renderer.rules += cssRule; | ||
} | ||
renderer._emitChange({ | ||
selector: selector, | ||
style: ruleset, | ||
css: css, | ||
media: media, | ||
type: 'rule' | ||
}); | ||
for (var i = 0, len = renderer.listeners.length; i < len; ++i) { | ||
renderer.listeners[i](change); | ||
} | ||
@@ -465,7 +284,6 @@ } | ||
// enhance renderer with passed set of enhancers | ||
if (config.enhancers) { | ||
config.enhancers.forEach(function (enhancer) { | ||
return renderer = enhancer(renderer); | ||
}); | ||
for (var i = 0, len = config.enhancers.length; i < len; ++i) { | ||
renderer = config.enhancers[i](renderer); | ||
} | ||
} | ||
@@ -472,0 +290,0 @@ |
@@ -14,6 +14,10 @@ "use strict"; | ||
return function (createRenderer) { | ||
return function () { | ||
return enhancers.reduce(function (renderer, enhancer) { | ||
return enhancer(renderer); | ||
}, createRenderer.apply(undefined, arguments)); | ||
return function (config) { | ||
var renderer = createRenderer(config); | ||
for (var i = 0, len = enhancers.length; i < len; ++i) { | ||
renderer = enhancers[i](renderer); | ||
} | ||
return renderer; | ||
}; | ||
@@ -20,0 +24,0 @@ }; |
@@ -16,9 +16,2 @@ 'use strict'; | ||
/** | ||
* beautifies CSS output of renderToString | ||
* | ||
* @param {Object} renderer - renderer which gets enhanced | ||
* @param {Object} options - beautifier options | ||
* @return {Object} enhanced renderer | ||
*/ | ||
function addBeautifier(renderer, options) { | ||
@@ -25,0 +18,0 @@ var existingRenderToString = renderer.renderToString.bind(renderer); |
@@ -7,18 +7,19 @@ 'use strict'; | ||
var _fela = require('fela'); | ||
var _createRenderer = require('../createRenderer'); | ||
/** | ||
* adds a special renderer only used for font rendering | ||
* to prevent flickering on changes | ||
* | ||
* @param {Object} renderer - renderer which gets enhanced | ||
* @param {DOMElement} mountNode - stylesheet to render fonts into | ||
* @return {Object} enhanced renderer | ||
*/ | ||
var _createRenderer2 = _interopRequireDefault(_createRenderer); | ||
var _render = require('../dom/render'); | ||
var _render2 = _interopRequireDefault(_render); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
/* weak */ | ||
function addFontRenderer(renderer, mountNode) { | ||
renderer.fontRenderer = (0, _fela.createRenderer)(); | ||
renderer.fontRenderer = (0, _createRenderer2.default)(); | ||
// mount font styles into the mountNode | ||
if (mountNode) { | ||
(0, _fela.render)(renderer.fontRenderer, mountNode); | ||
(0, _render2.default)(renderer.fontRenderer, mountNode); | ||
} | ||
@@ -25,0 +26,0 @@ |
@@ -14,15 +14,10 @@ 'use strict'; | ||
var _styleTypes = require('../utils/styleTypes'); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
/** | ||
* adds a logging tool which listens to renderer changes | ||
* | ||
* @param {Object} renderer - renderer which gets enhanced | ||
* @param {Object} options - logging options | ||
* @return {Object} enhanced renderer | ||
*/ | ||
function addLogger(renderer, options) { | ||
renderer.subscribe(function (change) { | ||
// log clearing | ||
if (change.type === 'clear') { | ||
if (change.type === _styleTypes.CLEAR_TYPE) { | ||
console.log('Cleared renderer cache.'); // eslint-disable-line | ||
@@ -32,11 +27,5 @@ return true; | ||
// log status of rehydration | ||
if (change.type === 'rehydrate') { | ||
console.log('Renderer rehydration ' + (change.done ? 'finished' : 'started') + '.'); // eslint-disable-line | ||
return true; | ||
} | ||
var selector = change.selector || change.font || change.name; | ||
var style = change.style || change.fontFace; | ||
var css = options.format ? (0, _cssbeautify2.default)(change.css) : change.css; | ||
var selector = change.selector || change.fontFamily || change.name; | ||
var css = change.cssDeclaration || change.keyframe || change.fontFace || change.css; | ||
var formattedCSS = options.format ? (0, _cssbeautify2.default)(css) : css; | ||
var isMedia = change.media && change.media.length > 0; | ||
@@ -47,4 +36,3 @@ | ||
isMedia && console.log(change.media); // eslint-disable-line | ||
options.logStyleObject && console.log(style); // eslint-disable-line | ||
options.logCSS && console.log(css); // eslint-disable-line | ||
options.logCSS && console.log(formattedCSS); // eslint-disable-line | ||
console.groupEnd(selector); // eslint-disable-line | ||
@@ -56,7 +44,3 @@ }); | ||
var defaultOptions = { | ||
logStyleObject: true, | ||
logCSS: false, | ||
formatCSS: false | ||
}; | ||
var defaultOptions = { logCSS: false, formatCSS: false }; | ||
@@ -63,0 +47,0 @@ exports.default = function () { |
@@ -9,8 +9,2 @@ 'use strict'; | ||
/** | ||
* adds a performance profiler to renderRule calls | ||
* | ||
* @param {Object} renderer - renderer which gets enhanced | ||
* @return {Object} enhanced renderer | ||
*/ | ||
function addPerfTool(renderer) { | ||
@@ -17,0 +11,0 @@ var existingRenderRule = renderer.renderRule.bind(renderer); |
@@ -19,3 +19,3 @@ 'use strict'; | ||
var _render = require('./render'); | ||
var _render = require('./dom/render'); | ||
@@ -27,2 +27,7 @@ var _render2 = _interopRequireDefault(_render); | ||
/* weak */ | ||
function deprecatedRender(renderer, mountNode) { | ||
console.warn('Importing `render` from `fela` is deprecated. Use `fela-dom` to import `render` instead.'); // eslint-disable-line | ||
return (0, _render2.default)(renderer, mountNode); | ||
} | ||
exports.default = { | ||
@@ -32,4 +37,4 @@ createRenderer: _createRenderer2.default, | ||
enhance: _enhance2.default, | ||
render: _render2.default | ||
render: deprecatedRender | ||
}; | ||
module.exports = exports['default']; |
@@ -10,10 +10,8 @@ 'use strict'; | ||
var _generatePropsReference = require('../utils/generatePropsReference'); | ||
var _processStyleWithPlugins = require('../utils/processStyleWithPlugins'); | ||
var _generatePropsReference2 = _interopRequireDefault(_generatePropsReference); | ||
var _processStyleWithPlugins2 = _interopRequireDefault(_processStyleWithPlugins); | ||
var _processStyle = require('../utils/processStyle'); | ||
var _styleTypes = require('../utils/styleTypes'); | ||
var _processStyle2 = _interopRequireDefault(_processStyle); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -28,66 +26,20 @@ | ||
/** | ||
* clears the sheet's cache but keeps all listeners | ||
*/ | ||
clear: function clear() { | ||
renderer.rules = {}; | ||
renderer.cache = {}; | ||
renderer.ids = []; | ||
}, | ||
/** | ||
* renders a new rule variation and caches the result | ||
* | ||
* @param {Function} rule - rule which gets rendered | ||
* @param {Object?} props - properties used to render | ||
* @return {Object} style object | ||
*/ | ||
renderRule: function renderRule(rule) { | ||
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
// rendering a rule for the first time | ||
// will create an ID reference | ||
if (renderer.ids.indexOf(rule) < 0) { | ||
renderer.ids.push(rule); | ||
} | ||
var style = rule(props); | ||
var reference = JSON.stringify(style); | ||
// uses the reference ID and the props to generate an unique className | ||
var ruleId = renderer.ids.indexOf(rule); | ||
var styleOutput = renderer._resolveStyle(rule, props); | ||
var propsReference = Object.keys(props).length > 0 ? (0, _generatePropsReference2.default)(styleOutput) : ''; | ||
var ref = ruleId + propsReference; | ||
// only if the cached rule has not already been rendered | ||
// with a specific set of properties it actually renders | ||
if (!renderer.rules.hasOwnProperty(ref)) { | ||
var style = (0, _processStyle2.default)(styleOutput, { | ||
type: 'rule', | ||
id: ruleId, | ||
props: props, | ||
rule: rule | ||
}, renderer.plugins); | ||
if (Object.keys(style).length > 0) { | ||
renderer.rules[ref] = _reactNative.StyleSheet.create({ | ||
style: style | ||
}).style; | ||
} else { | ||
renderer.rules[ref] = undefined; | ||
} | ||
if (!renderer.cache[reference]) { | ||
var processedStyle = (0, _processStyleWithPlugins2.default)(style, renderer.plugins, _styleTypes.RULE_TYPE); | ||
renderer.cache[reference] = _reactNative.StyleSheet.create({ | ||
style: processedStyle | ||
}); | ||
} | ||
return renderer.rules[ref]; | ||
}, | ||
/** | ||
* Encapsulated style resolving method | ||
* | ||
* @param {Function} style - rule or keyframe to be resolved | ||
* @param {Object} props - props used to resolve style | ||
* @return {Object} resolved style | ||
*/ | ||
_resolveStyle: function _resolveStyle(style, props) { | ||
return style(props); | ||
return renderer.cache[reference].style; | ||
} | ||
@@ -99,7 +51,6 @@ }; | ||
// enhance renderer with passed set of enhancers | ||
if (config.enhancers) { | ||
config.enhancers.forEach(function (enhancer) { | ||
return renderer = enhancer(renderer); | ||
}); | ||
for (var i = 0, len = config.enhancers.length; i < len; ++i) { | ||
renderer = config.enhancers[i](renderer); | ||
} | ||
} | ||
@@ -106,0 +57,0 @@ |
@@ -8,3 +8,3 @@ "use strict"; | ||
function customProperty(style, properties) { | ||
Object.keys(style).forEach(function (property) { | ||
for (var property in style) { | ||
var value = style[property]; | ||
@@ -19,3 +19,3 @@ if (properties[property]) { | ||
} | ||
}); | ||
} | ||
@@ -22,0 +22,0 @@ return style; |
@@ -27,9 +27,10 @@ 'use strict'; | ||
function extend(style) { | ||
Object.keys(style).forEach(function (property) { | ||
for (var property in style) { | ||
var value = style[property]; | ||
if (property === 'extend') { | ||
// arrayify to loop each extension to support arrays and single extends | ||
[].concat(value).forEach(function (extension) { | ||
return extendStyle(style, extension); | ||
}); | ||
var extensions = [].concat(value); | ||
for (var i = 0, len = extensions.length; i < len; ++i) { | ||
extendStyle(style, extensions[i]); | ||
} | ||
delete style[property]; | ||
@@ -40,3 +41,3 @@ } else if (value instanceof Object && !Array.isArray(value)) { | ||
} | ||
}); | ||
} | ||
@@ -43,0 +44,0 @@ return style; |
@@ -6,2 +6,3 @@ 'use strict'; | ||
}); | ||
exports.resolveFallbackValues = resolveFallbackValues; | ||
@@ -14,4 +15,4 @@ var _hyphenateStyleName = require('hyphenate-style-name'); | ||
function fallbackValue(style) { | ||
Object.keys(style).forEach(function (property) { | ||
function resolveFallbackValues(style) { | ||
for (var property in style) { | ||
var value = style[property]; | ||
@@ -21,5 +22,5 @@ if (Array.isArray(value)) { | ||
} else if (value instanceof Object) { | ||
style[property] = fallbackValue(value); | ||
style[property] = resolveFallbackValues(value); | ||
} | ||
}); | ||
} | ||
@@ -30,5 +31,3 @@ return style; | ||
exports.default = function () { | ||
return fallbackValue; | ||
}; | ||
module.exports = exports['default']; | ||
return resolveFallbackValues; | ||
}; |
@@ -10,3 +10,3 @@ 'use strict'; | ||
function friendlyPseudoClass(style) { | ||
Object.keys(style).forEach(function (property) { | ||
for (var property in style) { | ||
var value = style[property]; | ||
@@ -27,3 +27,3 @@ if (value instanceof Object && !Array.isArray(value)) { | ||
} | ||
}); | ||
} | ||
@@ -30,0 +30,0 @@ return style; |
@@ -11,2 +11,4 @@ 'use strict'; | ||
function addIsolation(style) { | ||
var exclude = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; | ||
if (style.isolation === false) { | ||
@@ -19,8 +21,16 @@ // remove the isolation prop to | ||
return _extends({ all: 'initial' }, style); | ||
var excludedDeclarations = exclude.reduce(function (exclusion, property) { | ||
exclusion[property] = 'inherit'; | ||
return exclusion; | ||
}, {}); | ||
return _extends({ | ||
all: 'initial' | ||
}, excludedDeclarations, style); | ||
} | ||
exports.default = function () { | ||
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
return function (style) { | ||
return addIsolation(style); | ||
return addIsolation(style, options.exclude); | ||
}; | ||
@@ -27,0 +37,0 @@ }; |
@@ -13,21 +13,14 @@ 'use strict'; | ||
exports.default = function () { | ||
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
return function (style, meta) { | ||
var logMetaData = options.logMetaData || false; | ||
function addLogger(style, type) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
console.log(type, (0, _assign2.default)({}, style)); // eslint-disable-line | ||
} | ||
var currentStyle = (0, _assign2.default)({}, style); | ||
return style; | ||
} /* weak */ | ||
if (logMetaData) { | ||
var reference = meta.className || meta.selector || meta.animationName; | ||
console.log(meta.type.toUpperCase() + ' ' + reference, currentStyle, meta); // eslint-disable-line | ||
} else { | ||
console.log(currentStyle); // eslint-disable-line | ||
} | ||
exports.default = function () { | ||
return addLogger; | ||
}; | ||
return style; | ||
}; | ||
}; /* weak */ | ||
module.exports = exports['default']; |
@@ -6,2 +6,3 @@ 'use strict'; | ||
}); | ||
exports.addVendorPrefixes = addVendorPrefixes; | ||
@@ -12,11 +13,39 @@ var _static = require('inline-style-prefixer/static'); | ||
var _fallbackValue = require('./fallbackValue'); | ||
var _cssifyObject = require('../utils/cssifyObject'); | ||
var _cssifyObject2 = _interopRequireDefault(_cssifyObject); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.default = function () { | ||
return function (style) { | ||
return (0, _static2.default)(style); | ||
}; | ||
}; /* weak */ | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } /* weak */ | ||
module.exports = exports['default']; | ||
// TODO: refactor this messy piece of code | ||
// into clean, performant equivalent | ||
function addVendorPrefixes(style) { | ||
var prefixedStyle = {}; | ||
for (var property in style) { | ||
var value = style[property]; | ||
if (value instanceof Object && !Array.isArray(value)) { | ||
prefixedStyle[property] = addVendorPrefixes(value); | ||
} else { | ||
var declaration = _defineProperty({}, property, style[property]); | ||
var prefixedDeclaration = (0, _fallbackValue.resolveFallbackValues)((0, _static2.default)(declaration)); | ||
var referenceProperty = Object.keys(prefixedDeclaration)[0]; | ||
var referenceValue = prefixedDeclaration[referenceProperty]; | ||
delete prefixedDeclaration[referenceProperty]; | ||
var inlinedProperties = (0, _cssifyObject2.default)(prefixedDeclaration); | ||
prefixedStyle[referenceProperty] = referenceValue + (inlinedProperties ? ';' + inlinedProperties : ''); | ||
} | ||
} | ||
return prefixedStyle; | ||
} | ||
exports.default = function () { | ||
return addVendorPrefixes; | ||
}; |
@@ -12,10 +12,10 @@ 'use strict'; | ||
function removeUndefined(style) { | ||
Object.keys(style).forEach(function (property) { | ||
for (var property in style) { | ||
var value = style[property]; | ||
if (value instanceof Object && !Array.isArray(value)) { | ||
style[property] = removeUndefined(value); | ||
} else if (Array.isArray(value)) { | ||
if (Array.isArray(value)) { | ||
style[property] = value.filter(function (val) { | ||
return !isInvalid(val); | ||
}); | ||
} else if (value instanceof Object) { | ||
style[property] = removeUndefined(value); | ||
} else { | ||
@@ -26,3 +26,3 @@ if (isInvalid(value)) { | ||
} | ||
}); | ||
} | ||
@@ -29,0 +29,0 @@ return style; |
@@ -31,3 +31,3 @@ 'use strict'; | ||
function addUnit(style, unit, propertyMap) { | ||
Object.keys(style).forEach(function (property) { | ||
var _loop = function _loop(property) { | ||
if (!(0, _unitlessCssProperty2.default)(property)) { | ||
@@ -49,4 +49,8 @@ (function () { | ||
} | ||
}); | ||
}; | ||
for (var property in style) { | ||
_loop(property); | ||
} | ||
return style; | ||
@@ -53,0 +57,0 @@ } |
@@ -7,7 +7,9 @@ 'use strict'; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /* weak */ | ||
/* weak */ | ||
var _styleTypes = require('../utils/styleTypes'); | ||
function validateStyleObject(style, logInvalid, deleteInvalid) { | ||
Object.keys(style).forEach(function (property) { | ||
for (var property in style) { | ||
var value = style[property]; | ||
@@ -29,6 +31,6 @@ if (value instanceof Object && !Array.isArray(value)) { | ||
} | ||
}); | ||
} | ||
} | ||
function validator(style, meta, options) { | ||
function validator(style, type, options) { | ||
var logInvalid = options.logInvalid, | ||
@@ -38,4 +40,4 @@ deleteInvalid = options.deleteInvalid; | ||
if (meta.type === 'keyframe') { | ||
Object.keys(style).forEach(function (percentage) { | ||
if (type === _styleTypes.KEYFRAME_TYPE) { | ||
for (var percentage in style) { | ||
var percentageValue = parseFloat(percentage); | ||
@@ -67,4 +69,4 @@ var value = style[percentage]; | ||
} | ||
}); | ||
} else if (meta.type === 'rule') { | ||
} | ||
} else if (type === _styleTypes.RULE_TYPE) { | ||
validateStyleObject(style, logInvalid, deleteInvalid); | ||
@@ -79,4 +81,4 @@ } | ||
exports.default = function (options) { | ||
return function (style, meta) { | ||
return validator(style, meta, _extends({}, defaultOptions, options)); | ||
return function (style, type) { | ||
return validator(style, type, _extends({}, defaultOptions, options)); | ||
}; | ||
@@ -83,0 +85,0 @@ }; |
@@ -9,3 +9,5 @@ 'use strict'; | ||
create: function create(styles) { | ||
return Object.keys(styles).reduce(function (rules, rule) { | ||
var rules = {}; | ||
var _loop = function _loop(rule) { | ||
if (typeof styles[rule] !== 'function') { | ||
@@ -18,7 +20,11 @@ rules[rule] = function () { | ||
} | ||
}; | ||
return rules; | ||
}, {}); | ||
for (var rule in styles) { | ||
_loop(rule); | ||
} | ||
return rules; | ||
} | ||
}; | ||
module.exports = exports['default']; |
@@ -9,18 +9,22 @@ "use strict"; | ||
function assign(base) { | ||
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = arguments[_key]; | ||
for (var _len = arguments.length, extendingStyles = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
extendingStyles[_key - 1] = arguments[_key]; | ||
} | ||
return args.reduce(function (extend, obj) { | ||
for (var property in obj) { | ||
var value = obj[property]; | ||
if (extend[property] instanceof Object && value instanceof Object) { | ||
extend[property] = assign({}, extend[property], value); | ||
for (var i = 0, len = extendingStyles.length; i < len; ++i) { | ||
var style = extendingStyles[i]; | ||
for (var property in style) { | ||
var value = style[property]; | ||
if (base[property] instanceof Object && value instanceof Object) { | ||
base[property] = assign({}, base[property], value); | ||
} else { | ||
extend[property] = value; | ||
base[property] = value; | ||
} | ||
} | ||
return extend; | ||
}, base); | ||
} | ||
return base; | ||
} | ||
module.exports = exports["default"]; |
@@ -14,10 +14,2 @@ 'use strict'; | ||
/** | ||
* renders keyframes into a CSS string with all prefixes | ||
* | ||
* @param {Object} frames - validated frame declarations | ||
* @param {string} animationName - animation reference naming | ||
* @param {string[]} prefixes - list of used vendor prefixes | ||
* @return {string} valid CSS string | ||
*/ | ||
function cssifyKeyframe(frames, animationName) { | ||
@@ -24,0 +16,0 @@ var prefixes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ['']; |
@@ -8,5 +8,5 @@ 'use strict'; | ||
var _hyphenateStyleName = require('hyphenate-style-name'); | ||
var _generateCSSDeclaration = require('./generateCSSDeclaration'); | ||
var _hyphenateStyleName2 = _interopRequireDefault(_hyphenateStyleName); | ||
var _generateCSSDeclaration2 = _interopRequireDefault(_generateCSSDeclaration); | ||
@@ -19,24 +19,20 @@ var _warning = require('./warning'); | ||
/** | ||
* generates a valid CSS string containing style | ||
* | ||
* @param {Object} style - object containing CSS declarations | ||
* @returns {string} valid CSS string with dash cased properties | ||
*/ | ||
/* weak */ | ||
function cssifyObject(style) { | ||
return Object.keys(style).reduce(function (css, prop) { | ||
// warn if invalid values are rendered | ||
process.env.NODE_ENV !== "production" ? (0, _warning2.default)(typeof style[prop] === 'string' || typeof style[prop] === 'number', 'The invalid value `' + style[prop] + '` has been used as `' + prop + '`.') : void 0; | ||
var css = ''; | ||
for (var property in style) { | ||
process.env.NODE_ENV !== "production" ? (0, _warning2.default)(typeof style[property] === 'string' || typeof style[property] === 'number', 'The invalid value `' + style[property] + '` has been used as `' + property + '`.') : void 0; | ||
// prevents the semicolon after | ||
// the last rule declaration | ||
if (css.length > 0) { | ||
if (css) { | ||
css += ';'; | ||
} | ||
css += (0, _hyphenateStyleName2.default)(prop) + ':' + style[prop]; | ||
return css; | ||
}, ''); | ||
css += (0, _generateCSSDeclaration2.default)(property, style[property]); | ||
} | ||
return css; | ||
} | ||
module.exports = exports['default']; |
{ | ||
"name": "fela", | ||
"version": "4.0.1", | ||
"version": "4.1.0", | ||
"description": "Fast & Dynamic Styling in JavaScript", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
68
7
129877
2053