mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Summary: Resolves https://github.com/facebook/react-native/issues/50778 ### Problem Description Implement the crossOrigin property for Image in RNW Fabric when only source.uri is passed and not src/ srcSet. For reference, check the public API documentation: https://reactnative.dev/docs/image#crossorigin Implement the referrerPolicy property for Image in RNW Fabric when only source.uri is passed and not src/ srcSet. For reference, check the public API documentation: https://reactnative.dev/docs/image#referrerpolicy Also refer docs for source, src, srcSet https://reactnative.dev/docs/image#source https://reactnative.dev/docs/image#src https://reactnative.dev/docs/image#srcset It's not mentioned in the doc that when src / srcSet is missing then crossOrigin / referralPolicy would be ignored when source uri is a remote URL that is passed. Currently these were ignored if src / srcSet was not passed and not added to sources headers. This change adds headers support even without passing src / srcSet and only sources uri that consists of remote URL. crossOrigin and referrerPolicy are passed as source.headers here:  ### Steps to reproduce ``` <Image defaultSource={{uri: this.state.defaultImageUri}} source={{uri: this.state.imageUri}} crossOrigin="use-credentials" referrerPolicy="no-referrer" /> ``` Pass this in React Native and check source headers ## Changelog: [GENERAL] [ADDED] - Support headers [crossOrigin and referralPolicy] in Image without src and srcSet and only remote source.uri Pull Request resolved: https://github.com/facebook/react-native/pull/50799 Test Plan: Refer this PR for testing; https://github.com/microsoft/react-native-windows/pull/14521 ## Screenshots _Add any relevant screen captures here from before or after your changes._ Before  After <img width="790" alt="image" src="https://github.com/user-attachments/assets/8e0a2522-7009-430d-b848-da80896670f4" /> ## Testing _If you added tests that prove your changes are effective or that your feature works, add a few sentences here detailing the added test scenarios._ Tested in playground and RNW Tester and Visual Studio Debugger _Optional_: Describe the tests that you ran locally to verify your changes. 1. Tested with only source remote uri passed 2. Tested with both source, src 3. Tested with source, src, srcSet Reviewed By: javache Differential Revision: D73427747 Pulled By: cipolleschi fbshipit-source-id: f09174d1e4eaa2173b27970a6079eeb8ba6f3069
83 lines
2.5 KiB
JavaScript
83 lines
2.5 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow strict-local
|
|
* @format
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
import type {ResolvedAssetSource} from './AssetSourceResolver';
|
|
import type {ImageProps} from './ImageProps';
|
|
|
|
import resolveAssetSource from './resolveAssetSource';
|
|
|
|
/**
|
|
* A function which returns the appropriate value for image source
|
|
* by resolving the `source`, `src` and `srcSet` props.
|
|
*/
|
|
export function getImageSourcesFromImageProps(
|
|
imageProps: ImageProps,
|
|
): ?ResolvedAssetSource | $ReadOnlyArray<{uri: string, ...}> {
|
|
let source = resolveAssetSource(imageProps.source);
|
|
|
|
let sources;
|
|
|
|
const {crossOrigin, referrerPolicy, src, srcSet, width, height} = imageProps;
|
|
|
|
const headers: {[string]: string} = {};
|
|
if (crossOrigin === 'use-credentials') {
|
|
headers['Access-Control-Allow-Credentials'] = 'true';
|
|
}
|
|
if (referrerPolicy != null) {
|
|
headers['Referrer-Policy'] = referrerPolicy;
|
|
}
|
|
if (srcSet != null) {
|
|
const sourceList = [];
|
|
const srcSetList = srcSet.split(', ');
|
|
// `src` prop should be used with default scale if `srcSet` does not have 1x scale.
|
|
let shouldUseSrcForDefaultScale = true;
|
|
srcSetList.forEach(imageSrc => {
|
|
const [uri, xScale = '1x'] = imageSrc.split(' ');
|
|
if (!xScale.endsWith('x')) {
|
|
console.warn(
|
|
'The provided format for scale is not supported yet. Please use scales like 1x, 2x, etc.',
|
|
);
|
|
} else {
|
|
const scale = parseInt(xScale.split('x')[0], 10);
|
|
if (!isNaN(scale)) {
|
|
// 1x scale is provided in `srcSet` prop so ignore the `src` prop if provided.
|
|
shouldUseSrcForDefaultScale =
|
|
scale === 1 ? false : shouldUseSrcForDefaultScale;
|
|
sourceList.push({headers, scale, uri, width, height});
|
|
}
|
|
}
|
|
});
|
|
|
|
if (shouldUseSrcForDefaultScale && src != null) {
|
|
sourceList.push({
|
|
headers,
|
|
scale: 1,
|
|
uri: src,
|
|
width,
|
|
height,
|
|
});
|
|
}
|
|
if (sourceList.length === 0) {
|
|
console.warn('The provided value for srcSet is not valid.');
|
|
}
|
|
|
|
sources = sourceList;
|
|
} else if (src != null) {
|
|
sources = [{uri: src, headers: headers, width, height}];
|
|
} else if (source != null && source.uri && Object.keys(headers).length > 0) {
|
|
sources = [{...source, headers}];
|
|
} else {
|
|
sources = source;
|
|
}
|
|
return sources;
|
|
}
|