| | |
| | | 'use strict'; |
| | | var $ = require('../internals/export'); |
| | | var global = require('../internals/global'); |
| | | var call = require('../internals/function-call'); |
| | | var uncurryThis = require('../internals/function-uncurry-this'); |
| | | var requireObjectCoercible = require('../internals/require-object-coercible'); |
| | | var isCallable = require('../internals/is-callable'); |
| | | var isRegExp = require('../internals/is-regexp'); |
| | | var toString = require('../internals/to-string'); |
| | | var getMethod = require('../internals/get-method'); |
| | | var getRegExpFlags = require('../internals/regexp-flags'); |
| | | var getRegExpFlags = require('../internals/regexp-get-flags'); |
| | | var getSubstitution = require('../internals/get-substitution'); |
| | | var wellKnownSymbol = require('../internals/well-known-symbol'); |
| | | var IS_PURE = require('../internals/is-pure'); |
| | | |
| | | var REPLACE = wellKnownSymbol('replace'); |
| | | var RegExpPrototype = RegExp.prototype; |
| | | var TypeError = global.TypeError; |
| | | var indexOf = uncurryThis(''.indexOf); |
| | | var replace = uncurryThis(''.replace); |
| | | var stringSlice = uncurryThis(''.slice); |
| | | var max = Math.max; |
| | | |
| | | var stringIndexOf = function (string, searchValue, fromIndex) { |
| | | if (fromIndex > string.length) return -1; |
| | | if (searchValue === '') return fromIndex; |
| | | return string.indexOf(searchValue, fromIndex); |
| | | return indexOf(string, searchValue, fromIndex); |
| | | }; |
| | | |
| | | // `String.prototype.replaceAll` method |
| | |
| | | if (searchValue != null) { |
| | | IS_REG_EXP = isRegExp(searchValue); |
| | | if (IS_REG_EXP) { |
| | | flags = toString(requireObjectCoercible('flags' in RegExpPrototype |
| | | ? searchValue.flags |
| | | : getRegExpFlags.call(searchValue) |
| | | )); |
| | | if (!~flags.indexOf('g')) throw TypeError('`.replaceAll` does not allow non-global regexes'); |
| | | flags = toString(requireObjectCoercible(getRegExpFlags(searchValue))); |
| | | if (!~indexOf(flags, 'g')) throw TypeError('`.replaceAll` does not allow non-global regexes'); |
| | | } |
| | | replacer = getMethod(searchValue, REPLACE); |
| | | if (replacer) { |
| | | return replacer.call(searchValue, O, replaceValue); |
| | | return call(replacer, searchValue, O, replaceValue); |
| | | } else if (IS_PURE && IS_REG_EXP) { |
| | | return toString(O).replace(searchValue, replaceValue); |
| | | return replace(toString(O), searchValue, replaceValue); |
| | | } |
| | | } |
| | | string = toString(O); |
| | |
| | | advanceBy = max(1, searchLength); |
| | | position = stringIndexOf(string, searchString, 0); |
| | | while (position !== -1) { |
| | | if (functionalReplace) { |
| | | replacement = toString(replaceValue(searchString, position, string)); |
| | | } else { |
| | | replacement = getSubstitution(searchString, string, position, [], undefined, replaceValue); |
| | | } |
| | | result += string.slice(endOfLastMatch, position) + replacement; |
| | | replacement = functionalReplace |
| | | ? toString(replaceValue(searchString, position, string)) |
| | | : getSubstitution(searchString, string, position, [], undefined, replaceValue); |
| | | result += stringSlice(string, endOfLastMatch, position) + replacement; |
| | | endOfLastMatch = position + searchLength; |
| | | position = stringIndexOf(string, searchString, position + advanceBy); |
| | | } |
| | | if (endOfLastMatch < string.length) { |
| | | result += string.slice(endOfLastMatch); |
| | | result += stringSlice(string, endOfLastMatch); |
| | | } |
| | | return result; |
| | | } |