@@ -5,20 +5,18 @@ var fs = require("fs")
55var path = require ( "path" )
66
77var assign = require ( "object-assign" )
8- var resolve = require ( "resolve" )
98var postcss = require ( "postcss" )
10- var helpers = require ( "postcss-message-helpers" )
119var glob = require ( "glob" )
1210var parseImports = require ( "./lib/parse-imports" )
1311var resolveMedia = require ( "./lib/resolve-media" )
12+ var resolveId = require ( "./lib/resolve-id" )
1413
1514/**
1615 * Constants
1716 */
1817var moduleDirectories = [
1918 "web_modules" ,
2019 "node_modules" ,
21- "bower_components" ,
2220]
2321
2422/**
@@ -67,7 +65,6 @@ function AtImport(options) {
6765
6866 var state = {
6967 importedFiles : { } ,
70- ignoredAtRules : [ ] ,
7168 hashFiles : { } ,
7269 }
7370 if ( opts . from ) {
@@ -85,8 +82,8 @@ function AtImport(options) {
8582 createProcessor ( result , options . plugins )
8683 )
8784
88- function onParseEnd ( ) {
89- addIgnoredAtRulesOnTop ( styles , state . ignoredAtRules )
85+ function onParseEnd ( ignored ) {
86+ addIgnoredAtRulesOnTop ( styles , ignored )
9087
9188 if (
9289 typeof opts . addDependencyTo === "object" &&
@@ -141,20 +138,32 @@ function parseStyles(
141138 } )
142139
143140 var importResults = imports . map ( function ( instance ) {
144- return helpers . try ( function transformAtImport ( ) {
145- return readAtImport (
146- result ,
147- instance . node ,
148- instance ,
149- options ,
150- state ,
151- media ,
152- processor
153- )
154- } , instance . node . source )
141+ return readAtImport (
142+ result ,
143+ instance . node ,
144+ instance ,
145+ options ,
146+ state ,
147+ media ,
148+ processor
149+ )
155150 } )
156151
157- return Promise . all ( importResults )
152+ return Promise . all ( importResults ) . then ( function ( result ) {
153+ // Flatten ignored instances
154+ return result . reduce ( function ( ignored , item ) {
155+ if ( Array . isArray ( item ) ) {
156+ item = item . filter ( function ( instance ) {
157+ return instance
158+ } )
159+ ignored = ignored . concat ( item )
160+ }
161+ else if ( item ) {
162+ ignored . push ( item )
163+ }
164+ return ignored
165+ } , [ ] )
166+ } )
158167}
159168
160169/**
@@ -212,15 +221,14 @@ function parseGlob(imports, instance, options) {
212221 * @param {Array } state
213222 */
214223function addIgnoredAtRulesOnTop ( styles , ignoredAtRules ) {
215- var i = ignoredAtRules . length
216- if ( i ) {
217- while ( i -- ) {
218- var ignored = ignoredAtRules [ i ] [ 1 ]
219- ignored . node . params = ignored . fullUri +
220- ( ignored . media . length ? " " + ignored . media . join ( ", " ) : "" )
221-
222- styles . prepend ( ignored . node )
223- }
224+ var i = ignoredAtRules . length - 1
225+ while ( i !== - 1 ) {
226+ var ignored = ignoredAtRules [ i ]
227+ ignored . node . params = ignored . fullUri +
228+ ( ignored . media . length ? " " + ignored . media . join ( ", " ) : "" )
229+
230+ styles . prepend ( ignored . node )
231+ i -= 1
224232 }
225233}
226234
@@ -247,51 +255,54 @@ function readAtImport(
247255 if ( parsedAtImport . uri . match ( / ^ (?: [ a - z ] + : ) ? \/ \/ / i) ) {
248256 parsedAtImport . media = media
249257
250- // save
251- state . ignoredAtRules . push ( [ atRule , parsedAtImport ] )
252-
253258 // detach
254259 atRule . remove ( )
255260
256- return Promise . resolve ( )
261+ return Promise . resolve ( parsedAtImport )
257262 }
258263
264+ var dir = atRule . source && atRule . source . input && atRule . source . input . file
265+ ? path . dirname ( path . resolve ( options . root , atRule . source . input . file ) )
266+ : options . root
267+
259268 addInputToPath ( options )
260- var resolvedFilename = resolveFilename (
261- parsedAtImport . uri ,
262- options . root ,
263- options . path ,
264- atRule . source ,
265- options . resolve
266- )
267269
268- if ( options . skipDuplicates ) {
269- // skip files already imported at the same scope
270- if (
271- state . importedFiles [ resolvedFilename ] &&
272- state . importedFiles [ resolvedFilename ] [ media ]
273- ) {
274- atRule . remove ( )
275- return Promise . resolve ( )
270+ return Promise . resolve ( ) . then ( function ( ) {
271+ if ( options . resolve ) {
272+ return options . resolve ( parsedAtImport . uri , dir , options )
276273 }
274+ return resolveId ( parsedAtImport . uri , dir , options . path )
275+ } ) . then ( function ( resolvedFilename ) {
276+ if ( options . skipDuplicates ) {
277+ // skip files already imported at the same scope
278+ if (
279+ state . importedFiles [ resolvedFilename ] &&
280+ state . importedFiles [ resolvedFilename ] [ media ]
281+ ) {
282+ atRule . remove ( )
283+ return Promise . resolve ( )
284+ }
277285
278- // save imported files to skip them next time
279- if ( ! state . importedFiles [ resolvedFilename ] ) {
280- state . importedFiles [ resolvedFilename ] = { }
286+ // save imported files to skip them next time
287+ if ( ! state . importedFiles [ resolvedFilename ] ) {
288+ state . importedFiles [ resolvedFilename ] = { }
289+ }
290+ state . importedFiles [ resolvedFilename ] [ media ] = true
281291 }
282- state . importedFiles [ resolvedFilename ] [ media ] = true
283- }
284292
285- return readImportedContent (
286- result ,
287- atRule ,
288- parsedAtImport ,
289- assign ( { } , options ) ,
290- resolvedFilename ,
291- state ,
292- media ,
293- processor
294- )
293+ return readImportedContent (
294+ result ,
295+ atRule ,
296+ parsedAtImport ,
297+ assign ( { } , options ) ,
298+ resolvedFilename ,
299+ state ,
300+ media ,
301+ processor
302+ )
303+ } ) . catch ( function ( err ) {
304+ result . warn ( err . message , { node : atRule } )
305+ } )
295306}
296307
297308/**
@@ -368,14 +379,18 @@ function readImportedContent(
368379 processor
369380 )
370381
371- return parsedResult . then ( function ( ) {
382+ var instances
383+
384+ return parsedResult . then ( function ( result ) {
385+ instances = result
372386 return processor . process ( newStyles )
373387 } )
374388 . then ( function ( newResult ) {
375389 result . messages = result . messages . concat ( newResult . messages )
376390 } )
377391 . then ( function ( ) {
378392 insertRules ( atRule , parsedAtImport , newStyles )
393+ return instances
379394 } )
380395}
381396
@@ -414,63 +429,6 @@ function insertRules(atRule, parsedAtImport, newStyles) {
414429 atRule . replaceWith ( newNodes )
415430}
416431
417- /**
418- * Check if a file exists
419- *
420- * @param {String } name
421- */
422- function resolveFilename ( name , root , paths , source , resolver ) {
423- var dir = source && source . input && source . input . file
424- ? path . dirname ( path . resolve ( root , source . input . file ) )
425- : root
426-
427- try {
428- var resolveOpts = {
429- basedir : dir ,
430- moduleDirectory : moduleDirectories . concat ( paths ) ,
431- paths : paths ,
432- extensions : [ ".css" ] ,
433- packageFilter : function processPackage ( pkg ) {
434- pkg . main = pkg . style || "index.css"
435- return pkg
436- } ,
437- }
438- var file
439- resolver = resolver || resolve . sync
440- try {
441- file = resolver ( name , resolveOpts )
442- }
443- catch ( e ) {
444- // fix to try relative files on windows with "./"
445- // if it's look like it doesn't start with a relative path already
446- // if (name.match(/^\.\.?/)) {throw e}
447- try {
448- file = resolver ( "./" + name , resolveOpts )
449- }
450- catch ( err ) {
451- // LAST HOPE
452- if ( ! paths . some ( function ( dir2 ) {
453- file = path . join ( dir2 , name )
454- return fs . existsSync ( file )
455- } ) ) {
456- throw err
457- }
458- }
459- }
460-
461- return path . normalize ( file )
462- }
463- catch ( e ) {
464- throw new Error (
465- "Failed to find '" + name + "' from " + root +
466- "\n in [ " +
467- "\n " + paths . join ( ",\n " ) +
468- "\n ]" ,
469- source
470- )
471- }
472- }
473-
474432/**
475433 * Read the contents of a file
476434 *
0 commit comments