You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					95 lines
				
				2.2 KiB
			
		
		
			
		
	
	
					95 lines
				
				2.2 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								'use strict';
							 | 
						||
| 
								 | 
							
								var token = '%[a-f0-9]{2}';
							 | 
						||
| 
								 | 
							
								var singleMatcher = new RegExp(token, 'gi');
							 | 
						||
| 
								 | 
							
								var multiMatcher = new RegExp('(' + token + ')+', 'gi');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function decodeComponents(components, split) {
							 | 
						||
| 
								 | 
							
									try {
							 | 
						||
| 
								 | 
							
										// Try to decode the entire string first
							 | 
						||
| 
								 | 
							
										return decodeURIComponent(components.join(''));
							 | 
						||
| 
								 | 
							
									} catch (err) {
							 | 
						||
| 
								 | 
							
										// Do nothing
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (components.length === 1) {
							 | 
						||
| 
								 | 
							
										return components;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									split = split || 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Split the array in 2 parts
							 | 
						||
| 
								 | 
							
									var left = components.slice(0, split);
							 | 
						||
| 
								 | 
							
									var right = components.slice(split);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return Array.prototype.concat.call([], decodeComponents(left), decodeComponents(right));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function decode(input) {
							 | 
						||
| 
								 | 
							
									try {
							 | 
						||
| 
								 | 
							
										return decodeURIComponent(input);
							 | 
						||
| 
								 | 
							
									} catch (err) {
							 | 
						||
| 
								 | 
							
										var tokens = input.match(singleMatcher);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for (var i = 1; i < tokens.length; i++) {
							 | 
						||
| 
								 | 
							
											input = decodeComponents(tokens, i).join('');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											tokens = input.match(singleMatcher);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return input;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function customDecodeURIComponent(input) {
							 | 
						||
| 
								 | 
							
									// Keep track of all the replacements and prefill the map with the `BOM`
							 | 
						||
| 
								 | 
							
									var replaceMap = {
							 | 
						||
| 
								 | 
							
										'%FE%FF': '\uFFFD\uFFFD',
							 | 
						||
| 
								 | 
							
										'%FF%FE': '\uFFFD\uFFFD'
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var match = multiMatcher.exec(input);
							 | 
						||
| 
								 | 
							
									while (match) {
							 | 
						||
| 
								 | 
							
										try {
							 | 
						||
| 
								 | 
							
											// Decode as big chunks as possible
							 | 
						||
| 
								 | 
							
											replaceMap[match[0]] = decodeURIComponent(match[0]);
							 | 
						||
| 
								 | 
							
										} catch (err) {
							 | 
						||
| 
								 | 
							
											var result = decode(match[0]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if (result !== match[0]) {
							 | 
						||
| 
								 | 
							
												replaceMap[match[0]] = result;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										match = multiMatcher.exec(input);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Add `%C2` at the end of the map to make sure it does not replace the combinator before everything else
							 | 
						||
| 
								 | 
							
									replaceMap['%C2'] = '\uFFFD';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var entries = Object.keys(replaceMap);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for (var i = 0; i < entries.length; i++) {
							 | 
						||
| 
								 | 
							
										// Replace all decoded components
							 | 
						||
| 
								 | 
							
										var key = entries[i];
							 | 
						||
| 
								 | 
							
										input = input.replace(new RegExp(key, 'g'), replaceMap[key]);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return input;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = function (encodedURI) {
							 | 
						||
| 
								 | 
							
									if (typeof encodedURI !== 'string') {
							 | 
						||
| 
								 | 
							
										throw new TypeError('Expected `encodedURI` to be of type `string`, got `' + typeof encodedURI + '`');
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									try {
							 | 
						||
| 
								 | 
							
										encodedURI = encodedURI.replace(/\+/g, ' ');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// Try the built in decoder first
							 | 
						||
| 
								 | 
							
										return decodeURIComponent(encodedURI);
							 | 
						||
| 
								 | 
							
									} catch (err) {
							 | 
						||
| 
								 | 
							
										// Fallback to a more advanced decoder
							 | 
						||
| 
								 | 
							
										return customDecodeURIComponent(encodedURI);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 |