| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | var async = require("async"); | 
					
						
							|  |  |  | var path = require("path"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var Tapable = require("tapable"); | 
					
						
							|  |  |  | var ContextModule = require("./ContextModule"); | 
					
						
							|  |  |  | var ContextElementDependency = require("./dependencies/ContextElementDependency"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function ContextModuleFactory(resolvers) { | 
					
						
							|  |  |  | 	Tapable.call(this); | 
					
						
							|  |  |  | 	this.resolvers = resolvers; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | module.exports = ContextModuleFactory; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ContextModuleFactory.prototype = Object.create(Tapable.prototype); | 
					
						
							|  |  |  | ContextModuleFactory.prototype.create = function(context, dependency, callback) { | 
					
						
							|  |  |  | 	this.applyPluginsAsyncWaterfall("before-resolve", { | 
					
						
							|  |  |  | 		context: context, | 
					
						
							|  |  |  | 		request: dependency.request, | 
					
						
							|  |  |  | 		recursive: dependency.recursive, | 
					
						
							|  |  |  | 		regExp: dependency.regExp | 
					
						
							|  |  |  | 	}, function(err, result) { | 
					
						
							|  |  |  | 		if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-06 01:19:04 +08:00
										 |  |  | 		// Ignored
 | 
					
						
							|  |  |  | 		if(!result) return callback(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		var context = result.context; | 
					
						
							|  |  |  | 		var request = result.request; | 
					
						
							|  |  |  | 		var recursive = result.recursive; | 
					
						
							|  |  |  | 		var regExp = result.regExp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 		var loaders, resource, loadersPrefix = ""; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 		var idx = request.lastIndexOf("!"); | 
					
						
							|  |  |  | 		if(idx >= 0) { | 
					
						
							|  |  |  | 			loaders = request.substr(0, idx+1); | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 			for(var i = 0; i < loaders.length && loaders[i] === "!"; i++) { | 
					
						
							|  |  |  | 				loadersPrefix += "!"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			loaders = loaders.substr(i).replace(/!+$/, "").replace(/!!+/g, "!"); | 
					
						
							| 
									
										
										
										
											2014-06-25 00:53:32 +08:00
										 |  |  | 			if(loaders === "") loaders = []; | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 			else loaders = loaders.split("!"); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			resource = request.substr(idx+1); | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 			loaders = []; | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			resource = request; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 		async.parallel([ | 
					
						
							|  |  |  | 			this.resolvers.context.resolve.bind(this.resolvers.context, context, resource), | 
					
						
							|  |  |  | 			async.map.bind(async, loaders, this.resolvers.loader.resolve.bind(this.resolvers.loader, context)) | 
					
						
							|  |  |  | 		], function(err, result) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 			if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			this.applyPluginsAsyncWaterfall("after-resolve", { | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 				loaders: loadersPrefix + result[1].join("!") + (result[1].length > 0 ? "!" : ""), | 
					
						
							|  |  |  | 				resource: result[0], | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				recursive: recursive, | 
					
						
							|  |  |  | 				regExp: regExp | 
					
						
							|  |  |  | 			},  function(err, result) { | 
					
						
							|  |  |  | 				if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-06 01:19:04 +08:00
										 |  |  | 				// Ignored
 | 
					
						
							|  |  |  | 				if(!result) return callback(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				return callback(null, new ContextModule(this.resolveDependencies.bind(this), result.resource, result.recursive, result.regExp, result.loaders)); | 
					
						
							|  |  |  | 			}.bind(this)); | 
					
						
							|  |  |  | 		}.bind(this)); | 
					
						
							|  |  |  | 	}.bind(this)); | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | ContextModuleFactory.prototype.resolveDependencies = function resolveDependencies(fs, resource, recursive, regExp, callback) { | 
					
						
							|  |  |  | 	(function addDirectory(directory, callback) { | 
					
						
							|  |  |  | 		fs.readdir(directory, function(err, files) { | 
					
						
							| 
									
										
										
										
											2014-11-02 19:16:55 +08:00
										 |  |  | 			if(!files || files.length === 0) return callback(null, []); | 
					
						
							| 
									
										
										
										
											2014-11-02 19:56:40 +08:00
										 |  |  | 			async.map(files.filter(function(p) { | 
					
						
							|  |  |  | 				return p.indexOf(".") !== 0; | 
					
						
							|  |  |  | 			}), function(seqment, callback) { | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				var subResource = path.join(directory, seqment) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				fs.stat(subResource, function(err, stat) { | 
					
						
							|  |  |  | 					if(err) return callback(err); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if(stat.isDirectory()) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						if(!recursive) return callback(); | 
					
						
							|  |  |  | 						addDirectory.call(this, subResource, callback); | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 					} else if(stat.isFile()) { | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 						var obj = { | 
					
						
							|  |  |  | 							context: resource, | 
					
						
							|  |  |  | 							request: "." + subResource.substr(resource.length).replace(/\\/g, "/") | 
					
						
							|  |  |  | 						}; | 
					
						
							|  |  |  | 						this.applyPluginsAsyncWaterfall("alternatives", [obj], function(err, alternatives) { | 
					
						
							|  |  |  | 							alternatives = alternatives.filter(function(obj) { | 
					
						
							|  |  |  | 								return regExp.test(obj.request); | 
					
						
							|  |  |  | 							}).map(function(obj) { | 
					
						
							|  |  |  | 								var dep = new ContextElementDependency(obj.request); | 
					
						
							|  |  |  | 								dep.optional = true; | 
					
						
							|  |  |  | 								return dep; | 
					
						
							|  |  |  | 							}); | 
					
						
							|  |  |  | 							callback(null, alternatives); | 
					
						
							|  |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 					} else callback(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				}.bind(this)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			}.bind(this), function(err, result) { | 
					
						
							|  |  |  | 				if(err) return callback(err); | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-23 00:08:05 +08:00
										 |  |  | 				if(!result) return callback(null, []); | 
					
						
							| 
									
										
										
										
											2013-02-04 19:34:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 				callback(null, result.filter(function(i) { return !!i; }).reduce(function(a, i) { | 
					
						
							|  |  |  | 					return a.concat(i); | 
					
						
							|  |  |  | 				}, [])); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}.bind(this)); | 
					
						
							|  |  |  | 	}.call(this, resource, callback)); | 
					
						
							|  |  |  | }; |