diff --git a/.eslintrc.js b/.eslintrc.js index bcab1b2756..53e01fe8c1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -236,7 +236,14 @@ module.exports = { 'no-inner-declarations': [ERROR, 'functions'], 'no-multi-spaces': ERROR, 'no-restricted-globals': [ERROR].concat(restrictedGlobals), - 'no-restricted-syntax': [ERROR, 'WithStatement'], + 'no-restricted-syntax': [ + ERROR, + 'WithStatement', + { + selector: 'MemberExpression[property.name=/^(?:substring|substr)$/]', + message: 'Prefer string.slice() over .substring() and .substr().', + }, + ], 'no-shadow': ERROR, 'no-unused-vars': [ERROR, {args: 'none'}], 'no-use-before-define': OFF, diff --git a/fixtures/concurrent/time-slicing/src/index.js b/fixtures/concurrent/time-slicing/src/index.js index 2b99f803f5..6a880584f0 100644 --- a/fixtures/concurrent/time-slicing/src/index.js +++ b/fixtures/concurrent/time-slicing/src/index.js @@ -22,7 +22,7 @@ class App extends PureComponent { } const multiplier = input.length !== 0 ? input.length : 1; const complexity = - (parseInt(window.location.search.substring(1), 10) / 100) * 25 || 25; + (parseInt(window.location.search.slice(1), 10) / 100) * 25 || 25; const data = _.range(5).map(t => _.range(complexity * multiplier).map((j, i) => { return { diff --git a/fixtures/dom/src/react-loader.js b/fixtures/dom/src/react-loader.js index c2f7b108ab..b2a37c49e5 100644 --- a/fixtures/dom/src/react-loader.js +++ b/fixtures/dom/src/react-loader.js @@ -11,7 +11,7 @@ import semver from 'semver'; function parseQuery(qstr) { var query = {}; - var a = qstr.substr(1).split('&'); + var a = qstr.slice(1).split('&'); for (var i = 0; i < a.length; i++) { var b = a[i].split('='); diff --git a/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js b/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js index 706613e401..a7b2abbe80 100644 --- a/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js +++ b/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js @@ -18,7 +18,7 @@ const ReactHooksESLintRule = ReactHooksESLintPlugin.rules['exhaustive-deps']; function normalizeIndent(strings) { const codeLines = strings[0].split('\n'); const leftPadding = codeLines[1].match(/\s+/)[0]; - return codeLines.map(line => line.substr(leftPadding.length)).join('\n'); + return codeLines.map(line => line.slice(leftPadding.length)).join('\n'); } // *************************************************** diff --git a/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js b/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js index aa2bcf9846..7b90afb75a 100644 --- a/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js +++ b/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js @@ -26,7 +26,7 @@ ESLintTester.setDefaultConfig({ function normalizeIndent(strings) { const codeLines = strings[0].split('\n'); const leftPadding = codeLines[1].match(/\s+/)[0]; - return codeLines.map(line => line.substr(leftPadding.length)).join('\n'); + return codeLines.map(line => line.slice(leftPadding.length)).join('\n'); } // *************************************************** diff --git a/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js b/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js index da1e3e754e..0b8b61b14f 100644 --- a/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js +++ b/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js @@ -1103,7 +1103,7 @@ export default { extraWarning = ` You can also do a functional update '${ setStateRecommendation.setter - }(${setStateRecommendation.missingDep.substring( + }(${setStateRecommendation.missingDep.slice( 0, 1, )} => ...)' if you only need '${ diff --git a/packages/react-client/src/ReactFlightClient.js b/packages/react-client/src/ReactFlightClient.js index 85b20a4c1f..ec1e5d34e7 100644 --- a/packages/react-client/src/ReactFlightClient.js +++ b/packages/react-client/src/ReactFlightClient.js @@ -515,11 +515,11 @@ export function parseModelString( switch (value[1]) { case '$': { // This was an escaped string value. - return value.substring(1); + return value.slice(1); } case 'L': { // Lazy node - const id = parseInt(value.substring(2), 16); + const id = parseInt(value.slice(2), 16); const chunk = getChunk(response, id); // We create a React.lazy wrapper around any lazy values. // When passed into React, we'll know how to suspend on this. @@ -527,21 +527,21 @@ export function parseModelString( } case '@': { // Promise - const id = parseInt(value.substring(2), 16); + const id = parseInt(value.slice(2), 16); const chunk = getChunk(response, id); return chunk; } case 'S': { // Symbol - return Symbol.for(value.substring(2)); + return Symbol.for(value.slice(2)); } case 'P': { // Server Context Provider - return getOrCreateServerContext(value.substring(2)).Provider; + return getOrCreateServerContext(value.slice(2)).Provider; } case 'F': { // Server Reference - const id = parseInt(value.substring(2), 16); + const id = parseInt(value.slice(2), 16); const chunk = getChunk(response, id); switch (chunk.status) { case RESOLVED_MODEL: @@ -582,15 +582,15 @@ export function parseModelString( } case 'D': { // Date - return new Date(Date.parse(value.substring(2))); + return new Date(Date.parse(value.slice(2))); } case 'n': { // BigInt - return BigInt(value.substring(2)); + return BigInt(value.slice(2)); } default: { // We assume that anything else is a reference ID. - const id = parseInt(value.substring(1), 16); + const id = parseInt(value.slice(1), 16); const chunk = getChunk(response, id); switch (chunk.status) { case RESOLVED_MODEL: diff --git a/packages/react-client/src/ReactFlightClientStream.js b/packages/react-client/src/ReactFlightClientStream.js index 81633e6966..d261da8b88 100644 --- a/packages/react-client/src/ReactFlightClientStream.js +++ b/packages/react-client/src/ReactFlightClientStream.js @@ -35,7 +35,7 @@ function processFullRow(response: Response, row: string): void { return; } const colon = row.indexOf(':', 0); - const id = parseInt(row.substring(0, colon), 16); + const id = parseInt(row.slice(0, colon), 16); const tag = row[colon + 1]; // When tags that are not text are added, check them here before // parsing the row as text. @@ -43,11 +43,11 @@ function processFullRow(response: Response, row: string): void { // } switch (tag) { case 'I': { - resolveModule(response, id, row.substring(colon + 2)); + resolveModule(response, id, row.slice(colon + 2)); return; } case 'E': { - const errorInfo = JSON.parse(row.substring(colon + 2)); + const errorInfo = JSON.parse(row.slice(colon + 2)); if (__DEV__) { resolveErrorDev( response, @@ -63,7 +63,7 @@ function processFullRow(response: Response, row: string): void { } default: { // We assume anything else is JSON. - resolveModel(response, id, row.substring(colon + 1)); + resolveModel(response, id, row.slice(colon + 1)); return; } } @@ -76,13 +76,13 @@ export function processStringChunk( ): void { let linebreak = chunk.indexOf('\n', offset); while (linebreak > -1) { - const fullrow = response._partialRow + chunk.substring(offset, linebreak); + const fullrow = response._partialRow + chunk.slice(offset, linebreak); processFullRow(response, fullrow); response._partialRow = ''; offset = linebreak + 1; linebreak = chunk.indexOf('\n', offset); } - response._partialRow += chunk.substring(offset); + response._partialRow += chunk.slice(offset); } export function processBinaryChunk( diff --git a/packages/react-debug-tools/src/ReactDebugHooks.js b/packages/react-debug-tools/src/ReactDebugHooks.js index 44d99922df..bed4c2fead 100644 --- a/packages/react-debug-tools/src/ReactDebugHooks.js +++ b/packages/react-debug-tools/src/ReactDebugHooks.js @@ -513,10 +513,10 @@ function parseCustomHookName(functionName: void | string): string { if (startIndex === -1) { startIndex = 0; } - if (functionName.substr(startIndex, 3) === 'use') { + if (functionName.slice(startIndex, startIndex + 3) === 'use') { startIndex += 3; } - return functionName.substr(startIndex); + return functionName.slice(startIndex); } function buildTree( diff --git a/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js b/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js index b026f7edb2..5e4860ce70 100644 --- a/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js +++ b/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js @@ -869,7 +869,7 @@ describe('ReactHooksInspectionIntegration', () => { const Suspense = React.Suspense; function Foo(props) { - const [value] = React.useState(props.defaultValue.substr(0, 3)); + const [value] = React.useState(props.defaultValue.slice(0, 3)); return
{value}
; } Foo.defaultProps = { diff --git a/packages/react-devtools-extensions/deploy.js b/packages/react-devtools-extensions/deploy.js index f177240909..37d06e4817 100644 --- a/packages/react-devtools-extensions/deploy.js +++ b/packages/react-devtools-extensions/deploy.js @@ -27,7 +27,7 @@ const main = async buildId => { const json = JSON.parse(file); const alias = json.alias[0]; - const commit = execSync('git rev-parse HEAD').toString().trim().substr(0, 7); + const commit = execSync('git rev-parse HEAD').toString().trim().slice(0, 7); let date = new Date(); date = `${date.toLocaleDateString()} – ${date.toLocaleTimeString()}`; diff --git a/packages/react-devtools-shared/src/__tests__/__serializers__/hookSerializer.js b/packages/react-devtools-shared/src/__tests__/__serializers__/hookSerializer.js index 2bf84086ed..20a5425b1a 100644 --- a/packages/react-devtools-shared/src/__tests__/__serializers__/hookSerializer.js +++ b/packages/react-devtools-shared/src/__tests__/__serializers__/hookSerializer.js @@ -13,7 +13,7 @@ function serializeHook(hook) { // Remove user-specific portions of this file path. let fileName = hook.hookSource.fileName; const index = fileName.lastIndexOf('/react-devtools-shared/'); - fileName = fileName.substring(index + 1); + fileName = fileName.slice(index + 1); let subHooks = hook.subHooks; if (subHooks) { diff --git a/packages/react-devtools-shared/src/backend/renderer.js b/packages/react-devtools-shared/src/backend/renderer.js index bf165bf8a3..7b12e583a9 100644 --- a/packages/react-devtools-shared/src/backend/renderer.js +++ b/packages/react-devtools-shared/src/backend/renderer.js @@ -4315,7 +4315,7 @@ export function attach( if (pseudoKey === undefined) { throw new Error('Expected root pseudo key to be known.'); } - const name = pseudoKey.substring(0, pseudoKey.lastIndexOf(':')); + const name = pseudoKey.slice(0, pseudoKey.lastIndexOf(':')); const counter = rootDisplayNameCounter.get(name); if (counter === undefined) { throw new Error('Expected counter to be known.'); diff --git a/packages/react-devtools-shared/src/devtools/utils.js b/packages/react-devtools-shared/src/devtools/utils.js index d1aa778d19..6a6fb08f7e 100644 --- a/packages/react-devtools-shared/src/devtools/utils.js +++ b/packages/react-devtools-shared/src/devtools/utils.js @@ -155,7 +155,7 @@ export function sanitizeForParse(value: any): any | string { value.charAt(0) === "'" && value.charAt(value.length - 1) === "'" ) { - return '"' + value.substr(1, value.length - 2) + '"'; + return '"' + value.slice(1, value.length - 1) + '"'; } } return value; diff --git a/packages/react-devtools-shared/src/devtools/views/utils.js b/packages/react-devtools-shared/src/devtools/views/utils.js index 9634f14556..7b7ac10e13 100644 --- a/packages/react-devtools-shared/src/devtools/views/utils.js +++ b/packages/react-devtools-shared/src/devtools/views/utils.js @@ -36,10 +36,10 @@ export function createRegExp(string: string): RegExp { // Allow /regex/ syntax with optional last / if (string[0] === '/') { // Cut off first slash - string = string.substring(1); + string = string.slice(1); // Cut off last slash, but only if it's there if (string[string.length - 1] === '/') { - string = string.substring(0, string.length - 1); + string = string.slice(0, string.length - 1); } try { return new RegExp(string, 'i'); @@ -186,9 +186,9 @@ export function truncateText(text: string, maxLength: number): string { const {length} = text; if (length > maxLength) { return ( - text.substr(0, Math.floor(maxLength / 2)) + + text.slice(0, Math.floor(maxLength / 2)) + '…' + - text.substr(length - Math.ceil(maxLength / 2) - 1) + text.slice(length - Math.ceil(maxLength / 2) - 1) ); } else { return text; diff --git a/packages/react-devtools-shared/src/utils.js b/packages/react-devtools-shared/src/utils.js index 5d6a9f3b60..bf2b7852f1 100644 --- a/packages/react-devtools-shared/src/utils.js +++ b/packages/react-devtools-shared/src/utils.js @@ -693,7 +693,7 @@ function truncateForDisplay( length: number = MAX_PREVIEW_STRING_LENGTH, ) { if (string.length > length) { - return string.substr(0, length) + '…'; + return string.slice(0, length) + '…'; } else { return string; } diff --git a/packages/react-devtools-timeline/src/EventTooltip.js b/packages/react-devtools-timeline/src/EventTooltip.js index ba3685f646..3d3698c09f 100644 --- a/packages/react-devtools-timeline/src/EventTooltip.js +++ b/packages/react-devtools-timeline/src/EventTooltip.js @@ -249,7 +249,7 @@ const TooltipNetworkMeasure = ({ let urlToDisplay = url; if (urlToDisplay.length > MAX_TOOLTIP_TEXT_LENGTH) { const half = Math.floor(MAX_TOOLTIP_TEXT_LENGTH / 2); - urlToDisplay = url.substr(0, half) + '…' + url.substr(url.length - half); + urlToDisplay = url.slice(0, half) + '…' + url.slice(url.length - half); } const timestampBegin = sendRequestTimestamp; diff --git a/packages/react-devtools-timeline/src/content-views/utils/text.js b/packages/react-devtools-timeline/src/content-views/utils/text.js index 2305975153..000a41cb0c 100644 --- a/packages/react-devtools-timeline/src/content-views/utils/text.js +++ b/packages/react-devtools-timeline/src/content-views/utils/text.js @@ -45,7 +45,7 @@ export function trimText( while (startIndex <= stopIndex) { const currentIndex = Math.floor((startIndex + stopIndex) / 2); const trimmedText = - currentIndex === maxIndex ? text : text.substr(0, currentIndex) + '…'; + currentIndex === maxIndex ? text : text.slice(0, currentIndex) + '…'; if (getTextWidth(context, trimmedText) <= width) { if (longestValidIndex < currentIndex) { diff --git a/packages/react-devtools-timeline/src/import-worker/preprocessData.js b/packages/react-devtools-timeline/src/import-worker/preprocessData.js index 82b6a37129..d6fe8faa6e 100644 --- a/packages/react-devtools-timeline/src/import-worker/preprocessData.js +++ b/packages/react-devtools-timeline/src/import-worker/preprocessData.js @@ -476,10 +476,10 @@ function processTimelineEvent( break; case 'blink.user_timing': if (name.startsWith('--react-version-')) { - const [reactVersion] = name.substr(16).split('-'); + const [reactVersion] = name.slice(16).split('-'); currentProfilerData.reactVersion = reactVersion; } else if (name.startsWith('--profiler-version-')) { - const [versionString] = name.substr(19).split('-'); + const [versionString] = name.slice(19).split('-'); profilerVersion = parseInt(versionString, 10); if (profilerVersion !== SCHEDULING_PROFILER_VERSION) { throw new InvalidProfileError( @@ -487,7 +487,7 @@ function processTimelineEvent( ); } } else if (name.startsWith('--react-lane-labels-')) { - const [laneLabelTuplesString] = name.substr(20).split('-'); + const [laneLabelTuplesString] = name.slice(20).split('-'); updateLaneToLabelMap(currentProfilerData, laneLabelTuplesString); } else if (name.startsWith('--component-')) { processReactComponentMeasure( @@ -497,7 +497,7 @@ function processTimelineEvent( state, ); } else if (name.startsWith('--schedule-render-')) { - const [laneBitmaskString] = name.substr(18).split('-'); + const [laneBitmaskString] = name.slice(18).split('-'); currentProfilerData.schedulingEvents.push({ type: 'schedule-render', @@ -506,7 +506,7 @@ function processTimelineEvent( warning: null, }); } else if (name.startsWith('--schedule-forced-update-')) { - const [laneBitmaskString, componentName] = name.substr(25).split('-'); + const [laneBitmaskString, componentName] = name.slice(25).split('-'); const forceUpdateEvent = { type: 'schedule-force-update', @@ -524,7 +524,7 @@ function processTimelineEvent( currentProfilerData.schedulingEvents.push(forceUpdateEvent); } else if (name.startsWith('--schedule-state-update-')) { - const [laneBitmaskString, componentName] = name.substr(24).split('-'); + const [laneBitmaskString, componentName] = name.slice(24).split('-'); const stateUpdateEvent = { type: 'schedule-state-update', @@ -542,7 +542,7 @@ function processTimelineEvent( currentProfilerData.schedulingEvents.push(stateUpdateEvent); } else if (name.startsWith('--error-')) { - const [componentName, phase, message] = name.substr(8).split('-'); + const [componentName, phase, message] = name.slice(8).split('-'); currentProfilerData.thrownErrors.push({ componentName, @@ -553,7 +553,7 @@ function processTimelineEvent( }); } else if (name.startsWith('--suspense-suspend-')) { const [id, componentName, phase, laneBitmaskString, promiseName] = name - .substr(19) + .slice(19) .split('-'); const lanes = getLanesFromTransportDecimalBitmask(laneBitmaskString); @@ -604,7 +604,7 @@ function processTimelineEvent( currentProfilerData.suspenseEvents.push(suspenseEvent); state.unresolvedSuspenseEvents.set(id, suspenseEvent); } else if (name.startsWith('--suspense-resolved-')) { - const [id] = name.substr(20).split('-'); + const [id] = name.slice(20).split('-'); const suspenseEvent = state.unresolvedSuspenseEvents.get(id); if (suspenseEvent != null) { state.unresolvedSuspenseEvents.delete(id); @@ -613,7 +613,7 @@ function processTimelineEvent( suspenseEvent.resolution = 'resolved'; } } else if (name.startsWith('--suspense-rejected-')) { - const [id] = name.substr(20).split('-'); + const [id] = name.slice(20).split('-'); const suspenseEvent = state.unresolvedSuspenseEvents.get(id); if (suspenseEvent != null) { state.unresolvedSuspenseEvents.delete(id); @@ -637,7 +637,7 @@ function processTimelineEvent( state.potentialLongNestedUpdate = null; } - const [laneBitmaskString] = name.substr(15).split('-'); + const [laneBitmaskString] = name.slice(15).split('-'); throwIfIncomplete('render', state.measureStack); if (getLastType(state.measureStack) !== 'render-idle') { @@ -682,7 +682,7 @@ function processTimelineEvent( ); } else if (name.startsWith('--commit-start-')) { state.nextRenderShouldGenerateNewBatchID = true; - const [laneBitmaskString] = name.substr(15).split('-'); + const [laneBitmaskString] = name.slice(15).split('-'); markWorkStarted( 'commit', @@ -705,7 +705,7 @@ function processTimelineEvent( state.measureStack, ); } else if (name.startsWith('--layout-effects-start-')) { - const [laneBitmaskString] = name.substr(23).split('-'); + const [laneBitmaskString] = name.slice(23).split('-'); markWorkStarted( 'layout-effects', @@ -722,7 +722,7 @@ function processTimelineEvent( state.measureStack, ); } else if (name.startsWith('--passive-effects-start-')) { - const [laneBitmaskString] = name.substr(24).split('-'); + const [laneBitmaskString] = name.slice(24).split('-'); markWorkStarted( 'passive-effects', @@ -739,7 +739,7 @@ function processTimelineEvent( state.measureStack, ); } else if (name.startsWith('--react-internal-module-start-')) { - const stackFrameStart = name.substr(30); + const stackFrameStart = name.slice(30); if (!state.internalModuleStackStringSet.has(stackFrameStart)) { state.internalModuleStackStringSet.add(stackFrameStart); @@ -749,7 +749,7 @@ function processTimelineEvent( state.internalModuleCurrentStackFrame = parsedStackFrameStart; } } else if (name.startsWith('--react-internal-module-stop-')) { - const stackFrameStop = name.substr(29); + const stackFrameStop = name.slice(29); if (!state.internalModuleStackStringSet.has(stackFrameStop)) { state.internalModuleStackStringSet.add(stackFrameStop); @@ -833,7 +833,7 @@ function processReactComponentMeasure( state: ProcessorState, ): void { if (name.startsWith('--component-render-start-')) { - const [componentName] = name.substr(25).split('-'); + const [componentName] = name.slice(25).split('-'); assertNoOverlappingComponentMeasure(state); @@ -856,7 +856,7 @@ function processReactComponentMeasure( currentProfilerData.componentMeasures.push(componentMeasure); } } else if (name.startsWith('--component-layout-effect-mount-start-')) { - const [componentName] = name.substr(38).split('-'); + const [componentName] = name.slice(38).split('-'); assertNoOverlappingComponentMeasure(state); @@ -879,7 +879,7 @@ function processReactComponentMeasure( currentProfilerData.componentMeasures.push(componentMeasure); } } else if (name.startsWith('--component-layout-effect-unmount-start-')) { - const [componentName] = name.substr(40).split('-'); + const [componentName] = name.slice(40).split('-'); assertNoOverlappingComponentMeasure(state); @@ -902,7 +902,7 @@ function processReactComponentMeasure( currentProfilerData.componentMeasures.push(componentMeasure); } } else if (name.startsWith('--component-passive-effect-mount-start-')) { - const [componentName] = name.substr(39).split('-'); + const [componentName] = name.slice(39).split('-'); assertNoOverlappingComponentMeasure(state); @@ -925,7 +925,7 @@ function processReactComponentMeasure( currentProfilerData.componentMeasures.push(componentMeasure); } } else if (name.startsWith('--component-passive-effect-unmount-start-')) { - const [componentName] = name.substr(41).split('-'); + const [componentName] = name.slice(41).split('-'); assertNoOverlappingComponentMeasure(state); diff --git a/packages/react-devtools-timeline/src/utils/formatting.js b/packages/react-devtools-timeline/src/utils/formatting.js index 59aadc8c0a..725197b138 100644 --- a/packages/react-devtools-timeline/src/utils/formatting.js +++ b/packages/react-devtools-timeline/src/utils/formatting.js @@ -26,7 +26,7 @@ export function formatDuration(ms: number): string { export function trimString(string: string, length: number): string { if (string.length > length) { - return `${string.substr(0, length - 1)}…`; + return `${string.slice(0, length - 1)}…`; } return string; } diff --git a/packages/react-dom-bindings/src/client/DOMPropertyOperations.js b/packages/react-dom-bindings/src/client/DOMPropertyOperations.js index ac311c72e0..ad14b6498c 100644 --- a/packages/react-dom-bindings/src/client/DOMPropertyOperations.js +++ b/packages/react-dom-bindings/src/client/DOMPropertyOperations.js @@ -203,7 +203,7 @@ export function setValueForPropertyOnCustomComponent( ) { if (name[0] === 'o' && name[1] === 'n') { const useCapture = name.endsWith('Capture'); - const eventName = name.substr(2, useCapture ? name.length - 9 : undefined); + const eventName = name.slice(2, useCapture ? name.length - 7 : undefined); const prevProps = getFiberCurrentPropsFromNode(node); const prevValue = prevProps != null ? prevProps[name] : null; diff --git a/packages/react-dom-bindings/src/server/escapeTextForBrowser.js b/packages/react-dom-bindings/src/server/escapeTextForBrowser.js index bccad86820..842d1b1328 100644 --- a/packages/react-dom-bindings/src/server/escapeTextForBrowser.js +++ b/packages/react-dom-bindings/src/server/escapeTextForBrowser.js @@ -88,14 +88,14 @@ function escapeHtml(string: string) { } if (lastIndex !== index) { - html += str.substring(lastIndex, index); + html += str.slice(lastIndex, index); } lastIndex = index + 1; html += escape; } - return lastIndex !== index ? html + str.substring(lastIndex, index) : html; + return lastIndex !== index ? html + str.slice(lastIndex, index) : html; } // end code copied and modified from escape-html diff --git a/packages/react-reconciler/src/__tests__/ReactNewContext-test.js b/packages/react-reconciler/src/__tests__/ReactNewContext-test.js index 7f8520088d..b6be6309e0 100644 --- a/packages/react-reconciler/src/__tests__/ReactNewContext-test.js +++ b/packages/react-reconciler/src/__tests__/ReactNewContext-test.js @@ -1635,7 +1635,7 @@ describe('ReactNewContext', () => { const LIMIT = 100; for (let i = 0; i < LIMIT; i++) { - const seed = Math.random().toString(36).substr(2, 5); + const seed = Math.random().toString(36).slice(2, 7); const actions = randomActions(5); try { simulate(seed, actions); diff --git a/packages/react-server-dom-webpack/src/ReactFlightClientConfigNodeBundler.js b/packages/react-server-dom-webpack/src/ReactFlightClientConfigNodeBundler.js index 7fc449fd68..e34299680a 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightClientConfigNodeBundler.js +++ b/packages/react-server-dom-webpack/src/ReactFlightClientConfigNodeBundler.js @@ -69,8 +69,8 @@ export function resolveServerReference( id: ServerReferenceId, ): ClientReference { const idx = id.lastIndexOf('#'); - const specifier = id.substr(0, idx); - const name = id.substr(idx + 1); + const specifier = id.slice(0, idx); + const name = id.slice(idx + 1); return {specifier, name}; } diff --git a/packages/react-server-dom-webpack/src/ReactFlightClientConfigWebpackBundler.js b/packages/react-server-dom-webpack/src/ReactFlightClientConfigWebpackBundler.js index 1c739c88b1..853a5db74d 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightClientConfigWebpackBundler.js +++ b/packages/react-server-dom-webpack/src/ReactFlightClientConfigWebpackBundler.js @@ -85,8 +85,8 @@ export function resolveServerReference( // probably go back to encoding path and name separately on the client reference. const idx = id.lastIndexOf('#'); if (idx !== -1) { - name = id.substr(idx + 1); - resolvedModuleData = bundlerConfig[id.substr(0, idx)]; + name = id.slice(idx + 1); + resolvedModuleData = bundlerConfig[id.slice(0, idx)]; } if (!resolvedModuleData) { throw new Error( diff --git a/packages/react-server-dom-webpack/src/ReactFlightServerConfigWebpackBundler.js b/packages/react-server-dom-webpack/src/ReactFlightServerConfigWebpackBundler.js index 49c1b2c1b7..a24583c315 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightServerConfigWebpackBundler.js +++ b/packages/react-server-dom-webpack/src/ReactFlightServerConfigWebpackBundler.js @@ -71,8 +71,8 @@ export function resolveClientReferenceMetadata( // probably go back to encoding path and name separately on the client reference. const idx = modulePath.lastIndexOf('#'); if (idx !== -1) { - name = modulePath.substr(idx + 1); - resolvedModuleData = config[modulePath.substr(0, idx)]; + name = modulePath.slice(idx + 1); + resolvedModuleData = config[modulePath.slice(0, idx)]; } if (!resolvedModuleData) { throw new Error( diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js index 55c55e19f8..2847801d94 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js @@ -87,8 +87,8 @@ describe('ReactFlightDOMBrowser', () => { // probably go back to encoding path and name separately on the client reference. const idx = ref.lastIndexOf('#'); if (idx !== -1) { - name = ref.substr(idx + 1); - resolvedModuleData = webpackServerMap[ref.substr(0, idx)]; + name = ref.slice(idx + 1); + resolvedModuleData = webpackServerMap[ref.slice(0, idx)]; } if (!resolvedModuleData) { throw new Error( diff --git a/packages/react-server/src/ReactFlightReplyServer.js b/packages/react-server/src/ReactFlightReplyServer.js index 4ba9b8785f..88b846f283 100644 --- a/packages/react-server/src/ReactFlightReplyServer.js +++ b/packages/react-server/src/ReactFlightReplyServer.js @@ -374,21 +374,21 @@ function parseModelString( switch (value[1]) { case '$': { // This was an escaped string value. - return value.substring(1); + return value.slice(1); } case '@': { // Promise - const id = parseInt(value.substring(2), 16); + const id = parseInt(value.slice(2), 16); const chunk = getChunk(response, id); return chunk; } case 'S': { // Symbol - return Symbol.for(value.substring(2)); + return Symbol.for(value.slice(2)); } case 'F': { // Server Reference - const id = parseInt(value.substring(2), 16); + const id = parseInt(value.slice(2), 16); const chunk = getChunk(response, id); if (chunk.status === RESOLVED_MODEL) { initializeModelChunk(chunk); @@ -411,7 +411,7 @@ function parseModelString( } case 'K': { // FormData - const stringId = value.substring(2); + const stringId = value.slice(2); const formPrefix = response._prefix + stringId + '_'; const data = new FormData(); const backingFormData = response._formData; @@ -421,7 +421,7 @@ function parseModelString( // $FlowFixMe[prop-missing] FormData has forEach on it. backingFormData.forEach((entry: File | string, entryKey: string) => { if (entryKey.startsWith(formPrefix)) { - data.append(entryKey.substr(formPrefix.length), entry); + data.append(entryKey.slice(formPrefix.length), entry); } }); return data; @@ -449,15 +449,15 @@ function parseModelString( } case 'D': { // Date - return new Date(Date.parse(value.substring(2))); + return new Date(Date.parse(value.slice(2))); } case 'n': { // BigInt - return BigInt(value.substring(2)); + return BigInt(value.slice(2)); } default: { // We assume that anything else is a reference ID. - const id = parseInt(value.substring(1), 16); + const id = parseInt(value.slice(1), 16); const chunk = getChunk(response, id); switch (chunk.status) { case RESOLVED_MODEL: @@ -517,7 +517,7 @@ export function resolveField( const prefix = response._prefix; if (key.startsWith(prefix)) { const chunks = response._chunks; - const id = +key.substr(prefix.length); + const id = +key.slice(prefix.length); const chunk = chunks.get(id); if (chunk) { // We were waiting on this key so now we can resolve it. diff --git a/packages/shared/ReactSerializationErrors.js b/packages/shared/ReactSerializationErrors.js index 4e9627ca92..e7ccc3638a 100644 --- a/packages/shared/ReactSerializationErrors.js +++ b/packages/shared/ReactSerializationErrors.js @@ -90,7 +90,7 @@ export function describeValueForErrorMessage(value: mixed): string { switch (typeof value) { case 'string': { return JSON.stringify( - value.length <= 10 ? value : value.substr(0, 10) + '...', + value.length <= 10 ? value : value.slice(0, 10) + '...', ); } case 'object': { diff --git a/scripts/babel/transform-test-gate-pragma.js b/scripts/babel/transform-test-gate-pragma.js index bdef629812..bc83487604 100644 --- a/scripts/babel/transform-test-gate-pragma.js +++ b/scripts/babel/transform-test-gate-pragma.js @@ -74,7 +74,7 @@ function transform(babel) { continue; } - const next3 = code.substring(i, i + 3); + const next3 = code.slice(i, i + 3); if (next3 === '===') { tokens.push({type: '=='}); i += 3; @@ -86,7 +86,7 @@ function transform(babel) { continue; } - const next2 = code.substring(i, i + 2); + const next2 = code.slice(i, i + 2); switch (next2) { case '&&': case '||': diff --git a/scripts/jest/setupHostConfigs.js b/scripts/jest/setupHostConfigs.js index 2ed0fe91a8..85fe96cd2a 100644 --- a/scripts/jest/setupHostConfigs.js +++ b/scripts/jest/setupHostConfigs.js @@ -116,7 +116,7 @@ function mockAllConfigs(rendererInfo) { // We want the reconciler to pick up the host config for this renderer. jest.mock(path, () => { let idx = path.lastIndexOf('/'); - let forkPath = path.substr(0, idx) + '/forks' + path.substr(idx); + let forkPath = path.slice(0, idx) + '/forks' + path.slice(idx); return jest.requireActual(`${forkPath}.${rendererInfo.shortName}.js`); }); }); diff --git a/scripts/jest/setupTests.js b/scripts/jest/setupTests.js index 159e8565a6..ddd1c2a032 100644 --- a/scripts/jest/setupTests.js +++ b/scripts/jest/setupTests.js @@ -76,7 +76,7 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) { // Don't throw yet though b'c it might be accidentally caught and suppressed. const stack = new Error().stack; unexpectedConsoleCallStacks.push([ - stack.substr(stack.indexOf('\n') + 1), + stack.slice(stack.indexOf('\n') + 1), util.format(format, ...args), ]); }; @@ -178,7 +178,7 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) { const args = matches[2] .split('&') .filter(s => s.startsWith('args[]=')) - .map(s => s.substr('args[]='.length)) + .map(s => s.slice('args[]='.length)) .map(decodeURIComponent); const format = errorMap[code]; let argIndex = 0; diff --git a/scripts/release/utils.js b/scripts/release/utils.js index efee7b25bc..2066ac2fe3 100644 --- a/scripts/release/utils.js +++ b/scripts/release/utils.js @@ -118,7 +118,7 @@ const getDateStringForCommit = async commit => { // On CI environment, this string is wrapped with quotes '...'s if (dateString.startsWith("'")) { - dateString = dateString.substr(1, 8); + dateString = dateString.slice(1, 9); } return dateString; diff --git a/scripts/rollup/build-all-release-channels.js b/scripts/rollup/build-all-release-channels.js index 957bfb842c..238d9b5a7f 100644 --- a/scripts/rollup/build-all-release-channels.js +++ b/scripts/rollup/build-all-release-channels.js @@ -36,7 +36,7 @@ let dateString = String( // On CI environment, this string is wrapped with quotes '...'s if (dateString.startsWith("'")) { - dateString = dateString.substr(1, 8); + dateString = dateString.slice(1, 9); } // Build the artifacts using a placeholder React version. We'll then do a string @@ -173,7 +173,7 @@ function processStable(buildDir) { } updatePlaceholderReactVersionInCompiledArtifacts( buildDir + '/facebook-www', - ReactVersion + '-www-classic-' + hash.digest('hex').substr(0, 8) + ReactVersion + '-www-classic-' + hash.digest('hex').slice(0, 8) ); } @@ -227,7 +227,7 @@ function processExperimental(buildDir, version) { } updatePlaceholderReactVersionInCompiledArtifacts( buildDir + '/facebook-www', - ReactVersion + '-www-modern-' + hash.digest('hex').substr(0, 8) + ReactVersion + '-www-modern-' + hash.digest('hex').slice(0, 8) ); } diff --git a/scripts/rollup/packaging.js b/scripts/rollup/packaging.js index 442ca962c7..b49472c1be 100644 --- a/scripts/rollup/packaging.js +++ b/scripts/rollup/packaging.js @@ -172,7 +172,7 @@ function getTarOptions(tgzName, packageName) { entries: [CONTENTS_FOLDER], map(header) { if (header.name.indexOf(CONTENTS_FOLDER + '/') === 0) { - header.name = header.name.substring(CONTENTS_FOLDER.length + 1); + header.name = header.name.slice(CONTENTS_FOLDER.length + 1); } }, },