'use strict'; /* eslint-disable es/no-string-prototype-matchall -- safe */ var $ = require('../internals/export'); var call = require('../internals/function-call'); var uncurryThis = require('../internals/function-uncurry-this-clause'); var createIteratorConstructor = require('../internals/iterator-create-constructor'); var createIterResultObject = require('../internals/create-iter-result-object'); 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 isNullOrUndefined = require('../internals/is-null-or-undefined'); 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 nativeMatchAll = uncurryThis(''.matchAll); var WORKS_WITH_NON_GLOBAL_REGEX = !!nativeMatchAll && !fails(function () { nativeMatchAll('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 createIterResultObject(undefined, true); var R = state.regexp; var S = state.string; var match = regExpExec(R, S); if (match === null) { state.done = true; return createIterResultObject(undefined, true); } if (state.global) { if (toString(match[0]) === '') R.lastIndex = advanceStringIndex(S, toLength(R.lastIndex), state.unicode); return createIterResultObject(match, false); } state.done = true; return createIterResultObject(match, 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 (!isNullOrUndefined(regexp)) { if (isRegExp(regexp)) { flags = toString(requireObjectCoercible(getRegExpFlags(regexp))); if (!~stringIndexOf(flags, 'g')) throw new $TypeError('`.matchAll` does not allow non-global regexes'); } if (WORKS_WITH_NON_GLOBAL_REGEX) return nativeMatchAll(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 nativeMatchAll(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);