@native-html/iframe-plugin
Version:
🌐 A WebView-based plugin to render iframes in react-native-render-html
102 lines (97 loc) • 3.11 kB
text/typescript
import { Dimensions } from 'react-native';
import {
CustomRendererProps,
useDocumentMetadata,
useSharedProps,
useNormalizedUrl,
useRendererProps,
useContentWidth
} from 'react-native-render-html';
import extractPrintDimensions, {
ExtractPrintDimensionsParams
} from './extractPrintDimensions';
import { IframeConfig, HTMLIframeProps } from './HTMLIframe';
import type { TBlock } from '@native-html/transient-render-engine';
const defaultIframeConfig: IframeConfig = {
webViewProps: {
allowsFullscreenVideo: true
}
};
/**
* Extract props for the HTMLIframe component from renderer function arguments.
* This function is especially usefull for custom iframe renderers.
*
* @param props - The props of a custom block renderer.
* @param iframeConfig - Override config options.
*
* @public
*/
export default function useHtmlIframeProps(
{ style, tnode }: CustomRendererProps<TBlock>,
iframeConfig?: IframeConfig
): HTMLIframeProps {
const {
WebView,
defaultWebViewProps,
computeEmbeddedMaxWidth,
provideEmbeddedHeaders
} = useSharedProps();
const contentWidth = useContentWidth();
const globalIframeConfig = useRendererProps('iframe');
const { onPress: onLinkPress } = useRendererProps('a');
const resolvedConfig = {
...defaultIframeConfig,
...globalIframeConfig,
...iframeConfig,
webViewProps: {
...defaultWebViewProps,
...defaultIframeConfig.webViewProps,
...globalIframeConfig?.webViewProps,
...iframeConfig?.webViewProps
}
};
const resolvedContentWidth =
typeof contentWidth === 'number'
? contentWidth
: Dimensions.get('window').width;
const documentBaseUrl = useDocumentMetadata().baseUrl;
const availableWidth =
computeEmbeddedMaxWidth?.call(null, resolvedContentWidth, 'iframe') ||
resolvedContentWidth;
const htmlAttribs = tnode.attributes;
const normalizedUrl = useNormalizedUrl(htmlAttribs.src);
const { width, height, ...restStyle } = style;
const attrWidth = Number(htmlAttribs.width);
const attrHeight = Number(htmlAttribs.height);
const printConfig: ExtractPrintDimensionsParams = {
attrWidth: Number.isNaN(attrWidth) ? null : attrWidth,
attrHeight: Number.isNaN(attrHeight) ? null : attrHeight,
styleWidth: typeof width === 'string' ? null : width,
styleHeight: typeof height === 'string' ? null : height,
contentWidth: availableWidth
};
const { printWidth, printHeight } = extractPrintDimensions(printConfig);
const scaleFactor =
typeof printConfig.attrWidth === 'number' &&
printConfig.attrWidth > printWidth
? printWidth / attrWidth
: 1;
const source = htmlAttribs.srcdoc
? { html: htmlAttribs.srcdoc as string, baseUrl: documentBaseUrl }
: {
uri: normalizedUrl,
headers: provideEmbeddedHeaders?.(normalizedUrl, 'iframe', {
printHeight,
printWidth
})
};
return {
...resolvedConfig,
source,
onLinkPress,
htmlAttribs,
scaleFactor,
style: [restStyle, { width: printWidth, height: printHeight }],
WebView
};
}