| 
									
										
										
										
											2014-08-22 19:51:24 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Jason Anderson @diurnalist | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var REGEXP_HASH = /\[hash(?::(\d+))?\]/gi, | 
					
						
							|  |  |  | 	REGEXP_CHUNKHASH = /\[chunkhash(?::(\d+))?\]/gi, | 
					
						
							|  |  |  | 	REGEXP_NAME = /\[name\]/gi, | 
					
						
							|  |  |  | 	REGEXP_ID = /\[id\]/gi, | 
					
						
							|  |  |  | 	REGEXP_FILE = /\[file\]/gi, | 
					
						
							|  |  |  | 	REGEXP_QUERY = /\[query\]/gi, | 
					
						
							|  |  |  | 	REGEXP_FILEBASE = /\[filebase\]/gi; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-24 05:24:49 +08:00
										 |  |  | // Using global RegExp for .test is dangerous
 | 
					
						
							|  |  |  | // We use a normal RegExp instead of .test
 | 
					
						
							|  |  |  | var REGEXP_HASH_FOR_TEST = new RegExp(REGEXP_HASH.source, "i"), | 
					
						
							|  |  |  | 	REGEXP_CHUNKHASH_FOR_TEST = new RegExp(REGEXP_CHUNKHASH.source, "i"), | 
					
						
							|  |  |  | 	REGEXP_NAME_FOR_TEST = new RegExp(REGEXP_NAME.source, "i"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 19:51:24 +08:00
										 |  |  | // Backwards compatibility; expose regexes on Template object
 | 
					
						
							|  |  |  | var Template = require("./Template"); | 
					
						
							|  |  |  | Template.REGEXP_HASH = REGEXP_HASH; | 
					
						
							|  |  |  | Template.REGEXP_CHUNKHASH = REGEXP_CHUNKHASH; | 
					
						
							|  |  |  | Template.REGEXP_NAME = REGEXP_NAME; | 
					
						
							|  |  |  | Template.REGEXP_ID = REGEXP_ID; | 
					
						
							|  |  |  | Template.REGEXP_FILE = REGEXP_FILE; | 
					
						
							|  |  |  | Template.REGEXP_QUERY = REGEXP_QUERY; | 
					
						
							|  |  |  | Template.REGEXP_FILEBASE = REGEXP_FILEBASE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function TemplatedPathPlugin() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = TemplatedPathPlugin; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-12 01:25:18 +08:00
										 |  |  | function withHashLength(replacer, handlerFn) { | 
					
						
							| 
									
										
										
										
											2015-07-08 20:39:02 +08:00
										 |  |  | 	return function(_, hashLength) { | 
					
						
							| 
									
										
										
										
											2014-09-12 01:25:18 +08:00
										 |  |  | 		var length = hashLength && parseInt(hashLength, 10); | 
					
						
							| 
									
										
										
										
											2015-07-16 06:19:23 +08:00
										 |  |  | 		if(length && handlerFn) { | 
					
						
							| 
									
										
										
										
											2014-09-12 01:25:18 +08:00
										 |  |  | 			return handlerFn(length); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-08-22 19:51:24 +08:00
										 |  |  | 		var hash = replacer.apply(this, arguments); | 
					
						
							| 
									
										
										
										
											2014-09-12 01:25:18 +08:00
										 |  |  | 		return length ? hash.slice(0, length) : hash; | 
					
						
							| 
									
										
										
										
											2014-08-22 19:51:24 +08:00
										 |  |  | 	}; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function getReplacer(value, allowEmpty) { | 
					
						
							| 
									
										
										
										
											2015-07-08 20:39:02 +08:00
										 |  |  | 	return function(match) { | 
					
						
							| 
									
										
										
										
											2014-08-22 19:51:24 +08:00
										 |  |  | 		// last argument in replacer is the entire input string
 | 
					
						
							|  |  |  | 		var input = arguments[arguments.length - 1]; | 
					
						
							| 
									
										
										
										
											2015-07-16 06:19:23 +08:00
										 |  |  | 		if(value == null) { | 
					
						
							|  |  |  | 			if(!allowEmpty) throw new Error("Path variable " + match + " not implemented in this context: " + input); | 
					
						
							| 
									
										
										
										
											2014-08-22 19:51:24 +08:00
										 |  |  | 			return ""; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			return "" + value; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function replacePathVariables(path, data) { | 
					
						
							|  |  |  | 	var chunk = data.chunk; | 
					
						
							|  |  |  | 	var chunkId = chunk && chunk.id; | 
					
						
							|  |  |  | 	var chunkName = chunk && (chunk.name || chunk.id); | 
					
						
							|  |  |  | 	var chunkHash = chunk && (chunk.renderedHash || chunk.hash); | 
					
						
							| 
									
										
										
										
											2014-09-12 01:25:18 +08:00
										 |  |  | 	var chunkHashWithLength = chunk && chunk.hashWithLength; | 
					
						
							| 
									
										
										
										
											2014-08-22 19:51:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-16 06:19:23 +08:00
										 |  |  | 	if(data.noChunkHash && REGEXP_CHUNKHASH_FOR_TEST.test(path)) { | 
					
						
							| 
									
										
										
										
											2015-06-27 17:34:17 +08:00
										 |  |  | 		throw new Error("Cannot use [chunkhash] for chunk in '" + path + "' (use [hash] instead)"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 19:51:24 +08:00
										 |  |  | 	return path | 
					
						
							| 
									
										
										
										
											2014-10-28 18:51:18 +08:00
										 |  |  | 		.replace(REGEXP_HASH, withHashLength(getReplacer(data.hash), data.hashWithLength)) | 
					
						
							| 
									
										
										
										
											2014-09-12 01:25:18 +08:00
										 |  |  | 		.replace(REGEXP_CHUNKHASH, withHashLength(getReplacer(chunkHash), chunkHashWithLength)) | 
					
						
							| 
									
										
										
										
											2014-08-22 19:51:24 +08:00
										 |  |  | 		.replace(REGEXP_ID, getReplacer(chunkId)) | 
					
						
							|  |  |  | 		.replace(REGEXP_NAME, getReplacer(chunkName)) | 
					
						
							|  |  |  | 		.replace(REGEXP_FILE, getReplacer(data.filename)) | 
					
						
							|  |  |  | 		.replace(REGEXP_FILEBASE, getReplacer(data.basename)) | 
					
						
							|  |  |  | 		// query is optional, it's OK if it's in a path but there's nothing to replace it with
 | 
					
						
							|  |  |  | 		.replace(REGEXP_QUERY, getReplacer(data.query, true)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TemplatedPathPlugin.prototype.constructor = TemplatedPathPlugin; | 
					
						
							|  |  |  | TemplatedPathPlugin.prototype.apply = function(compiler) { | 
					
						
							|  |  |  | 	compiler.plugin("compilation", function(compilation) { | 
					
						
							|  |  |  | 		var mainTemplate = compilation.mainTemplate; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		mainTemplate.plugin("asset-path", replacePathVariables); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		mainTemplate.plugin("global-hash", function(chunk, paths) { | 
					
						
							|  |  |  | 			var outputOptions = this.outputOptions; | 
					
						
							|  |  |  | 			var publicPath = outputOptions.publicPath || ""; | 
					
						
							|  |  |  | 			var filename = outputOptions.filename || ""; | 
					
						
							| 
									
										
										
										
											2015-07-23 04:34:25 +08:00
										 |  |  | 			var chunkFilename = outputOptions.chunkFilename || outputOptions.filename; | 
					
						
							| 
									
										
										
										
											2015-07-16 06:19:23 +08:00
										 |  |  | 			if(REGEXP_HASH_FOR_TEST.test(publicPath) || REGEXP_CHUNKHASH_FOR_TEST.test(publicPath) || REGEXP_NAME_FOR_TEST.test(publicPath)) | 
					
						
							| 
									
										
										
										
											2014-08-22 19:51:24 +08:00
										 |  |  | 				return true; | 
					
						
							| 
									
										
										
										
											2015-07-16 06:19:23 +08:00
										 |  |  | 			if(REGEXP_HASH_FOR_TEST.test(filename)) | 
					
						
							| 
									
										
										
										
											2014-08-22 19:51:24 +08:00
										 |  |  | 				return true; | 
					
						
							| 
									
										
										
										
											2015-07-16 06:19:23 +08:00
										 |  |  | 			if(REGEXP_HASH_FOR_TEST.test(chunkFilename)) | 
					
						
							| 
									
										
										
										
											2014-08-22 19:51:24 +08:00
										 |  |  | 				return true; | 
					
						
							| 
									
										
										
										
											2015-07-16 06:19:23 +08:00
										 |  |  | 			if(REGEXP_HASH_FOR_TEST.test(paths.join("|"))) | 
					
						
							| 
									
										
										
										
											2014-08-22 19:51:24 +08:00
										 |  |  | 				return true; | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2015-06-25 05:17:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		mainTemplate.plugin("hash-for-chunk", function(hash, chunk) { | 
					
						
							|  |  |  | 			var outputOptions = this.outputOptions; | 
					
						
							| 
									
										
										
										
											2015-07-23 04:34:25 +08:00
										 |  |  | 			var chunkFilename = outputOptions.chunkFilename || outputOptions.filename; | 
					
						
							| 
									
										
										
										
											2015-07-16 06:19:23 +08:00
										 |  |  | 			if(REGEXP_CHUNKHASH_FOR_TEST.test(chunkFilename)) | 
					
						
							| 
									
										
										
										
											2015-07-23 04:34:25 +08:00
										 |  |  | 				hash.update(JSON.stringify(chunk.getChunkMaps(true, true).hash)); | 
					
						
							| 
									
										
										
										
											2015-07-16 06:19:23 +08:00
										 |  |  | 			if(REGEXP_NAME_FOR_TEST.test(chunkFilename)) | 
					
						
							| 
									
										
										
										
											2015-07-23 04:34:25 +08:00
										 |  |  | 				hash.update(JSON.stringify(chunk.getChunkMaps(true, true).name)); | 
					
						
							| 
									
										
										
										
											2015-06-25 05:17:12 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2014-08-22 19:51:24 +08:00
										 |  |  | 	}); | 
					
						
							|  |  |  | }; |