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.
97 lines
4.1 KiB
97 lines
4.1 KiB
'use strict'; |
|
/* eslint-disable es-x/no-string-prototype-matchall -- safe */ |
|
var $ = require('../internals/export'); |
|
var call = require('../internals/function-call'); |
|
var uncurryThis = require('../internals/function-uncurry-this'); |
|
var createIteratorConstructor = require('../internals/create-iterator-constructor'); |
|
var requireObjectCoercible = require('../internals/require-object-coercible'); |
|
var toLength = require('../internals/to-length'); |
|
var toString = require('../internals/to-string'); |
|
var anObject = require('../internals/an-object'); |
|
var classof = require('../internals/classof-raw'); |
|
var isRegExp = require('../internals/is-regexp'); |
|
var getRegExpFlags = require('../internals/regexp-get-flags'); |
|
var getMethod = require('../internals/get-method'); |
|
var defineBuiltIn = require('../internals/define-built-in'); |
|
var fails = require('../internals/fails'); |
|
var wellKnownSymbol = require('../internals/well-known-symbol'); |
|
var speciesConstructor = require('../internals/species-constructor'); |
|
var advanceStringIndex = require('../internals/advance-string-index'); |
|
var regExpExec = require('../internals/regexp-exec-abstract'); |
|
var InternalStateModule = require('../internals/internal-state'); |
|
var IS_PURE = require('../internals/is-pure'); |
|
|
|
var MATCH_ALL = wellKnownSymbol('matchAll'); |
|
var REGEXP_STRING = 'RegExp String'; |
|
var REGEXP_STRING_ITERATOR = REGEXP_STRING + ' Iterator'; |
|
var setInternalState = InternalStateModule.set; |
|
var getInternalState = InternalStateModule.getterFor(REGEXP_STRING_ITERATOR); |
|
var RegExpPrototype = RegExp.prototype; |
|
var $TypeError = TypeError; |
|
var stringIndexOf = uncurryThis(''.indexOf); |
|
var un$MatchAll = uncurryThis(''.matchAll); |
|
|
|
var WORKS_WITH_NON_GLOBAL_REGEX = !!un$MatchAll && !fails(function () { |
|
un$MatchAll('a', /./); |
|
}); |
|
|
|
var $RegExpStringIterator = createIteratorConstructor(function RegExpStringIterator(regexp, string, $global, fullUnicode) { |
|
setInternalState(this, { |
|
type: REGEXP_STRING_ITERATOR, |
|
regexp: regexp, |
|
string: string, |
|
global: $global, |
|
unicode: fullUnicode, |
|
done: false |
|
}); |
|
}, REGEXP_STRING, function next() { |
|
var state = getInternalState(this); |
|
if (state.done) return { value: undefined, done: true }; |
|
var R = state.regexp; |
|
var S = state.string; |
|
var match = regExpExec(R, S); |
|
if (match === null) return { value: undefined, done: state.done = true }; |
|
if (state.global) { |
|
if (toString(match[0]) === '') R.lastIndex = advanceStringIndex(S, toLength(R.lastIndex), state.unicode); |
|
return { value: match, done: false }; |
|
} |
|
state.done = true; |
|
return { value: match, done: false }; |
|
}); |
|
|
|
var $matchAll = function (string) { |
|
var R = anObject(this); |
|
var S = toString(string); |
|
var C = speciesConstructor(R, RegExp); |
|
var flags = toString(getRegExpFlags(R)); |
|
var matcher, $global, fullUnicode; |
|
matcher = new C(C === RegExp ? R.source : R, flags); |
|
$global = !!~stringIndexOf(flags, 'g'); |
|
fullUnicode = !!~stringIndexOf(flags, 'u'); |
|
matcher.lastIndex = toLength(R.lastIndex); |
|
return new $RegExpStringIterator(matcher, S, $global, fullUnicode); |
|
}; |
|
|
|
// `String.prototype.matchAll` method |
|
// https://tc39.es/ecma262/#sec-string.prototype.matchall |
|
$({ target: 'String', proto: true, forced: WORKS_WITH_NON_GLOBAL_REGEX }, { |
|
matchAll: function matchAll(regexp) { |
|
var O = requireObjectCoercible(this); |
|
var flags, S, matcher, rx; |
|
if (regexp != null) { |
|
if (isRegExp(regexp)) { |
|
flags = toString(requireObjectCoercible(getRegExpFlags(regexp))); |
|
if (!~stringIndexOf(flags, 'g')) throw $TypeError('`.matchAll` does not allow non-global regexes'); |
|
} |
|
if (WORKS_WITH_NON_GLOBAL_REGEX) return un$MatchAll(O, regexp); |
|
matcher = getMethod(regexp, MATCH_ALL); |
|
if (matcher === undefined && IS_PURE && classof(regexp) == 'RegExp') matcher = $matchAll; |
|
if (matcher) return call(matcher, regexp, O); |
|
} else if (WORKS_WITH_NON_GLOBAL_REGEX) return un$MatchAll(O, regexp); |
|
S = toString(O); |
|
rx = new RegExp(regexp, 'g'); |
|
return IS_PURE ? call($matchAll, rx, S) : rx[MATCH_ALL](S); |
|
} |
|
}); |
|
|
|
IS_PURE || MATCH_ALL in RegExpPrototype || defineBuiltIn(RegExpPrototype, MATCH_ALL, $matchAll);
|
|
|