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);
}
},
},