@@ -77,11 +77,9 @@ function AtImport(options) {
7777 * @param {Object } options
7878 */
7979function parseStyles ( styles , options , cb , importedFiles , ignoredAtRules , media ) {
80- styles . eachAtRule ( function checkAtRule ( atRule ) {
81- if ( atRule . name !== "import" ) {
82- return
83- }
84-
80+ var imports = [ ]
81+ styles . eachAtRule ( "import" , function checkAtRule ( atRule ) { imports . push ( atRule ) } )
82+ imports . forEach ( function ( atRule ) {
8583 helpers . try ( function transformAtImport ( ) {
8684 readAtImport ( atRule , options , cb , importedFiles , ignoredAtRules , media )
8785 } , atRule . source )
@@ -102,14 +100,16 @@ function addIgnoredAtRulesOnTop(styles, ignoredAtRules) {
102100 while ( i -- ) {
103101 var ignoredAtRule = ignoredAtRules [ i ] [ 0 ]
104102 ignoredAtRule . params = ignoredAtRules [ i ] [ 1 ] . fullUri + ( ignoredAtRules [ i ] [ 1 ] . media ? " " + ignoredAtRules [ i ] [ 1 ] . media : "" )
105- ignoredAtRule . before = "\n"
106- ignoredAtRule . after = ""
103+
104+ // keep ast ref
105+ ignoredAtRule . parent = styles
107106
108107 // don't use prepend() to avoid weird behavior of normalize()
109108 styles . nodes . unshift ( ignoredAtRule )
110109 }
111110
112- if ( first && first . before !== undefined ) {
111+ // separate remote import a little with others rules if no newlines already
112+ if ( first && first . before . indexOf ( "\n" ) === - 1 ) {
113113 first . before = "\n\n" + first . before
114114 }
115115 }
@@ -126,33 +126,38 @@ function readAtImport(atRule, options, cb, importedFiles, ignoredAtRules, media)
126126 // @todo extract what can be interesting from this one
127127 var parsedAtImport = parseImport ( atRule . params , atRule . source )
128128
129-
130-
131129 // adjust media according to current scope
132130 media = parsedAtImport . media ? ( media ? media + " and " : "" ) + parsedAtImport . media : ( media ? media : null )
133131
134132 // just update protocol base uri (protocol://url) or protocol-relative (//url) if media needed
135133 if ( parsedAtImport . uri . match ( / ^ (?: [ a - z ] + : ) ? \/ \/ / i) ) {
136134 parsedAtImport . media = media
137- var atRuleCloned = atRule . clone ( )
138- atRuleCloned . parent = atRule . parent . clone ( )
139- ignoredAtRules . push ( [ atRuleCloned , parsedAtImport ] )
140- atRule . removeSelf ( )
135+
136+ // save
137+ ignoredAtRules . push ( [ atRule , parsedAtImport ] )
138+
139+ // detach
140+ detach ( atRule )
141+
141142 return
142143 }
143144
144145 addInputToPath ( options )
145146 var resolvedFilename = resolveFilename ( parsedAtImport . uri , options . root , options . path , atRule . source )
146147
148+ // skip files already imported at the same scope
147149 if ( importedFiles [ resolvedFilename ] && importedFiles [ resolvedFilename ] [ media ] ) {
148- atRule . removeSelf ( )
150+ detach ( atRule )
149151 return
150152 }
153+
154+ // save imported files to skip them next time
151155 if ( ! importedFiles [ resolvedFilename ] ) {
152156 importedFiles [ resolvedFilename ] = { }
153157 }
154158 importedFiles [ resolvedFilename ] [ media ] = true
155159
160+
156161 readImportedContent ( atRule , parsedAtImport , clone ( options ) , resolvedFilename , cb , importedFiles , ignoredAtRules )
157162}
158163
@@ -179,7 +184,7 @@ function readImportedContent(atRule, parsedAtImport, options, resolvedFilename,
179184
180185 if ( fileContent . trim ( ) === "" ) {
181186 console . log ( helpers . message ( resolvedFilename + " is empty" , atRule . source ) )
182- atRule . removeSelf ( )
187+ detach ( atRule )
183188 return
184189 }
185190
@@ -199,29 +204,41 @@ function readImportedContent(atRule, parsedAtImport, options, resolvedFilename,
199204 * @param {Object } newStyles
200205 */
201206function insertRules ( atRule , parsedAtImport , newStyles ) {
207+ var newNodes = newStyles . nodes
208+
202209 // wrap rules if the @import have a media query
203210 if ( parsedAtImport . media && parsedAtImport . media . length ) {
211+ // better output
212+ if ( newStyles . nodes && newStyles . nodes . length ) {
213+ newStyles . nodes [ 0 ] . before = newStyles . nodes [ 0 ] . before || "\n"
214+ // newStyles.nodes[newStyles.nodes.length - 1].after = (newStyles.nodes[newStyles.nodes.length - 1].after || "") + "\n"
215+ }
216+
204217 // wrap new rules with media (media query)
205218 var wrapper = postcss . atRule ( {
206219 name : "media" ,
207220 params : parsedAtImport . media
208221 } )
209- wrapper . append ( newStyles )
210- newStyles = wrapper
211222
212- // better output
213- newStyles . before = atRule . before
214- if ( newStyles . nodes && newStyles . nodes . length ) {
215- newStyles . nodes [ 0 ] . before = newStyles . nodes [ 0 ] . before || "\n"
216- }
217- newStyles . after = atRule . after || "\n"
223+ // keep ast clean
224+ newNodes . forEach ( function ( node ) { node . parent = wrapper } )
225+ wrapper . source = atRule . source
226+
227+ // copy code style
228+ wrapper . before = atRule . before
229+ wrapper . after = atRule . after
230+
231+ // move nodes
232+ wrapper . nodes = newNodes
233+ newNodes = [ wrapper ]
218234 }
219- else if ( newStyles . nodes && newStyles . nodes . length ) {
220- newStyles . nodes [ 0 ] . before = atRule . before
235+ else if ( newNodes && newNodes . length ) {
236+ newNodes [ 0 ] . before = atRule . before
221237 }
222-
223- atRule . parent . insertBefore ( atRule , newStyles )
224- atRule . removeSelf ( )
238+ // replace atRule by imported nodes
239+ var nodes = atRule . parent . nodes
240+ nodes . splice . apply ( nodes , [ nodes . indexOf ( atRule ) , 0 ] . concat ( newNodes ) )
241+ detach ( atRule )
225242}
226243
227244/**
@@ -317,3 +334,7 @@ function addInputToPath(options) {
317334 }
318335 }
319336}
337+
338+ function detach ( node ) {
339+ node . parent . nodes . splice ( node . parent . nodes . indexOf ( node ) , 1 )
340+ }
0 commit comments