From f9bb9e969ad6b169ee60940daf1409630589f548 Mon Sep 17 00:00:00 2001 From: "Jules Sam. Randolph" Date: Sun, 26 Sep 2021 14:34:56 -0300 Subject: [PATCH] fix: never assume the definition of `__DEV__` in the global scope Especially appropriate for jest tests and react-native-web. --- packages/render-html/src/RenderHTMLConfigProvider.tsx | 2 +- packages/render-html/src/RenderHTMLDebug.tsx | 2 +- packages/render-html/src/RenderHTMLSource.tsx | 6 +++--- packages/render-html/src/TNodeRenderer.tsx | 6 +++--- packages/render-html/src/TRenderEngineProvider.tsx | 6 +++++- packages/render-html/src/context/RenderRegistryProvider.tsx | 2 +- packages/render-html/src/context/RenderersPropsProvider.tsx | 2 +- packages/render-html/src/context/defaultSharedProps.ts | 2 +- packages/render-html/src/debugMessages.ts | 2 +- packages/render-html/src/elements/ListElement.tsx | 6 +++++- packages/render-html/src/hooks/useProfiler.ts | 2 +- packages/render-html/src/hooks/useTRenderEngine.ts | 2 +- packages/render-html/src/hooks/useTTree.ts | 2 +- packages/render-html/src/render/RenderRegistry.ts | 2 +- 14 files changed, 26 insertions(+), 18 deletions(-) diff --git a/packages/render-html/src/RenderHTMLConfigProvider.tsx b/packages/render-html/src/RenderHTMLConfigProvider.tsx index 9d3837789..0df5375f7 100644 --- a/packages/render-html/src/RenderHTMLConfigProvider.tsx +++ b/packages/render-html/src/RenderHTMLConfigProvider.tsx @@ -61,7 +61,7 @@ export default function RenderHTMLConfigProvider( const engine = useAmbientTRenderEngine(); const profile = useProfiler({ prop: 'remoteErrorView or remoteLoadingView' }); const sourceLoaderConfig = useMemo(() => { - __DEV__ && profile(); + typeof __DEV__ === 'boolean' && __DEV__ && profile(); return { remoteErrorView: remoteErrorView || defaultRenderError, remoteLoadingView: remoteLoadingView || defaultRenderLoading diff --git a/packages/render-html/src/RenderHTMLDebug.tsx b/packages/render-html/src/RenderHTMLDebug.tsx index 774c33787..6b5c016ff 100644 --- a/packages/render-html/src/RenderHTMLDebug.tsx +++ b/packages/render-html/src/RenderHTMLDebug.tsx @@ -5,7 +5,7 @@ import { RenderHTMLProps } from './shared-types'; const RenderHTMLDebug = function RenderHTMLDebug( props: PropsWithChildren ) { - if (__DEV__) { + if (typeof __DEV__ === 'boolean' && __DEV__) { if (typeof props.contentWidth !== 'number') { console.warn(debugMessage.contentWidth); } diff --git a/packages/render-html/src/RenderHTMLSource.tsx b/packages/render-html/src/RenderHTMLSource.tsx index 407654f2c..c91da52a1 100644 --- a/packages/render-html/src/RenderHTMLSource.tsx +++ b/packages/render-html/src/RenderHTMLSource.tsx @@ -63,7 +63,7 @@ function RawSourceLoader({ }: SourceLoaderProps): ReactElement | null { if (isEmptySource(source)) { /* istanbul ignore next */ - if (__DEV__) { + if (typeof __DEV__ === 'boolean' && __DEV__) { console.warn(debugMessage.noSource); } return null; @@ -111,13 +111,13 @@ const RenderHTMLSource = memo( prop: 'onDocumentMetadataLoaded or onTTreeChange' }); const ttreeEvents: TTreeEvents = useMemo(() => { - __DEV__ && profile(); + typeof __DEV__ === 'boolean' && __DEV__ && profile(); return { onDocumentMetadataLoaded, onTTreeChange }; }, [onDocumentMetadataLoaded, onTTreeChange, profile]); - if (__DEV__) { + if (typeof __DEV__ === 'boolean' && __DEV__) { if (!(typeof contentWidth === 'number')) { console.warn(debugMessage.contentWidth); } diff --git a/packages/render-html/src/TNodeRenderer.tsx b/packages/render-html/src/TNodeRenderer.tsx index 2b4825072..8324377be 100644 --- a/packages/render-html/src/TNodeRenderer.tsx +++ b/packages/render-html/src/TNodeRenderer.tsx @@ -28,15 +28,15 @@ const TNodeRenderer = memo(function MemoizedTNodeRenderer( if (tnode.type === 'text') { return React.createElement(TTextRenderer, tnodeProps); } - if (tnode.type === 'empty' && __DEV__) { + if (typeof __DEV__ === 'boolean' && __DEV__ && tnode.type === 'empty') { if (tnode.isUnregistered) { console.warn( `There is no custom renderer registered for tag "${tnode.tagName}" which is not part of the HTML5 standard. The tag will not be rendered.` + - ' If you don\'t want this tag to be rendered, add it to "ignoredTags" prop array. If you do, register a custom renderer for this tag.' + ' If you don\'t want this tag to be rendered, add it to "ignoredTags" prop array. If you do, register an HTMLElementModel for this tag with "customHTMLElementModels" prop.' ); } else if (tnode.tagName !== 'head') { console.warn( - `The "${tnode.tagName}" tag is a valid HTML element but is not handled by this library. You must register a custom renderer or plugin and make sure its content model is not set to "none".` + + `The "${tnode.tagName}" tag is a valid HTML element but is not handled by this library. You must extend the default HTMLElementModel for this tag with "customHTMLElementModels" prop and make sure its content model is not set to "none".` + ' If you don\'t want this tag to be rendered, add it to "ignoredTags" prop array.' ); } diff --git a/packages/render-html/src/TRenderEngineProvider.tsx b/packages/render-html/src/TRenderEngineProvider.tsx index 2362e98b9..95b60df62 100644 --- a/packages/render-html/src/TRenderEngineProvider.tsx +++ b/packages/render-html/src/TRenderEngineProvider.tsx @@ -77,7 +77,11 @@ export const defaultTRenderEngineProviderProps: TRenderEngineConfig = { */ export function useAmbientTRenderEngine() { const engine = React.useContext(TRenderEngineContext); - if (__DEV__ && engine === defaultTRenderEngine) { + if ( + typeof __DEV__ === 'boolean' && + __DEV__ && + engine === defaultTRenderEngine + ) { console.error('TRenderEngineProvider is missing in the render tree.'); } return engine; diff --git a/packages/render-html/src/context/RenderRegistryProvider.tsx b/packages/render-html/src/context/RenderRegistryProvider.tsx index 51d59e54e..93a2fa0ac 100644 --- a/packages/render-html/src/context/RenderRegistryProvider.tsx +++ b/packages/render-html/src/context/RenderRegistryProvider.tsx @@ -31,7 +31,7 @@ export default function RenderRegistryProvider({ }>) { const profile = useProfiler({ prop: 'renderers' }); const registry = useMemo(() => { - __DEV__ && profile(); + typeof __DEV__ === 'boolean' && __DEV__ && profile(); return new RenderRegistry(renderers, elementModels); }, [renderers, elementModels, profile]); return ( diff --git a/packages/render-html/src/context/RenderersPropsProvider.tsx b/packages/render-html/src/context/RenderersPropsProvider.tsx index fdf00c377..e0140e685 100644 --- a/packages/render-html/src/context/RenderersPropsProvider.tsx +++ b/packages/render-html/src/context/RenderersPropsProvider.tsx @@ -33,7 +33,7 @@ export default function RenderersPropsProvider( ) { const profile = useProfiler({ prop: 'renderersProps' }); const mergedRenderersProps = useMemo(() => { - __DEV__ && profile(); + typeof __DEV__ === 'boolean' && __DEV__ && profile(); return mergeDeepRight(defaultRendererProps, props.renderersProps || {}); }, [props.renderersProps, profile]); return React.createElement( diff --git a/packages/render-html/src/context/defaultSharedProps.ts b/packages/render-html/src/context/defaultSharedProps.ts index ced907a3c..c330e997b 100644 --- a/packages/render-html/src/context/defaultSharedProps.ts +++ b/packages/render-html/src/context/defaultSharedProps.ts @@ -3,7 +3,7 @@ import { RenderHTMLAmbiantSharedProps } from '../shared-types'; function WebViewPlaceholder() { /* istanbul ignore else */ - if (__DEV__) { + if (typeof __DEV__ === 'boolean' && __DEV__) { console.warn( 'One of your renderers is attempting to use WebView component, which has not been ' + "provided as a prop to the RenderHtml component. As a consequence, the element won't be rendered." diff --git a/packages/render-html/src/debugMessages.ts b/packages/render-html/src/debugMessages.ts index 654ecc26b..ab0e86061 100644 --- a/packages/render-html/src/debugMessages.ts +++ b/packages/render-html/src/debugMessages.ts @@ -18,7 +18,7 @@ let debugMessage: Record; export type DebugMessages = typeof debugMessage; /* istanbul ignore next */ -if (__DEV__) { +if (typeof __DEV__ === 'boolean' && __DEV__) { debugMessage = { outdatedComputeImagesMaxWidth: "You're attempting to use an outdated prop, 'computeImagesMaxWidth'. This prop has been replaced in version 6 with 'computeEmbeddedMaxWidth'.", diff --git a/packages/render-html/src/elements/ListElement.tsx b/packages/render-html/src/elements/ListElement.tsx index 7e7906930..ecf5bed35 100644 --- a/packages/render-html/src/elements/ListElement.tsx +++ b/packages/render-html/src/elements/ListElement.tsx @@ -110,7 +110,11 @@ export default function ListElement({ ownListType || listStyleTypeFallbackRecord[listType]; const listStyleType = ownListType || selectedListType; - if (__DEV__ && !(listStyleType in listStyleSpecs)) { + if ( + typeof __DEV__ === 'boolean' && + __DEV__ && + !(listStyleType in listStyleSpecs) + ) { if (listStyleType.match(/^("|')/)) { console.warn( "This library doesn't support strings for list-style-type CSS properties." diff --git a/packages/render-html/src/hooks/useProfiler.ts b/packages/render-html/src/hooks/useProfiler.ts index eec12153c..72285476a 100644 --- a/packages/render-html/src/hooks/useProfiler.ts +++ b/packages/render-html/src/hooks/useProfiler.ts @@ -4,7 +4,7 @@ import identity from 'ramda/src/identity'; declare const performance: { now: () => number }; const useProfiler = - __DEV__ && typeof performance === 'object' + typeof __DEV__ === 'boolean' && __DEV__ && typeof performance === 'object' ? function useProfiler({ name, prop }: { name?: string; prop?: string }) { const lastUpdate = useRef(0); const profile = useCallback( diff --git a/packages/render-html/src/hooks/useTRenderEngine.ts b/packages/render-html/src/hooks/useTRenderEngine.ts index 415f98d8c..6f706aa47 100644 --- a/packages/render-html/src/hooks/useTRenderEngine.ts +++ b/packages/render-html/src/hooks/useTRenderEngine.ts @@ -30,7 +30,7 @@ export default function useTRenderEngine({ }: TRenderEngineConfig) { const profile = useProfiler({ name: 'TRenderEngineProvider' }); return useMemo(() => { - __DEV__ && profile(); + typeof __DEV__ === 'boolean' && __DEV__ && profile(); return buildTREFromConfig({ allowedStyles, baseStyle, diff --git a/packages/render-html/src/hooks/useTTree.ts b/packages/render-html/src/hooks/useTTree.ts index 63c26d9b8..e00ec069b 100644 --- a/packages/render-html/src/hooks/useTTree.ts +++ b/packages/render-html/src/hooks/useTTree.ts @@ -11,7 +11,7 @@ function useTTreeChangeEffect(ttree: TDocument) { const updateNumber = useRef(0); useEffect(() => { onTTreeChange?.call(null, ttree); - if (debug && __DEV__) { + if (debug && typeof __DEV__ === 'boolean' && __DEV__) { console.info( `Transient Render Tree update ${++updateNumber.current}:\n${ttree.snapshot( { diff --git a/packages/render-html/src/render/RenderRegistry.ts b/packages/render-html/src/render/RenderRegistry.ts index 43337f594..aea3942fe 100644 --- a/packages/render-html/src/render/RenderRegistry.ts +++ b/packages/render-html/src/render/RenderRegistry.ts @@ -43,7 +43,7 @@ export default class RenderRegistry { if (tnode.tagName! in this.customRenderers) { const renderer = this.customRenderers[tnode.tagName!]; /* istanbul ignore next */ - if (__DEV__) { + if (typeof __DEV__ === 'boolean' && __DEV__) { // In DEV, check for discrepancies. const elementModel = this.elementModels[tnode.tagName!]; if (!elementModel) {