Comparing version 2.0.0 to 3.0.0
200
dist/fela.js
@@ -11,3 +11,3 @@ (function (global, factory) { | ||
} : function (obj) { | ||
return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; | ||
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; | ||
}; | ||
@@ -125,3 +125,3 @@ | ||
function diffStyle(style) { | ||
var base = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
var base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
@@ -193,3 +193,3 @@ return Object.keys(style).reduce(function (diff, property) { | ||
function cssifyKeyframe(frames, animationName) { | ||
var prefixes = arguments.length <= 2 || arguments[2] === undefined ? [''] : arguments[2]; | ||
var prefixes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ['']; | ||
@@ -205,5 +205,12 @@ var keyframe = Object.keys(frames).reduce(function (css, percentage) { | ||
/** | ||
* 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]; | ||
var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
// the renderer is the key | ||
var renderer = { | ||
@@ -226,5 +233,6 @@ listeners: [], | ||
renderer.ids = []; | ||
renderer.callStack = []; | ||
// emit changes to notify subscribers | ||
renderer._emitChange(); | ||
renderer._emitFullReload(); | ||
}, | ||
@@ -241,3 +249,3 @@ | ||
renderRule: function renderRule(rule) { | ||
var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
@@ -263,6 +271,4 @@ // rendering a rule for the first time | ||
if (!renderer.rendered.hasOwnProperty(className)) { | ||
var resolvedStyle = renderer._resolveStyle(rule, props); | ||
// process style using each plugin | ||
var style = processStyle(resolvedStyle, { | ||
var style = processStyle(rule(props), { | ||
type: 'rule', | ||
@@ -278,13 +284,6 @@ className: className, | ||
renderer.rendered[className] = false; | ||
if (Object.keys(diffedStyle).length > 0) { | ||
renderer._renderStyle(className, diffedStyle); | ||
renderer.rendered[className] = renderer._didChange; | ||
if (renderer._didChange) { | ||
renderer._didChange = false; | ||
renderer._emitChange(); | ||
} | ||
} else { | ||
renderer.rendered[className] = false; | ||
} | ||
@@ -303,2 +302,4 @@ | ||
renderer.callStack.push(renderer.renderRule.bind(renderer, rule, props)); | ||
// returns either the base className or both the base and the dynamic part | ||
@@ -317,3 +318,3 @@ return className !== baseClassName ? baseClassName + ' ' + className : className; | ||
renderKeyframe: function renderKeyframe(keyframe) { | ||
var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
@@ -332,3 +333,3 @@ // rendering a Keyframe for the first time | ||
if (!renderer.rendered.hasOwnProperty(animationName)) { | ||
var processedKeyframe = processStyle(renderer._resolveStyle(keyframe, props), { | ||
var processedKeyframe = processStyle(keyframe(props), { | ||
type: 'keyframe', | ||
@@ -344,3 +345,5 @@ keyframe: keyframe, | ||
renderer.keyframes += css; | ||
renderer._emitChange(); | ||
renderer.callStack.push(renderer.renderKeyframe.bind(renderer, keyframe, props)); | ||
renderer._emitFullReload(); | ||
} | ||
@@ -359,3 +362,3 @@ | ||
renderFont: function renderFont(family, files) { | ||
var properties = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; | ||
var properties = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
@@ -381,5 +384,8 @@ var key = family + generatePropsReference(properties); | ||
var css = '@font-face{' + cssifyObject(fontFace) + '}'; | ||
renderer.rendered[key] = true; | ||
renderer.fontFaces += css; | ||
renderer._emitChange(); | ||
renderer.callStack.push(renderer.renderFont.bind(renderer, family, files, properties)); | ||
renderer._emitFullReload(); | ||
})(); | ||
@@ -406,2 +412,3 @@ } | ||
renderer.statics += style.replace(/\s{2,}/g, ''); | ||
renderer._emitFullReload(); | ||
} else { | ||
@@ -412,7 +419,15 @@ var processedStyle = processStyle(style, { | ||
}, renderer.plugins); | ||
renderer.statics += selector + '{' + cssifyObject(processedStyle) + '}'; | ||
var css = cssifyObject(processedStyle); | ||
renderer.statics += selector + '{' + css + '}'; | ||
renderer.callStack.push(renderer.renderStatic.bind(renderer, style, selector)); | ||
renderer._emitChange({ | ||
selector: selector, | ||
style: css, | ||
type: 'rule' | ||
}); | ||
} | ||
renderer.rendered[reference] = true; | ||
renderer._emitChange(); | ||
} | ||
@@ -455,10 +470,18 @@ }, | ||
/** | ||
* 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 | ||
* rehydrates the whole cache using the callStack | ||
*/ | ||
_resolveStyle: function _resolveStyle(style, props) { | ||
return style(props); | ||
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 }); | ||
// run a full reload after every style is rerendered | ||
renderer._emitFullReload(); | ||
}, | ||
@@ -468,4 +491,4 @@ | ||
/** | ||
* calls each listener with the current CSS markup of all caches | ||
* gets only called if the markup actually changes | ||
* calls each listener with a change object | ||
* gets only called if something actually changes | ||
* | ||
@@ -475,6 +498,5 @@ * @param {Function} callback - callback function which will be executed | ||
*/ | ||
_emitChange: function _emitChange() { | ||
var css = renderer.renderToString(); | ||
_emitChange: function _emitChange(change) { | ||
renderer.listeners.forEach(function (listener) { | ||
return listener(css); | ||
return listener(change, renderer); | ||
}); | ||
@@ -485,2 +507,13 @@ }, | ||
/** | ||
* emits change object to trigger full css reload | ||
*/ | ||
_emitFullReload: function _emitFullReload() { | ||
renderer._emitChange({ | ||
css: renderer.renderToString(), | ||
type: 'static' | ||
}); | ||
}, | ||
/** | ||
* iterates a style object and renders each rule to the cache | ||
@@ -492,4 +525,4 @@ * | ||
_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 pseudo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; | ||
var media = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ''; | ||
@@ -502,3 +535,3 @@ var ruleset = Object.keys(style).reduce(function (ruleset, property) { | ||
// allow pseudo classes, attribute selectors and the child selector | ||
if (property.charAt(0) === ':' || property.charAt(0) === '[' || property.charAt(0) === '>') { | ||
if (property.match(/^(:|\[|>)/) !== null) { | ||
renderer._renderStyle(className, value, pseudo + property, media); | ||
@@ -519,5 +552,8 @@ } else if (property.substr(0, 6) === '@media') { | ||
if (Object.keys(ruleset).length > 0) { | ||
var css = '.' + className + pseudo + '{' + cssifyObject(ruleset) + '}'; | ||
renderer._didChange = true; | ||
renderer.rendered[className] = true; | ||
var css = cssifyObject(ruleset); | ||
var selector = '.' + className + pseudo; | ||
var cssRule = selector + '{' + css + '}'; | ||
if (media.length > 0) { | ||
@@ -528,6 +564,13 @@ if (!renderer.mediaRules.hasOwnProperty(media)) { | ||
renderer.mediaRules[media] += css; | ||
renderer.mediaRules[media] += cssRule; | ||
} else { | ||
renderer.rules += css; | ||
renderer.rules += cssRule; | ||
} | ||
renderer._emitChange({ | ||
selector: selector, | ||
style: css, | ||
media: media, | ||
type: 'rule' | ||
}); | ||
} | ||
@@ -612,9 +655,60 @@ } | ||
var NODE_TYPE = 1; | ||
var NODE_NAME = 'STYLE'; | ||
function createDOMInterface(renderer, node) { | ||
// this counter is used to cache the amount of @media rules | ||
// rendered using insertRule since the last full rerender with textContent | ||
// using the counter enables to insert rules and @media rules separately | ||
// which helps to ensure correct order and prevents rule order issue | ||
var mediaRules = 0; | ||
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; | ||
return true; | ||
} | ||
// only update DOM if the renderer is not hydrating at the moment | ||
if (!isHydrating) { | ||
switch (change.type) { | ||
case 'rule': | ||
// only use insertRule in production as browser devtools might have | ||
// weird behavior if used together with insertRule at runtime | ||
if (true) { | ||
node.textContent = renderer.renderToString(); | ||
// the @media rules counter gets reset as the | ||
// full rerender also includes all @media rules | ||
mediaRules = 0; | ||
} else {} | ||
break; | ||
case 'static': | ||
// rules that cannot be dynamically added with insertRule | ||
// which are @font-face, @keyframes and static string assets | ||
// need to use textContent to apply styles | ||
node.textContent = change.css; | ||
mediaRules = 0; | ||
break; | ||
} | ||
} | ||
} | ||
}; | ||
return DOMInterface; | ||
} | ||
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 !== NODE_TYPE) { | ||
if (!mountNode || mountNode.nodeType !== 1) { | ||
throw new Error('You need to specify a valid element node (nodeType = 1) to render into.'); | ||
@@ -625,3 +719,3 @@ } | ||
// or if the node already got the data-fela-stylesheet attribute applied suggesting it is already used by another Renderer | ||
warning$1(mountNode.nodeName === NODE_NAME, 'You are using a node other than `<style>`. Your styles might not get applied correctly.'); | ||
warning$1(mountNode.nodeName === 'STYLE', 'You are using a node other than `<style>`. Your styles might not get applied correctly.'); | ||
warning$1(!mountNode.hasAttribute('data-fela-stylesheet'), 'This node is already used by another renderer. Rendering might overwrite other styles.'); | ||
@@ -632,9 +726,9 @@ | ||
// updated the DOM node's textContent with newly rendered markup | ||
renderer.subscribe(function (css) { | ||
return mountNode.textContent = css; | ||
}); | ||
var DOMInterface = createDOMInterface(renderer, mountNode); | ||
renderer.subscribe(DOMInterface.updateNode); | ||
// render currently rendered styles to the DOM once when it is not already in DOM | ||
// render currently rendered styles to the DOM once | ||
// if it is not already in DOM | ||
var css = renderer.renderToString(); | ||
if (mountNode.textContent !== css) { | ||
@@ -641,0 +735,0 @@ mountNode.textContent = css; |
@@ -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,n=0,t=void 0,i=e.length;if(0===i)return"";for(;n<i;++n)t=e.charCodeAt(n),r=(r<<5)-r+t,r|=0;return"-"+r.toString(36)}function n(e){return Object.keys(e).sort().reduce(function(r,n){return r+n+e[n]},"")}function t(e){return Object.keys(p).reduce(function(r,n){return e.indexOf(n)>-1&&(r=p[n]),r},void 0)}function i(e,r,n){return n.reduce(function(e,n){return n(e,r)},e)}function o(e){var r=arguments.length<=1||void 0===arguments[1]?{}:arguments[1];return Object.keys(e).reduce(function(n,t){var i=e[t];if(i instanceof Object&&!Array.isArray(i)){var u=o(i,r[t]);Object.keys(u).length>0&&(n[t]=u)}else if(void 0!==i&&!r.hasOwnProperty(t)||r[t]!==i){if("string"==typeof i&&i.indexOf("undefined")>-1)return n;n[t]=i}return n},{})}function u(e){return Object.keys(e).reduce(function(r,n){return r.length>0&&(r+=";"),r+=g(n)+":"+e[n]},"")}function f(e,r){var n=arguments.length<=2||void 0===arguments[2]?[""]:arguments[2],t=Object.keys(e).reduce(function(r,n){return r+n+"{"+u(e[n])+"}"},"");return n.reduce(function(e,n){return e+"@"+n+"keyframes "+r+"{"+t+"}"},"")}function a(){var e=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],r={listeners:[],keyframePrefixes:e.keyframePrefixes||["-webkit-","-moz-"],plugins:e.plugins||[],clear:function(){r.fontFaces="",r.keyframes="",r.statics="",r.rules="",r.mediaRules={},r.rendered={},r.base={},r.ids=[],r._emitChange()},renderRule:function(e){var n=arguments.length<=1||void 0===arguments[1]?{}:arguments[1];r.ids.indexOf(e)<0&&(r.ids.push(e),Object.keys(n).length>0&&r.renderRule(e,{}));var t=r.ids.indexOf(e),u="c"+t+h(n);if(!r.rendered.hasOwnProperty(u)){var f=r._resolveStyle(e,n),a=i(f,{type:"rule",className:u,id:t,props:n,rule:e},r.plugins),s=o(a,r.base[t]);Object.keys(s).length>0?(r._renderStyle(u,s),r.rendered[u]=r._didChange,r._didChange&&(r._didChange=!1,r._emitChange())):r.rendered[u]=!1,u==="c"+t&&(r.base[t]=s)}var c="c"+t;return r.rendered[u]?u!==c?c+" "+u:u:c},renderKeyframe:function(e){var n=arguments.length<=1||void 0===arguments[1]?{}:arguments[1];r.ids.indexOf(e)<0&&r.ids.push(e);var t=h(n),o="k"+r.ids.indexOf(e)+t;if(!r.rendered.hasOwnProperty(o)){var u=i(r._resolveStyle(e,n),{type:"keyframe",keyframe:e,props:n,animationName:o,id:r.ids.indexOf(e)},r.plugins),a=f(u,o,r.keyframePrefixes);r.rendered[o]=!0,r.keyframes+=a,r._emitChange()}return o},renderFont:function(e,n){var i=arguments.length<=2||void 0===arguments[2]?{}:arguments[2],o=e+h(i);return r.rendered.hasOwnProperty(o)||!function(){var f={fontFamily:"'"+e+"'",src:n.map(function(e){return"url('"+e+"') format('"+t(e)+"')"}).join(",")},a=["fontVariant","fontWeight","fontStretch","fontStyle","unicodeRange"];Object.keys(i).filter(function(e){return a.indexOf(e)>-1}).forEach(function(e){return f[e]=i[e]});var s="@font-face{"+u(f)+"}";r.rendered[o]=!0,r.fontFaces+=s,r._emitChange()}(),e},renderStatic:function(e,t){var o="string"==typeof e?e:t+n(e);if(!r.rendered.hasOwnProperty(o)){if("string"==typeof e)r.statics+=e.replace(/\s{2,}/g,"");else{var f=i(e,{selector:t,type:"static"},r.plugins);r.statics+=t+"{"+u(f)+"}"}r.rendered[o]=!0,r._emitChange()}},renderToString:function(){var e=r.fontFaces+r.statics+r.rules;for(var n in r.mediaRules)e+="@media "+n+"{"+r.mediaRules[n]+"}";return e+r.keyframes},subscribe:function(e){return r.listeners.push(e),{unsubscribe:function(){return r.listeners.splice(r.listeners.indexOf(e),1)}}},_resolveStyle:function(e,r){return e(r)},_emitChange:function(){var e=r.renderToString();r.listeners.forEach(function(r){return r(e)})},_renderStyle:function(e,n){var t=arguments.length<=2||void 0===arguments[2]?"":arguments[2],i=arguments.length<=3||void 0===arguments[3]?"":arguments[3],o=Object.keys(n).reduce(function(o,u){var f=n[u];if(f instanceof Object&&!Array.isArray(f)){if(":"===u.charAt(0)||"["===u.charAt(0)||">"===u.charAt(0))r._renderStyle(e,f,t+u,i);else if("@media"===u.substr(0,6)){var a=u.slice(6).trim(),s=i.length>0?i+" and "+a:a;r._renderStyle(e,f,t,s)}}else o[u]=f;return o},{});if(Object.keys(o).length>0){var f="."+e+t+"{"+u(o)+"}";r._didChange=!0,i.length>0?(r.mediaRules.hasOwnProperty(i)||(r.mediaRules[i]=""),r.mediaRules[i]+=f):r.rules+=f}}};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,n=Array(r>1?r-1:0),t=1;t<r;t++)n[t-1]=arguments[t];return n.reduce(function(e,r){for(var n in r){var t=r[n];e[n]instanceof Object&&t instanceof Object?e[n]=s({},e[n],t):e[n]=t}return e},e)}function c(){for(var e=arguments.length,r=Array(e),n=0;n<e;n++)r[n]=arguments[n];return function(e){return r.reduce(function(r,n){return s(r,n(e))},{})}}function d(){for(var e=arguments.length,r=Array(e),n=0;n<e;n++)r[n]=arguments[n];return function(e){return function(){return r.reduce(function(e,r){return r(e)},e.apply(void 0,arguments))}}}function l(e,r){if(!r||r.nodeType!==m)throw new Error("You need to specify a valid element node (nodeType = 1) to render into.");r.setAttribute("data-fela-stylesheet",""),e.subscribe(function(e){return r.textContent=e});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?"symbol":typeof e},y.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};var h=function(e){return r(n(e))},p={".woff":"woff",".eof":"eof",".ttf":"truetype",".svg":"svg"},v=e(function(e){function r(e){return e.replace(n,"-$&").toLowerCase().replace(t,"-ms-")}var n=/[A-Z]/g,t=/^ms-/;e.exports=r}),g=v&&"object"==typeof v&&"default"in v?v.default:v,m=1,b={createRenderer:a,combineRules:c,enhance:d,render:l};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){var r=0,n=0,t=void 0,i=e.length;if(0===i)return"";for(;n<i;++n)t=e.charCodeAt(n),r=(r<<5)-r+t,r|=0;return"-"+r.toString(36)}function n(e){return Object.keys(e).sort().reduce(function(r,n){return r+n+e[n]},"")}function t(e){return Object.keys(m).reduce(function(r,n){return e.indexOf(n)>-1&&(r=m[n]),r},void 0)}function i(e,r,n){return n.reduce(function(e,n){return n(e,r)},e)}function o(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return Object.keys(e).reduce(function(n,t){var i=e[t];if(i instanceof Object&&!Array.isArray(i)){var u=o(i,r[t]);Object.keys(u).length>0&&(n[t]=u)}else if(void 0!==i&&!r.hasOwnProperty(t)||r[t]!==i){if("string"==typeof i&&i.indexOf("undefined")>-1)return n;n[t]=i}return n},{})}function u(e){return Object.keys(e).reduce(function(r,n){return r.length>0&&(r+=";"),r+=g(n)+":"+e[n]},"")}function a(e,r){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[""],t=Object.keys(e).reduce(function(r,n){return r+n+"{"+u(e[n])+"}"},"");return n.reduce(function(e,n){return e+"@"+n+"keyframes "+r+"{"+t+"}"},"")}function c(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r={listeners:[],keyframePrefixes:e.keyframePrefixes||["-webkit-","-moz-"],plugins:e.plugins||[],clear:function(){r.fontFaces="",r.keyframes="",r.statics="",r.rules="",r.mediaRules={},r.rendered={},r.base={},r.ids=[],r.callStack=[],r._emitFullReload()},renderRule:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};r.ids.indexOf(e)<0&&(r.ids.push(e),Object.keys(n).length>0&&r.renderRule(e,{}));var t=r.ids.indexOf(e),u="c"+t+h(n);if(!r.rendered.hasOwnProperty(u)){var a=i(e(n),{type:"rule",className:u,id:t,props:n,rule:e},r.plugins),c=o(a,r.base[t]);r.rendered[u]=!1,Object.keys(c).length>0&&r._renderStyle(u,c),u==="c"+t&&(r.base[t]=c)}var s="c"+t;return r.rendered[u]?(r.callStack.push(r.renderRule.bind(r,e,n)),u!==s?s+" "+u:u):s},renderKeyframe:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};r.ids.indexOf(e)<0&&r.ids.push(e);var t=h(n),o="k"+r.ids.indexOf(e)+t;if(!r.rendered.hasOwnProperty(o)){var u=i(e(n),{type:"keyframe",keyframe:e,props:n,animationName:o,id:r.ids.indexOf(e)},r.plugins),c=a(u,o,r.keyframePrefixes);r.rendered[o]=!0,r.keyframes+=c,r.callStack.push(r.renderKeyframe.bind(r,e,n)),r._emitFullReload()}return o},renderFont:function(e,n){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=e+h(i);return r.rendered.hasOwnProperty(o)||!function(){var a={fontFamily:"'"+e+"'",src:n.map(function(e){return"url('"+e+"') format('"+t(e)+"')"}).join(",")},c=["fontVariant","fontWeight","fontStretch","fontStyle","unicodeRange"];Object.keys(i).filter(function(e){return c.indexOf(e)>-1}).forEach(function(e){return a[e]=i[e]});var s="@font-face{"+u(a)+"}";r.rendered[o]=!0,r.fontFaces+=s,r.callStack.push(r.renderFont.bind(r,e,n,i)),r._emitFullReload()}(),e},renderStatic:function(e,t){var o="string"==typeof e?e:t+n(e);if(!r.rendered.hasOwnProperty(o)){if("string"==typeof e)r.statics+=e.replace(/\s{2,}/g,""),r._emitFullReload();else{var a=i(e,{selector:t,type:"static"},r.plugins),c=u(a);r.statics+=t+"{"+c+"}",r.callStack.push(r.renderStatic.bind(r,e,t)),r._emitChange({selector:t,style:c,type:"rule"})}r.rendered[o]=!0}},renderToString:function(){var e=r.fontFaces+r.statics+r.rules;for(var n in r.mediaRules)e+="@media "+n+"{"+r.mediaRules[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}),r._emitFullReload()},_emitChange:function(e){r.listeners.forEach(function(n){return n(e,r)})},_emitFullReload:function(){r._emitChange({css:r.renderToString(),type:"static"})},_renderStyle:function(e,n){var t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"",o=Object.keys(n).reduce(function(o,u){var a=n[u];if(a instanceof Object&&!Array.isArray(a)){if(null!==u.match(/^(:|\[|>)/))r._renderStyle(e,a,t+u,i);else if("@media"===u.substr(0,6)){var c=u.slice(6).trim(),s=i.length>0?i+" and "+c:c;r._renderStyle(e,a,t,s)}}else o[u]=a;return o},{});if(Object.keys(o).length>0){r.rendered[e]=!0;var a=u(o),c="."+e+t,s=c+"{"+a+"}";i.length>0?(r.mediaRules.hasOwnProperty(i)||(r.mediaRules[i]=""),r.mediaRules[i]+=s):r.rules+=s,r._emitChange({selector:c,style:a,media:i,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,n=Array(r>1?r-1:0),t=1;t<r;t++)n[t-1]=arguments[t];return n.reduce(function(e,r){for(var n in r){var t=r[n];e[n]instanceof Object&&t instanceof Object?e[n]=s({},e[n],t):e[n]=t}return e},e)}function f(){for(var e=arguments.length,r=Array(e),n=0;n<e;n++)r[n]=arguments[n];return function(e){return r.reduce(function(r,n){return s(r,n(e))},{})}}function d(){for(var e=arguments.length,r=Array(e),n=0;n<e;n++)r[n]=arguments[n];return function(e){return function(){return r.reduce(function(e,r){return r(e)},e.apply(void 0,arguments))}}}function l(e,r){var n=0,t=!1,i={updateNode:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if("hydrate"===e.type)return t=!e.done,!0;if(!t)switch(e.type){case"rule":var i=e.selector,o=e.style,u=e.media,a=i+"{"+o+"}",c=r.sheet,s=c.cssRules.length;u&&u.length>0?(c.insertRule("@media "+u+"{"+a+"}",s-n),n+=1):c.insertRule(a,0);break;case"static":r.textContent=e.css,n=0}}};return i}function y(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 n=l(e,r);e.subscribe(n.updateNode);var t=e.renderToString();r.textContent!==t&&(r.textContent=t)}var p={};p.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},p.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};var h=function(e){return r(n(e))},m={".woff":"woff",".eof":"eof",".ttf":"truetype",".svg":"svg"},v=e(function(e){function r(e){return e.replace(n,"-$&").toLowerCase().replace(t,"-ms-")}var n=/[A-Z]/g,t=/^ms-/;e.exports=r}),g=v&&"object"==typeof v&&"default"in v?v.default:v,b={createRenderer:c,combineRules:f,enhance:d,render:y};return b}); |
@@ -38,5 +38,12 @@ 'use strict'; | ||
/** | ||
* 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]; | ||
var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
// the renderer is the key | ||
var renderer = { | ||
@@ -59,5 +66,6 @@ listeners: [], | ||
renderer.ids = []; | ||
renderer.callStack = []; | ||
// emit changes to notify subscribers | ||
renderer._emitChange(); | ||
renderer._emitFullReload(); | ||
}, | ||
@@ -74,3 +82,3 @@ | ||
renderRule: function renderRule(rule) { | ||
var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
@@ -96,6 +104,4 @@ // rendering a rule for the first time | ||
if (!renderer.rendered.hasOwnProperty(className)) { | ||
var resolvedStyle = renderer._resolveStyle(rule, props); | ||
// process style using each plugin | ||
var style = (0, _processStyle2.default)(resolvedStyle, { | ||
var style = (0, _processStyle2.default)(rule(props), { | ||
type: 'rule', | ||
@@ -111,13 +117,6 @@ className: className, | ||
renderer.rendered[className] = false; | ||
if (Object.keys(diffedStyle).length > 0) { | ||
renderer._renderStyle(className, diffedStyle); | ||
renderer.rendered[className] = renderer._didChange; | ||
if (renderer._didChange) { | ||
renderer._didChange = false; | ||
renderer._emitChange(); | ||
} | ||
} else { | ||
renderer.rendered[className] = false; | ||
} | ||
@@ -136,2 +135,4 @@ | ||
renderer.callStack.push(renderer.renderRule.bind(renderer, rule, props)); | ||
// returns either the base className or both the base and the dynamic part | ||
@@ -150,3 +151,3 @@ return className !== baseClassName ? baseClassName + ' ' + className : className; | ||
renderKeyframe: function renderKeyframe(keyframe) { | ||
var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
@@ -165,3 +166,3 @@ // rendering a Keyframe for the first time | ||
if (!renderer.rendered.hasOwnProperty(animationName)) { | ||
var processedKeyframe = (0, _processStyle2.default)(renderer._resolveStyle(keyframe, props), { | ||
var processedKeyframe = (0, _processStyle2.default)(keyframe(props), { | ||
type: 'keyframe', | ||
@@ -177,3 +178,5 @@ keyframe: keyframe, | ||
renderer.keyframes += css; | ||
renderer._emitChange(); | ||
renderer.callStack.push(renderer.renderKeyframe.bind(renderer, keyframe, props)); | ||
renderer._emitFullReload(); | ||
} | ||
@@ -192,3 +195,3 @@ | ||
renderFont: function renderFont(family, files) { | ||
var properties = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; | ||
var properties = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
@@ -214,5 +217,8 @@ var key = family + (0, _generatePropsReference2.default)(properties); | ||
var css = '@font-face{' + (0, _cssifyObject2.default)(fontFace) + '}'; | ||
renderer.rendered[key] = true; | ||
renderer.fontFaces += css; | ||
renderer._emitChange(); | ||
renderer.callStack.push(renderer.renderFont.bind(renderer, family, files, properties)); | ||
renderer._emitFullReload(); | ||
})(); | ||
@@ -239,2 +245,3 @@ } | ||
renderer.statics += style.replace(/\s{2,}/g, ''); | ||
renderer._emitFullReload(); | ||
} else { | ||
@@ -245,7 +252,15 @@ var processedStyle = (0, _processStyle2.default)(style, { | ||
}, renderer.plugins); | ||
renderer.statics += selector + '{' + (0, _cssifyObject2.default)(processedStyle) + '}'; | ||
var css = (0, _cssifyObject2.default)(processedStyle); | ||
renderer.statics += selector + '{' + css + '}'; | ||
renderer.callStack.push(renderer.renderStatic.bind(renderer, style, selector)); | ||
renderer._emitChange({ | ||
selector: selector, | ||
style: css, | ||
type: 'rule' | ||
}); | ||
} | ||
renderer.rendered[reference] = true; | ||
renderer._emitChange(); | ||
} | ||
@@ -288,10 +303,18 @@ }, | ||
/** | ||
* 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 | ||
* rehydrates the whole cache using the callStack | ||
*/ | ||
_resolveStyle: function _resolveStyle(style, props) { | ||
return style(props); | ||
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 }); | ||
// run a full reload after every style is rerendered | ||
renderer._emitFullReload(); | ||
}, | ||
@@ -301,4 +324,4 @@ | ||
/** | ||
* calls each listener with the current CSS markup of all caches | ||
* gets only called if the markup actually changes | ||
* calls each listener with a change object | ||
* gets only called if something actually changes | ||
* | ||
@@ -308,6 +331,5 @@ * @param {Function} callback - callback function which will be executed | ||
*/ | ||
_emitChange: function _emitChange() { | ||
var css = renderer.renderToString(); | ||
_emitChange: function _emitChange(change) { | ||
renderer.listeners.forEach(function (listener) { | ||
return listener(css); | ||
return listener(change, renderer); | ||
}); | ||
@@ -318,2 +340,13 @@ }, | ||
/** | ||
* emits change object to trigger full css reload | ||
*/ | ||
_emitFullReload: function _emitFullReload() { | ||
renderer._emitChange({ | ||
css: renderer.renderToString(), | ||
type: 'static' | ||
}); | ||
}, | ||
/** | ||
* iterates a style object and renders each rule to the cache | ||
@@ -325,4 +358,4 @@ * | ||
_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 pseudo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; | ||
var media = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ''; | ||
@@ -335,3 +368,3 @@ var ruleset = Object.keys(style).reduce(function (ruleset, property) { | ||
// allow pseudo classes, attribute selectors and the child selector | ||
if (property.charAt(0) === ':' || property.charAt(0) === '[' || property.charAt(0) === '>') { | ||
if (property.match(/^(:|\[|>)/) !== null) { | ||
renderer._renderStyle(className, value, pseudo + property, media); | ||
@@ -352,5 +385,8 @@ } else if (property.substr(0, 6) === '@media') { | ||
if (Object.keys(ruleset).length > 0) { | ||
var css = '.' + className + pseudo + '{' + (0, _cssifyObject2.default)(ruleset) + '}'; | ||
renderer._didChange = true; | ||
renderer.rendered[className] = true; | ||
var css = (0, _cssifyObject2.default)(ruleset); | ||
var selector = '.' + className + pseudo; | ||
var cssRule = selector + '{' + css + '}'; | ||
if (media.length > 0) { | ||
@@ -361,6 +397,13 @@ if (!renderer.mediaRules.hasOwnProperty(media)) { | ||
renderer.mediaRules[media] += css; | ||
renderer.mediaRules[media] += cssRule; | ||
} else { | ||
renderer.rules += css; | ||
renderer.rules += cssRule; | ||
} | ||
renderer._emitChange({ | ||
selector: selector, | ||
style: css, | ||
media: media, | ||
type: 'rule' | ||
}); | ||
} | ||
@@ -367,0 +410,0 @@ } |
@@ -26,2 +26,3 @@ 'use strict'; | ||
var css = existingRenderToString(); | ||
return (0, _cssbeautify2.default)(css, _extends({}, defaultOptions, options)); | ||
@@ -28,0 +29,0 @@ }; |
@@ -16,3 +16,3 @@ 'use strict'; | ||
var className = existingRenderRule(rule, props); | ||
console.log(timerCounter + ' ' + rule.name, props); // eslint-disable-line | ||
console.log(timerCounter + ' ' + (rule.name || 'anonym'), props); // eslint-disable-line | ||
console.timeEnd(timerCounter); // eslint-disable-line | ||
@@ -19,0 +19,0 @@ |
@@ -21,3 +21,3 @@ 'use strict'; | ||
function createRenderer() { | ||
var config = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
@@ -45,3 +45,3 @@ var renderer = { | ||
renderRule: function renderRule(rule) { | ||
var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
@@ -48,0 +48,0 @@ // rendering a rule for the first time |
@@ -14,3 +14,3 @@ 'use strict'; | ||
exports.default = function () { | ||
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
return function (style, meta) { | ||
@@ -17,0 +17,0 @@ var logMetaData = options.logMetaData || false; |
@@ -7,3 +7,3 @@ 'use strict'; | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
@@ -51,3 +51,3 @@ var _warning = require('../utils/warning'); | ||
exports.default = function () { | ||
var unit = arguments.length <= 0 || arguments[0] === undefined ? 'px' : arguments[0]; | ||
var unit = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'px'; | ||
@@ -54,0 +54,0 @@ process.env.NODE_ENV !== "production" ? (0, _warning2.default)(unit.match(/ch|em|ex|rem|vh|vw|vmin|vmax|px|cm|mm|in|pc|pt|mozmm|%/) !== null, 'You are using an invalid unit `' + unit + '`. Consider using one of the following ch, em, ex, rem, vh, vw, vmin, vmax, px, cm, mm, in, pc, pt, mozmm or %.') : void 0; |
@@ -17,3 +17,3 @@ 'use strict'; | ||
exports.default = [(0, _logger2.default)(), (0, _validator2.default)()]; | ||
exports.default = [(0, _logger2.default)({ logMetaData: true }), (0, _validator2.default)()]; | ||
module.exports = exports['default']; |
@@ -12,11 +12,12 @@ 'use strict'; | ||
var _DOMInterface = require('./utils/DOMInterface'); | ||
var _DOMInterface2 = _interopRequireDefault(_DOMInterface); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var NODE_TYPE = 1; | ||
var NODE_NAME = 'STYLE'; | ||
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 !== NODE_TYPE) { | ||
if (!mountNode || mountNode.nodeType !== 1) { | ||
throw new Error('You need to specify a valid element node (nodeType = 1) to render into.'); | ||
@@ -27,3 +28,3 @@ } | ||
// or if the node already got the data-fela-stylesheet attribute applied suggesting it is already used by another Renderer | ||
process.env.NODE_ENV !== "production" ? (0, _warning2.default)(mountNode.nodeName === NODE_NAME, 'You are using a node other than `<style>`. Your styles might not get applied correctly.') : void 0; | ||
process.env.NODE_ENV !== "production" ? (0, _warning2.default)(mountNode.nodeName === 'STYLE', 'You are using a node other than `<style>`. Your styles might not get applied correctly.') : void 0; | ||
process.env.NODE_ENV !== "production" ? (0, _warning2.default)(!mountNode.hasAttribute('data-fela-stylesheet'), 'This node is already used by another renderer. Rendering might overwrite other styles.') : void 0; | ||
@@ -34,9 +35,9 @@ | ||
// updated the DOM node's textContent with newly rendered markup | ||
renderer.subscribe(function (css) { | ||
return mountNode.textContent = css; | ||
}); | ||
var DOMInterface = (0, _DOMInterface2.default)(renderer, mountNode); | ||
renderer.subscribe(DOMInterface.updateNode); | ||
// render currently rendered styles to the DOM once when it is not already in DOM | ||
// render currently rendered styles to the DOM once | ||
// if it is not already in DOM | ||
var css = renderer.renderToString(); | ||
if (mountNode.textContent !== css) { | ||
@@ -43,0 +44,0 @@ mountNode.textContent = css; |
@@ -23,3 +23,3 @@ 'use strict'; | ||
function cssifyKeyframe(frames, animationName) { | ||
var prefixes = arguments.length <= 2 || arguments[2] === undefined ? [''] : arguments[2]; | ||
var prefixes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ['']; | ||
@@ -26,0 +26,0 @@ var keyframe = Object.keys(frames).reduce(function (css, percentage) { |
@@ -14,3 +14,3 @@ 'use strict'; | ||
function diffStyle(style) { | ||
var base = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
var base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
@@ -17,0 +17,0 @@ return Object.keys(style).reduce(function (diff, property) { |
{ | ||
"name": "fela", | ||
"version": "2.0.0", | ||
"version": "3.0.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
119658
41
1815