Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @fantom_flags enableOptimizedBoxShadowParsing:*
* @format
*/

Expand Down
56 changes: 9 additions & 47 deletions packages/react-native/Libraries/StyleSheet/processBoxShadow.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@
import type {ProcessedColorValue} from './processColor';
import type {BoxShadowValue} from './StyleSheetTypes';

import {enableOptimizedBoxShadowParsing} from '../../src/private/featureflags/ReactNativeFeatureFlags';
import processColor from './processColor';

// Pre-compiled regex patterns for performance - avoids regex compilation on each call
const COMMA_SPLIT_REGEX = /,(?![^()]*\))/;
const WHITESPACE_SPLIT_REGEX = /\s+(?![^(]*\))/;
const LENGTH_PARSE_REGEX = /^([+-]?\d*\.?\d+)(px)?$/;
Expand All @@ -39,12 +37,7 @@ export default function processBoxShadow(

const boxShadowList =
typeof rawBoxShadows === 'string'
? parseBoxShadowString(
rawBoxShadows.replace(
enableOptimizedBoxShadowParsing() ? NEWLINE_REGEX : /\n/g,
' ',
),
)
? parseBoxShadowString(rawBoxShadows.replace(NEWLINE_REGEX, ' '))
: rawBoxShadows;

for (const rawBoxShadow of boxShadowList) {
Expand Down Expand Up @@ -121,9 +114,7 @@ function parseBoxShadowString(rawBoxShadows: string): Array<BoxShadowValue> {
let result: Array<BoxShadowValue> = [];

for (const rawBoxShadow of rawBoxShadows
.split(
enableOptimizedBoxShadowParsing() ? COMMA_SPLIT_REGEX : /,(?![^()]*\))/,
) // split by comma that is not in parenthesis
.split(COMMA_SPLIT_REGEX)
.map(bS => bS.trim())
.filter(bS => bS !== '')) {
const boxShadow: BoxShadowValue = {
Expand All @@ -137,11 +128,7 @@ function parseBoxShadowString(rawBoxShadows: string): Array<BoxShadowValue> {
let lengthCount = 0;

// split rawBoxShadow string by all whitespaces that are not in parenthesis
const args = rawBoxShadow.split(
enableOptimizedBoxShadowParsing()
? WHITESPACE_SPLIT_REGEX
: /\s+(?![^(]*\))/,
);
const args = rawBoxShadow.split(WHITESPACE_SPLIT_REGEX);
for (const arg of args) {
const processedColor = processColor(arg);
if (processedColor != null) {
Expand Down Expand Up @@ -210,43 +197,18 @@ function parseBoxShadowString(rawBoxShadows: string): Array<BoxShadowValue> {
}

function parseLength(length: string): ?number {
if (enableOptimizedBoxShadowParsing()) {
// Use pre-compiled regex for performance
const match = LENGTH_PARSE_REGEX.exec(length);
const match = LENGTH_PARSE_REGEX.exec(length);

if (!match) {
return null;
}

const value = parseFloat(match[1]);
if (Number.isNaN(value)) {
return null;
}

// match[2] is 'px' or undefined
// If no unit and value is not 0, return null
if (match[2] == null && value !== 0) {
return null;
}

return value;
}

// matches on args with units like "1.5 5% -80deg"
const argsWithUnitsRegex = /([+-]?\d*(\.\d+)?)([\w\W]+)?/g;
const match = argsWithUnitsRegex.exec(length);

if (!match || Number.isNaN(match[1])) {
if (!match) {
return null;
}

if (match[3] != null && match[3] !== 'px') {
return null;
}
const value = parseFloat(match[1]);

if (match[3] == null && match[1] !== '0') {
// If no unit (px) and value is not 0, reject it
if (match[2] == null && value !== 0) {
return null;
}

return Number(match[1]);
return value;
}
Original file line number Diff line number Diff line change
Expand Up @@ -1054,17 +1054,6 @@ const definitions: FeatureFlagDefinitions = {
},
ossReleaseStage: 'none',
},
enableOptimizedBoxShadowParsing: {
defaultValue: false,
metadata: {
dateAdded: '2026-02-26',
description:
'Hoists regex patterns to module scope and optimizes parseLength in processBoxShadow for improved performance.',
expectedReleaseValue: true,
purpose: 'experimentation',
},
ossReleaseStage: 'none',
},
externalElementInspectionEnabled: {
defaultValue: true,
metadata: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<5966ef11ee71a38059decda1c529fd6f>>
* @generated SignedSource<<0fffffdeaf8ab7210131ac789f8b208b>>
* @flow strict
* @noformat
*/
Expand Down Expand Up @@ -33,7 +33,6 @@ export type ReactNativeFeatureFlagsJsOnly = $ReadOnly<{
animatedShouldUseSingleOp: Getter<boolean>,
deferFlatListFocusChangeRenderUpdate: Getter<boolean>,
disableMaintainVisibleContentPosition: Getter<boolean>,
enableOptimizedBoxShadowParsing: Getter<boolean>,
externalElementInspectionEnabled: Getter<boolean>,
fixImageSrcDimensionPropagation: Getter<boolean>,
fixVirtualizeListCollapseWindowSize: Getter<boolean>,
Expand Down Expand Up @@ -165,11 +164,6 @@ export const deferFlatListFocusChangeRenderUpdate: Getter<boolean> = createJavaS
*/
export const disableMaintainVisibleContentPosition: Getter<boolean> = createJavaScriptFlagGetter('disableMaintainVisibleContentPosition', false);

/**
* Hoists regex patterns to module scope and optimizes parseLength in processBoxShadow for improved performance.
*/
export const enableOptimizedBoxShadowParsing: Getter<boolean> = createJavaScriptFlagGetter('enableOptimizedBoxShadowParsing', false);

/**
* Enable the external inspection API for DevTools to communicate with the Inspector overlay.
*/
Expand Down
Loading