@@ -3,12 +3,16 @@ import asap from 'asap';
33
44import OrderedElements from './ordered-elements' ;
55import { generateCSS } from './generate' ;
6- import { flattenDeep , hashObject } from './util' ;
6+ import { hashObject } from './util' ;
77
88/* ::
99import type { SheetDefinition, SheetDefinitions } from './index.js';
1010import type { MaybeSheetDefinition } from './exports.js';
1111import type { SelectorHandler } from './generate.js';
12+ type ProcessedStyleDefinitions = {
13+ classNameBits: Array<string>,
14+ definitionBits: Array<Object>,
15+ };
1216*/
1317
1418// The current <style> tag we are inserting into, or null if we haven't
@@ -136,24 +140,26 @@ let injectionBuffer = "";
136140let isBuffering = false ;
137141
138142const injectGeneratedCSSOnce = ( key , generatedCSS ) => {
139- if ( ! alreadyInjected [ key ] ) {
140- if ( ! isBuffering ) {
141- // We should never be automatically buffering on the server (or any
142- // place without a document), so guard against that.
143- if ( typeof document === "undefined" ) {
144- throw new Error (
145- "Cannot automatically buffer without a document" ) ;
146- }
143+ if ( alreadyInjected [ key ] ) {
144+ return ;
145+ }
147146
148- // If we're not already buffering, schedule a call to flush the
149- // current styles.
150- isBuffering = true ;
151- asap ( flushToStyleTag ) ;
147+ if ( ! isBuffering ) {
148+ // We should never be automatically buffering on the server (or any
149+ // place without a document), so guard against that.
150+ if ( typeof document === "undefined" ) {
151+ throw new Error (
152+ "Cannot automatically buffer without a document" ) ;
152153 }
153154
154- injectionBuffer += generatedCSS ;
155- alreadyInjected [ key ] = true ;
155+ // If we're not already buffering, schedule a call to flush the
156+ // current styles.
157+ isBuffering = true ;
158+ asap ( flushToStyleTag ) ;
156159 }
160+
161+ injectionBuffer += generatedCSS ;
162+ alreadyInjected [ key ] = true ;
157163}
158164
159165export const injectStyleOnce = (
@@ -163,13 +169,15 @@ export const injectStyleOnce = (
163169 useImportant /* : boolean */ ,
164170 selectorHandlers /* : SelectorHandler[] */ = [ ]
165171) => {
166- if ( ! alreadyInjected [ key ] ) {
167- const generated = generateCSS (
168- selector , definitions , selectorHandlers ,
169- stringHandlers , useImportant ) ;
170-
171- injectGeneratedCSSOnce ( key , generated ) ;
172+ if ( alreadyInjected [ key ] ) {
173+ return ;
172174 }
175+
176+ const generated = generateCSS (
177+ selector , definitions , selectorHandlers ,
178+ stringHandlers , useImportant ) ;
179+
180+ injectGeneratedCSSOnce ( key , generated ) ;
173181} ;
174182
175183export const reset = ( ) => {
@@ -211,6 +219,25 @@ export const addRenderedClassNames = (classNames /* : string[] */) => {
211219 } ) ;
212220} ;
213221
222+ const processStyleDefinitions = (
223+ styleDefinitions /* : any[] */ ,
224+ result /* : ProcessedStyleDefinitions */
225+ ) /* : void */ => {
226+ for ( let i = 0 ; i < styleDefinitions . length ; i += 1 ) {
227+ // Filter out falsy values from the input, to allow for
228+ // `css(a, test && c)`
229+ if ( styleDefinitions [ i ] ) {
230+ if ( Array . isArray ( styleDefinitions [ i ] ) ) {
231+ // We've encountered an array, so let's recurse
232+ processStyleDefinitions ( styleDefinitions [ i ] , result ) ;
233+ } else {
234+ result . classNameBits . push ( styleDefinitions [ i ] . _name ) ;
235+ result . definitionBits . push ( styleDefinitions [ i ] . _definition ) ;
236+ }
237+ }
238+ }
239+ } ;
240+
214241/**
215242 * Inject styles associated with the passed style definition objects, and return
216243 * an associated CSS class name.
@@ -226,28 +253,23 @@ export const injectAndGetClassName = (
226253 styleDefinitions /* : MaybeSheetDefinition[] */ ,
227254 selectorHandlers /* : SelectorHandler[] */
228255) /* : string */ => {
229- styleDefinitions = flattenDeep ( styleDefinitions ) ;
256+ const processedStyleDefinitions /* : ProcessedStyleDefinitions */ = {
257+ classNameBits : [ ] ,
258+ definitionBits : [ ] ,
259+ } ;
260+ // Mutates processedStyleDefinitions
261+ processStyleDefinitions ( styleDefinitions , processedStyleDefinitions ) ;
230262
231- const classNameBits = [ ] ;
232- const definitionBits = [ ] ;
233- for ( let i = 0 ; i < styleDefinitions . length ; i += 1 ) {
234- // Filter out falsy values from the input, to allow for
235- // `css(a, test && c)`
236- if ( styleDefinitions [ i ] ) {
237- classNameBits . push ( styleDefinitions [ i ] . _name ) ;
238- definitionBits . push ( styleDefinitions [ i ] . _definition ) ;
239- }
240- }
241263 // Break if there aren't any valid styles.
242- if ( classNameBits . length === 0 ) {
264+ if ( processedStyleDefinitions . classNameBits . length === 0 ) {
243265 return "" ;
244266 }
245- const className = classNameBits . join ( "-o_O-" ) ;
267+ const className = processedStyleDefinitions . classNameBits . join ( "-o_O-" ) ;
246268
247269 injectStyleOnce (
248270 className ,
249271 `.${ className } ` ,
250- definitionBits ,
272+ processedStyleDefinitions . definitionBits ,
251273 useImportant ,
252274 selectorHandlers
253275 ) ;
0 commit comments