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.
		
		
		
		
		
			
		
			
				
					
					
						
							119 lines
						
					
					
						
							4.5 KiB
						
					
					
				
			
		
		
	
	
							119 lines
						
					
					
						
							4.5 KiB
						
					
					
				| 'use strict';
 | |
| 
 | |
| var anObject = require('./_an-object');
 | |
| var toObject = require('./_to-object');
 | |
| var toLength = require('./_to-length');
 | |
| var toInteger = require('./_to-integer');
 | |
| var advanceStringIndex = require('./_advance-string-index');
 | |
| var regExpExec = require('./_regexp-exec-abstract');
 | |
| var max = Math.max;
 | |
| var min = Math.min;
 | |
| var floor = Math.floor;
 | |
| var SUBSTITUTION_SYMBOLS = /\$([$&`']|\d\d?|<[^>]*>)/g;
 | |
| var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&`']|\d\d?)/g;
 | |
| 
 | |
| var maybeToString = function (it) {
 | |
|   return it === undefined ? it : String(it);
 | |
| };
 | |
| 
 | |
| // @@replace logic
 | |
| require('./_fix-re-wks')('replace', 2, function (defined, REPLACE, $replace, maybeCallNative) {
 | |
|   return [
 | |
|     // `String.prototype.replace` method
 | |
|     // https://tc39.github.io/ecma262/#sec-string.prototype.replace
 | |
|     function replace(searchValue, replaceValue) {
 | |
|       var O = defined(this);
 | |
|       var fn = searchValue == undefined ? undefined : searchValue[REPLACE];
 | |
|       return fn !== undefined
 | |
|         ? fn.call(searchValue, O, replaceValue)
 | |
|         : $replace.call(String(O), searchValue, replaceValue);
 | |
|     },
 | |
|     // `RegExp.prototype[@@replace]` method
 | |
|     // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace
 | |
|     function (regexp, replaceValue) {
 | |
|       var res = maybeCallNative($replace, regexp, this, replaceValue);
 | |
|       if (res.done) return res.value;
 | |
| 
 | |
|       var rx = anObject(regexp);
 | |
|       var S = String(this);
 | |
|       var functionalReplace = typeof replaceValue === 'function';
 | |
|       if (!functionalReplace) replaceValue = String(replaceValue);
 | |
|       var global = rx.global;
 | |
|       if (global) {
 | |
|         var fullUnicode = rx.unicode;
 | |
|         rx.lastIndex = 0;
 | |
|       }
 | |
|       var results = [];
 | |
|       while (true) {
 | |
|         var result = regExpExec(rx, S);
 | |
|         if (result === null) break;
 | |
|         results.push(result);
 | |
|         if (!global) break;
 | |
|         var matchStr = String(result[0]);
 | |
|         if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
 | |
|       }
 | |
|       var accumulatedResult = '';
 | |
|       var nextSourcePosition = 0;
 | |
|       for (var i = 0; i < results.length; i++) {
 | |
|         result = results[i];
 | |
|         var matched = String(result[0]);
 | |
|         var position = max(min(toInteger(result.index), S.length), 0);
 | |
|         var captures = [];
 | |
|         // NOTE: This is equivalent to
 | |
|         //   captures = result.slice(1).map(maybeToString)
 | |
|         // but for some reason `nativeSlice.call(result, 1, result.length)` (called in
 | |
|         // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and
 | |
|         // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.
 | |
|         for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));
 | |
|         var namedCaptures = result.groups;
 | |
|         if (functionalReplace) {
 | |
|           var replacerArgs = [matched].concat(captures, position, S);
 | |
|           if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);
 | |
|           var replacement = String(replaceValue.apply(undefined, replacerArgs));
 | |
|         } else {
 | |
|           replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
 | |
|         }
 | |
|         if (position >= nextSourcePosition) {
 | |
|           accumulatedResult += S.slice(nextSourcePosition, position) + replacement;
 | |
|           nextSourcePosition = position + matched.length;
 | |
|         }
 | |
|       }
 | |
|       return accumulatedResult + S.slice(nextSourcePosition);
 | |
|     }
 | |
|   ];
 | |
| 
 | |
|     // https://tc39.github.io/ecma262/#sec-getsubstitution
 | |
|   function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {
 | |
|     var tailPos = position + matched.length;
 | |
|     var m = captures.length;
 | |
|     var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;
 | |
|     if (namedCaptures !== undefined) {
 | |
|       namedCaptures = toObject(namedCaptures);
 | |
|       symbols = SUBSTITUTION_SYMBOLS;
 | |
|     }
 | |
|     return $replace.call(replacement, symbols, function (match, ch) {
 | |
|       var capture;
 | |
|       switch (ch.charAt(0)) {
 | |
|         case '$': return '$';
 | |
|         case '&': return matched;
 | |
|         case '`': return str.slice(0, position);
 | |
|         case "'": return str.slice(tailPos);
 | |
|         case '<':
 | |
|           capture = namedCaptures[ch.slice(1, -1)];
 | |
|           break;
 | |
|         default: // \d\d?
 | |
|           var n = +ch;
 | |
|           if (n === 0) return match;
 | |
|           if (n > m) {
 | |
|             var f = floor(n / 10);
 | |
|             if (f === 0) return match;
 | |
|             if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);
 | |
|             return match;
 | |
|           }
 | |
|           capture = captures[n - 1];
 | |
|       }
 | |
|       return capture === undefined ? '' : capture;
 | |
|     });
 | |
|   }
 | |
| });
 |