1
1
var contexts = require ( "../contexts" ) ,
2
- Visitor = require ( "./visitor" ) ;
2
+ Visitor = require ( "./visitor" ) ,
3
+ ImportSequencer = require ( "./import-sequencer" ) ;
4
+
5
+ var ImportVisitor = function ( importer , finish ) {
3
6
4
- var ImportVisitor = function ( importer , finish , evalEnv , onceFileDetectionMap , recursionDetector ) {
5
7
this . _visitor = new Visitor ( this ) ;
6
8
this . _importer = importer ;
7
9
this . _finish = finish ;
8
- this . context = evalEnv || new contexts . Eval ( ) ;
10
+ this . context = new contexts . Eval ( ) ;
9
11
this . importCount = 0 ;
10
- this . onceFileDetectionMap = onceFileDetectionMap || { } ;
12
+ this . onceFileDetectionMap = { } ;
11
13
this . recursionDetector = { } ;
12
- if ( recursionDetector ) {
13
- for ( var fullFilename in recursionDetector ) {
14
- if ( recursionDetector . hasOwnProperty ( fullFilename ) ) {
15
- this . recursionDetector [ fullFilename ] = true ;
16
- }
17
- }
18
- }
14
+ this . _sequencer = new ImportSequencer ( ) ;
19
15
} ;
20
16
21
17
ImportVisitor . prototype = {
@@ -31,85 +27,121 @@ ImportVisitor.prototype = {
31
27
}
32
28
33
29
this . isFinished = true ;
34
-
30
+ this . _sequencer . tryRun ( ) ;
35
31
if ( this . importCount === 0 ) {
36
- this . _finish ( error ) ;
32
+ this . _finish ( error || this . error ) ;
37
33
}
38
34
} ,
39
35
visitImport : function ( importNode , visitArgs ) {
40
- var importVisitor = this ,
41
- evaldImportNode ,
42
- inlineCSS = importNode . options . inline ;
36
+ var inlineCSS = importNode . options . inline ;
43
37
44
38
if ( ! importNode . css || inlineCSS ) {
45
39
46
- try {
47
- evaldImportNode = importNode . evalForImport ( this . context ) ;
48
- } catch ( e ) {
49
- if ( ! e . filename ) { e . index = importNode . index ; e . filename = importNode . currentFileInfo . filename ; }
50
- // attempt to eval properly and treat as css
51
- importNode . css = true ;
52
- // if that fails, this error will be thrown
53
- importNode . error = e ;
40
+ var context = new contexts . Eval ( this . context , this . context . frames . slice ( 0 ) ) ;
41
+ var importParent = context . frames [ 0 ] ;
42
+
43
+ this . importCount ++ ;
44
+ if ( importNode . isVariableImport ( ) ) {
45
+ this . _sequencer . addVariableImport ( this . processImportNode . bind ( this , importNode , context , importParent ) ) ;
46
+ } else {
47
+ importNode = this . processImportNode ( importNode , context , importParent ) ;
48
+ }
49
+ }
50
+ visitArgs . visitDeeper = false ;
51
+ return importNode ;
52
+ } ,
53
+ processImportNode : function ( importNode , context , importParent ) {
54
+ var evaldImportNode ,
55
+ inlineCSS = importNode . options . inline ;
56
+
57
+ try {
58
+ evaldImportNode = importNode . evalForImport ( context ) ;
59
+ } catch ( e ) {
60
+ if ( ! e . filename ) { e . index = importNode . index ; e . filename = importNode . currentFileInfo . filename ; }
61
+ // attempt to eval properly and treat as css
62
+ importNode . css = true ;
63
+ // if that fails, this error will be thrown
64
+ importNode . error = e ;
65
+ }
66
+
67
+ if ( evaldImportNode && ( ! evaldImportNode . css || inlineCSS ) ) {
68
+
69
+ if ( evaldImportNode . options . multiple ) {
70
+ context . importMultiple = true ;
54
71
}
55
72
56
- if ( evaldImportNode && ( ! evaldImportNode . css || inlineCSS ) ) {
57
- importNode = evaldImportNode ;
58
- this . importCount ++ ;
59
- var context = new contexts . Eval ( this . context , this . context . frames . slice ( 0 ) ) ;
73
+ // try appending if we haven't determined if it is css or not
74
+ var tryAppendLessExtension = evaldImportNode . css === undefined ;
60
75
61
- if ( importNode . options . multiple ) {
62
- context . importMultiple = true ;
76
+ var onImported = this . onImported . bind ( this , evaldImportNode , context ) ,
77
+ sequencedOnImported = this . _sequencer . addImport ( onImported ) ;
78
+
79
+ this . _importer . push ( evaldImportNode . getPath ( ) , tryAppendLessExtension , evaldImportNode . currentFileInfo , evaldImportNode . options , sequencedOnImported ) ;
80
+
81
+ for ( var i = 0 ; i < importParent . rules . length ; i ++ ) {
82
+ if ( importParent . rules [ i ] === importNode ) {
83
+ importParent . rules [ i ] = evaldImportNode ;
84
+ break ;
63
85
}
86
+ }
87
+ importNode = evaldImportNode ;
88
+ } else {
89
+ this . importCount -- ;
90
+ }
91
+ return importNode ;
92
+ } ,
93
+ onImported : function ( importNode , context , e , root , importedAtRoot , fullPath ) {
94
+ if ( e ) {
95
+ if ( ! e . filename ) {
96
+ e . index = importNode . index ; e . filename = importNode . currentFileInfo . filename ;
97
+ }
98
+ this . error = e ;
99
+ }
64
100
65
- // try appending if we haven't determined if it is css or not
66
- var tryAppendLessExtension = importNode . css === undefined ;
67
- this . _importer . push ( importNode . getPath ( ) , tryAppendLessExtension , importNode . currentFileInfo , importNode . options , function ( e , root , importedAtRoot , fullPath ) {
68
- if ( e && ! e . filename ) {
69
- e . index = importNode . index ; e . filename = importNode . currentFileInfo . filename ;
70
- }
101
+ var importVisitor = this ,
102
+ inlineCSS = importNode . options . inline ,
103
+ duplicateImport = importedAtRoot || fullPath in importVisitor . recursionDetector ;
71
104
72
- var duplicateImport = importedAtRoot || fullPath in importVisitor . recursionDetector ;
73
- if ( ! context . importMultiple ) {
74
- if ( duplicateImport ) {
75
- importNode . skip = true ;
76
- } else {
77
- importNode . skip = function ( ) {
78
- if ( fullPath in importVisitor . onceFileDetectionMap ) {
79
- return true ;
80
- }
81
- importVisitor . onceFileDetectionMap [ fullPath ] = true ;
82
- return false ;
83
- } ;
84
- }
105
+ if ( ! context . importMultiple ) {
106
+ if ( duplicateImport ) {
107
+ importNode . skip = true ;
108
+ } else {
109
+ importNode . skip = function ( ) {
110
+ if ( fullPath in importVisitor . onceFileDetectionMap ) {
111
+ return true ;
85
112
}
113
+ importVisitor . onceFileDetectionMap [ fullPath ] = true ;
114
+ return false ;
115
+ } ;
116
+ }
117
+ }
86
118
87
- var subFinish = function ( e ) {
88
- importVisitor . importCount -- ;
119
+ if ( root ) {
120
+ importNode . root = root ;
121
+ importNode . importedFilename = fullPath ;
89
122
90
- if ( importVisitor . importCount === 0 && importVisitor . isFinished ) {
91
- importVisitor . _finish ( e ) ;
92
- }
93
- } ;
123
+ if ( ! inlineCSS && ( context . importMultiple || ! duplicateImport ) ) {
124
+ importVisitor . recursionDetector [ fullPath ] = true ;
94
125
95
- if ( root ) {
96
- importNode . root = root ;
97
- importNode . importedFilename = fullPath ;
126
+ var oldContext = this . context ;
127
+ this . context = context ;
128
+ try {
129
+ this . _visitor . visit ( root ) ;
130
+ } catch ( e ) {
131
+ this . error = e ;
132
+ }
133
+ this . context = oldContext ;
134
+ }
135
+ }
98
136
99
- if ( ! inlineCSS && ( context . importMultiple || ! duplicateImport ) ) {
100
- importVisitor . recursionDetector [ fullPath ] = true ;
101
- new ImportVisitor ( importVisitor . _importer , subFinish , context , importVisitor . onceFileDetectionMap , importVisitor . recursionDetector )
102
- . run ( root ) ;
103
- return ;
104
- }
105
- }
137
+ importVisitor . importCount -- ;
106
138
107
- subFinish ( ) ;
108
- } ) ;
139
+ if ( importVisitor . isFinished ) {
140
+ this . _sequencer . tryRun ( ) ;
141
+ if ( importVisitor . importCount === 0 ) {
142
+ importVisitor . _finish ( importVisitor . error ) ;
109
143
}
110
144
}
111
- visitArgs . visitDeeper = false ;
112
- return importNode ;
113
145
} ,
114
146
visitRule : function ( ruleNode , visitArgs ) {
115
147
visitArgs . visitDeeper = false ;
0 commit comments