@wordpress/server-side-render 5.21.0 → 5.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 5.23.0 (2025-05-07)
6
+
7
+ ### Bug Fixes
8
+
9
+ - Fix `ServerSideRender` not updating when attributes change by properly implementing debounced fetch with refs ([#69237](https://github.com/WordPress/gutenberg/pull/69237)).
10
+
11
+ ## 5.22.0 (2025-04-11)
12
+
5
13
  ## 5.21.0 (2025-03-27)
6
14
 
7
15
  ## 5.20.0 (2025-03-13)
@@ -105,12 +105,7 @@ function DefaultLoadingResponsePlaceholder({
105
105
  }
106
106
  function ServerSideRender(props) {
107
107
  const {
108
- attributes,
109
- block,
110
108
  className,
111
- httpMethod = 'GET',
112
- urlQueryArgs,
113
- skipBlockSupportAttributes = false,
114
109
  EmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,
115
110
  ErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,
116
111
  LoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder
@@ -121,11 +116,22 @@ function ServerSideRender(props) {
121
116
  const [response, setResponse] = (0, _element.useState)(null);
122
117
  const prevProps = (0, _compose.usePrevious)(props);
123
118
  const [isLoading, setIsLoading] = (0, _element.useState)(false);
124
- function fetchData() {
119
+ const latestPropsRef = (0, _element.useRef)(props);
120
+ (0, _element.useLayoutEffect)(() => {
121
+ latestPropsRef.current = props;
122
+ }, [props]);
123
+ const fetchData = (0, _element.useCallback)(() => {
125
124
  var _sanitizedAttributes, _sanitizedAttributes2;
126
125
  if (!isMountedRef.current) {
127
126
  return;
128
127
  }
128
+ const {
129
+ attributes,
130
+ block,
131
+ skipBlockSupportAttributes = false,
132
+ httpMethod = 'GET',
133
+ urlQueryArgs
134
+ } = latestPropsRef.current;
129
135
  setIsLoading(true);
130
136
 
131
137
  // Schedule showing the Spinner after 1 second.
@@ -172,7 +178,7 @@ function ServerSideRender(props) {
172
178
  }
173
179
  });
174
180
  return fetchRequest;
175
- }
181
+ }, []);
176
182
  const debouncedFetchData = (0, _compose.useDebounce)(fetchData, 500);
177
183
 
178
184
  // When the component unmounts, set isMountedRef to false. This will
@@ -194,12 +200,12 @@ function ServerSideRender(props) {
194
200
  });
195
201
  const hasResponse = !!response;
196
202
  const hasEmptyResponse = response === '';
197
- const hasError = response?.error;
203
+ const hasError = !!response?.error;
198
204
  if (isLoading) {
199
205
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(LoadingResponsePlaceholder, {
200
206
  ...props,
201
207
  showLoader: showLoader,
202
- children: hasResponse && /*#__PURE__*/(0, _jsxRuntime.jsx)(_element.RawHTML, {
208
+ children: hasResponse && !hasError && /*#__PURE__*/(0, _jsxRuntime.jsx)(_element.RawHTML, {
203
209
  className: className,
204
210
  children: response
205
211
  })
@@ -1 +1 @@
1
- {"version":3,"names":["_es","_interopRequireDefault","require","_compose","_element","_i18n","_apiFetch","_url","_components","_blocks","_jsxRuntime","EMPTY_OBJECT","rendererPath","block","attributes","urlQueryArgs","addQueryArgs","context","removeBlockSupportAttributes","backgroundColor","borderColor","fontFamily","fontSize","gradient","textColor","className","restAttributes","border","color","elements","spacing","typography","restStyles","style","DefaultEmptyResponsePlaceholder","jsx","Placeholder","children","__","DefaultErrorResponsePlaceholder","response","errorMessage","sprintf","errorMsg","DefaultLoadingResponsePlaceholder","showLoader","jsxs","position","top","left","marginTop","marginLeft","Spinner","opacity","ServerSideRender","props","httpMethod","skipBlockSupportAttributes","EmptyResponsePlaceholder","ErrorResponsePlaceholder","LoadingResponsePlaceholder","isMountedRef","useRef","setShowLoader","useState","fetchRequestRef","setResponse","prevProps","usePrevious","isLoading","setIsLoading","fetchData","_sanitizedAttributes","_sanitizedAttributes2","current","timeout","setTimeout","sanitizedAttributes","__experimentalSanitizeBlockAttributes","isPostRequest","urlAttributes","path","data","fetchRequest","apiFetch","method","then","fetchResponse","rendered","catch","error","message","finally","clearTimeout","debouncedFetchData","useDebounce","useEffect","undefined","fastDeepEqual","hasResponse","hasEmptyResponse","hasError","RawHTML"],"sources":["@wordpress/server-side-render/src/server-side-render.js"],"sourcesContent":["/**\n * External dependencies\n */\nimport fastDeepEqual from 'fast-deep-equal/es6';\n\n/**\n * WordPress dependencies\n */\nimport { useDebounce, usePrevious } from '@wordpress/compose';\nimport { RawHTML, useEffect, useRef, useState } from '@wordpress/element';\nimport { __, sprintf } from '@wordpress/i18n';\nimport apiFetch from '@wordpress/api-fetch';\nimport { addQueryArgs } from '@wordpress/url';\nimport { Placeholder, Spinner } from '@wordpress/components';\nimport { __experimentalSanitizeBlockAttributes } from '@wordpress/blocks';\n\nconst EMPTY_OBJECT = {};\n\nexport function rendererPath( block, attributes = null, urlQueryArgs = {} ) {\n\treturn addQueryArgs( `/wp/v2/block-renderer/${ block }`, {\n\t\tcontext: 'edit',\n\t\t...( null !== attributes ? { attributes } : {} ),\n\t\t...urlQueryArgs,\n\t} );\n}\n\nexport function removeBlockSupportAttributes( attributes ) {\n\tconst {\n\t\tbackgroundColor,\n\t\tborderColor,\n\t\tfontFamily,\n\t\tfontSize,\n\t\tgradient,\n\t\ttextColor,\n\t\tclassName,\n\t\t...restAttributes\n\t} = attributes;\n\n\tconst { border, color, elements, spacing, typography, ...restStyles } =\n\t\tattributes?.style || EMPTY_OBJECT;\n\n\treturn {\n\t\t...restAttributes,\n\t\tstyle: restStyles,\n\t};\n}\n\nfunction DefaultEmptyResponsePlaceholder( { className } ) {\n\treturn (\n\t\t<Placeholder className={ className }>\n\t\t\t{ __( 'Block rendered as empty.' ) }\n\t\t</Placeholder>\n\t);\n}\n\nfunction DefaultErrorResponsePlaceholder( { response, className } ) {\n\tconst errorMessage = sprintf(\n\t\t// translators: %s: error message describing the problem\n\t\t__( 'Error loading block: %s' ),\n\t\tresponse.errorMsg\n\t);\n\treturn <Placeholder className={ className }>{ errorMessage }</Placeholder>;\n}\n\nfunction DefaultLoadingResponsePlaceholder( { children, showLoader } ) {\n\treturn (\n\t\t<div style={ { position: 'relative' } }>\n\t\t\t{ showLoader && (\n\t\t\t\t<div\n\t\t\t\t\tstyle={ {\n\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\ttop: '50%',\n\t\t\t\t\t\tleft: '50%',\n\t\t\t\t\t\tmarginTop: '-9px',\n\t\t\t\t\t\tmarginLeft: '-9px',\n\t\t\t\t\t} }\n\t\t\t\t>\n\t\t\t\t\t<Spinner />\n\t\t\t\t</div>\n\t\t\t) }\n\t\t\t<div style={ { opacity: showLoader ? '0.3' : 1 } }>\n\t\t\t\t{ children }\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport default function ServerSideRender( props ) {\n\tconst {\n\t\tattributes,\n\t\tblock,\n\t\tclassName,\n\t\thttpMethod = 'GET',\n\t\turlQueryArgs,\n\t\tskipBlockSupportAttributes = false,\n\t\tEmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,\n\t\tErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,\n\t\tLoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder,\n\t} = props;\n\n\tconst isMountedRef = useRef( false );\n\tconst [ showLoader, setShowLoader ] = useState( false );\n\tconst fetchRequestRef = useRef();\n\tconst [ response, setResponse ] = useState( null );\n\tconst prevProps = usePrevious( props );\n\tconst [ isLoading, setIsLoading ] = useState( false );\n\n\tfunction fetchData() {\n\t\tif ( ! isMountedRef.current ) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetIsLoading( true );\n\n\t\t// Schedule showing the Spinner after 1 second.\n\t\tconst timeout = setTimeout( () => {\n\t\t\tsetShowLoader( true );\n\t\t}, 1000 );\n\n\t\tlet sanitizedAttributes =\n\t\t\tattributes &&\n\t\t\t__experimentalSanitizeBlockAttributes( block, attributes );\n\n\t\tif ( skipBlockSupportAttributes ) {\n\t\t\tsanitizedAttributes =\n\t\t\t\tremoveBlockSupportAttributes( sanitizedAttributes );\n\t\t}\n\n\t\t// If httpMethod is 'POST', send the attributes in the request body instead of the URL.\n\t\t// This allows sending a larger attributes object than in a GET request, where the attributes are in the URL.\n\t\tconst isPostRequest = 'POST' === httpMethod;\n\t\tconst urlAttributes = isPostRequest\n\t\t\t? null\n\t\t\t: sanitizedAttributes ?? null;\n\t\tconst path = rendererPath( block, urlAttributes, urlQueryArgs );\n\t\tconst data = isPostRequest\n\t\t\t? { attributes: sanitizedAttributes ?? null }\n\t\t\t: null;\n\n\t\t// Store the latest fetch request so that when we process it, we can\n\t\t// check if it is the current request, to avoid race conditions on slow networks.\n\t\tconst fetchRequest = ( fetchRequestRef.current = apiFetch( {\n\t\t\tpath,\n\t\t\tdata,\n\t\t\tmethod: isPostRequest ? 'POST' : 'GET',\n\t\t} )\n\t\t\t.then( ( fetchResponse ) => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current &&\n\t\t\t\t\tfetchResponse\n\t\t\t\t) {\n\t\t\t\t\tsetResponse( fetchResponse.rendered );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.catch( ( error ) => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current\n\t\t\t\t) {\n\t\t\t\t\tsetResponse( {\n\t\t\t\t\t\terror: true,\n\t\t\t\t\t\terrorMsg: error.message,\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.finally( () => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current\n\t\t\t\t) {\n\t\t\t\t\tsetIsLoading( false );\n\t\t\t\t\t// Cancel the timeout to show the Spinner.\n\t\t\t\t\tsetShowLoader( false );\n\t\t\t\t\tclearTimeout( timeout );\n\t\t\t\t}\n\t\t\t} ) );\n\n\t\treturn fetchRequest;\n\t}\n\n\tconst debouncedFetchData = useDebounce( fetchData, 500 );\n\n\t// When the component unmounts, set isMountedRef to false. This will\n\t// let the async fetch callbacks know when to stop.\n\tuseEffect( () => {\n\t\tisMountedRef.current = true;\n\t\treturn () => {\n\t\t\tisMountedRef.current = false;\n\t\t};\n\t}, [] );\n\n\tuseEffect( () => {\n\t\t// Don't debounce the first fetch. This ensures that the first render\n\t\t// shows data as soon as possible.\n\t\tif ( prevProps === undefined ) {\n\t\t\tfetchData();\n\t\t} else if ( ! fastDeepEqual( prevProps, props ) ) {\n\t\t\tdebouncedFetchData();\n\t\t}\n\t} );\n\n\tconst hasResponse = !! response;\n\tconst hasEmptyResponse = response === '';\n\tconst hasError = response?.error;\n\n\tif ( isLoading ) {\n\t\treturn (\n\t\t\t<LoadingResponsePlaceholder { ...props } showLoader={ showLoader }>\n\t\t\t\t{ hasResponse && (\n\t\t\t\t\t<RawHTML className={ className }>{ response }</RawHTML>\n\t\t\t\t) }\n\t\t\t</LoadingResponsePlaceholder>\n\t\t);\n\t}\n\n\tif ( hasEmptyResponse || ! hasResponse ) {\n\t\treturn <EmptyResponsePlaceholder { ...props } />;\n\t}\n\n\tif ( hasError ) {\n\t\treturn <ErrorResponsePlaceholder response={ response } { ...props } />;\n\t}\n\n\treturn <RawHTML className={ className }>{ response }</RawHTML>;\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_es","_interopRequireDefault","require","_compose","_element","_i18n","_apiFetch","_url","_components","_blocks","_jsxRuntime","EMPTY_OBJECT","rendererPath","block","attributes","urlQueryArgs","addQueryArgs","context","removeBlockSupportAttributes","backgroundColor","borderColor","fontFamily","fontSize","gradient","textColor","className","restAttributes","border","color","elements","spacing","typography","restStyles","style","DefaultEmptyResponsePlaceholder","jsx","Placeholder","children","__","DefaultErrorResponsePlaceholder","response","errorMessage","sprintf","errorMsg","DefaultLoadingResponsePlaceholder","showLoader","jsxs","position","top","left","marginTop","marginLeft","Spinner","opacity","ServerSideRender","props","EmptyResponsePlaceholder","ErrorResponsePlaceholder","LoadingResponsePlaceholder","isMountedRef","useRef","setShowLoader","useState","fetchRequestRef","setResponse","prevProps","usePrevious","isLoading","setIsLoading","latestPropsRef","useLayoutEffect","current","fetchData","useCallback","_sanitizedAttributes","_sanitizedAttributes2","skipBlockSupportAttributes","httpMethod","timeout","setTimeout","sanitizedAttributes","__experimentalSanitizeBlockAttributes","isPostRequest","urlAttributes","path","data","fetchRequest","apiFetch","method","then","fetchResponse","rendered","catch","error","message","finally","clearTimeout","debouncedFetchData","useDebounce","useEffect","undefined","fastDeepEqual","hasResponse","hasEmptyResponse","hasError","RawHTML"],"sources":["@wordpress/server-side-render/src/server-side-render.js"],"sourcesContent":["/**\n * External dependencies\n */\nimport fastDeepEqual from 'fast-deep-equal/es6';\n\n/**\n * WordPress dependencies\n */\nimport { useDebounce, usePrevious } from '@wordpress/compose';\nimport {\n\tRawHTML,\n\tuseCallback,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from '@wordpress/element';\nimport { __, sprintf } from '@wordpress/i18n';\nimport apiFetch from '@wordpress/api-fetch';\nimport { addQueryArgs } from '@wordpress/url';\nimport { Placeholder, Spinner } from '@wordpress/components';\nimport { __experimentalSanitizeBlockAttributes } from '@wordpress/blocks';\n\nconst EMPTY_OBJECT = {};\n\nexport function rendererPath( block, attributes = null, urlQueryArgs = {} ) {\n\treturn addQueryArgs( `/wp/v2/block-renderer/${ block }`, {\n\t\tcontext: 'edit',\n\t\t...( null !== attributes ? { attributes } : {} ),\n\t\t...urlQueryArgs,\n\t} );\n}\n\nexport function removeBlockSupportAttributes( attributes ) {\n\tconst {\n\t\tbackgroundColor,\n\t\tborderColor,\n\t\tfontFamily,\n\t\tfontSize,\n\t\tgradient,\n\t\ttextColor,\n\t\tclassName,\n\t\t...restAttributes\n\t} = attributes;\n\n\tconst { border, color, elements, spacing, typography, ...restStyles } =\n\t\tattributes?.style || EMPTY_OBJECT;\n\n\treturn {\n\t\t...restAttributes,\n\t\tstyle: restStyles,\n\t};\n}\n\nfunction DefaultEmptyResponsePlaceholder( { className } ) {\n\treturn (\n\t\t<Placeholder className={ className }>\n\t\t\t{ __( 'Block rendered as empty.' ) }\n\t\t</Placeholder>\n\t);\n}\n\nfunction DefaultErrorResponsePlaceholder( { response, className } ) {\n\tconst errorMessage = sprintf(\n\t\t// translators: %s: error message describing the problem\n\t\t__( 'Error loading block: %s' ),\n\t\tresponse.errorMsg\n\t);\n\treturn <Placeholder className={ className }>{ errorMessage }</Placeholder>;\n}\n\nfunction DefaultLoadingResponsePlaceholder( { children, showLoader } ) {\n\treturn (\n\t\t<div style={ { position: 'relative' } }>\n\t\t\t{ showLoader && (\n\t\t\t\t<div\n\t\t\t\t\tstyle={ {\n\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\ttop: '50%',\n\t\t\t\t\t\tleft: '50%',\n\t\t\t\t\t\tmarginTop: '-9px',\n\t\t\t\t\t\tmarginLeft: '-9px',\n\t\t\t\t\t} }\n\t\t\t\t>\n\t\t\t\t\t<Spinner />\n\t\t\t\t</div>\n\t\t\t) }\n\t\t\t<div style={ { opacity: showLoader ? '0.3' : 1 } }>\n\t\t\t\t{ children }\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport default function ServerSideRender( props ) {\n\tconst {\n\t\tclassName,\n\t\tEmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,\n\t\tErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,\n\t\tLoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder,\n\t} = props;\n\n\tconst isMountedRef = useRef( false );\n\tconst [ showLoader, setShowLoader ] = useState( false );\n\tconst fetchRequestRef = useRef();\n\tconst [ response, setResponse ] = useState( null );\n\tconst prevProps = usePrevious( props );\n\tconst [ isLoading, setIsLoading ] = useState( false );\n\tconst latestPropsRef = useRef( props );\n\n\tuseLayoutEffect( () => {\n\t\tlatestPropsRef.current = props;\n\t}, [ props ] );\n\n\tconst fetchData = useCallback( () => {\n\t\tif ( ! isMountedRef.current ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst {\n\t\t\tattributes,\n\t\t\tblock,\n\t\t\tskipBlockSupportAttributes = false,\n\t\t\thttpMethod = 'GET',\n\t\t\turlQueryArgs,\n\t\t} = latestPropsRef.current;\n\n\t\tsetIsLoading( true );\n\n\t\t// Schedule showing the Spinner after 1 second.\n\t\tconst timeout = setTimeout( () => {\n\t\t\tsetShowLoader( true );\n\t\t}, 1000 );\n\n\t\tlet sanitizedAttributes =\n\t\t\tattributes &&\n\t\t\t__experimentalSanitizeBlockAttributes( block, attributes );\n\n\t\tif ( skipBlockSupportAttributes ) {\n\t\t\tsanitizedAttributes =\n\t\t\t\tremoveBlockSupportAttributes( sanitizedAttributes );\n\t\t}\n\n\t\t// If httpMethod is 'POST', send the attributes in the request body instead of the URL.\n\t\t// This allows sending a larger attributes object than in a GET request, where the attributes are in the URL.\n\t\tconst isPostRequest = 'POST' === httpMethod;\n\t\tconst urlAttributes = isPostRequest\n\t\t\t? null\n\t\t\t: sanitizedAttributes ?? null;\n\t\tconst path = rendererPath( block, urlAttributes, urlQueryArgs );\n\t\tconst data = isPostRequest\n\t\t\t? { attributes: sanitizedAttributes ?? null }\n\t\t\t: null;\n\n\t\t// Store the latest fetch request so that when we process it, we can\n\t\t// check if it is the current request, to avoid race conditions on slow networks.\n\t\tconst fetchRequest = ( fetchRequestRef.current = apiFetch( {\n\t\t\tpath,\n\t\t\tdata,\n\t\t\tmethod: isPostRequest ? 'POST' : 'GET',\n\t\t} )\n\t\t\t.then( ( fetchResponse ) => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current &&\n\t\t\t\t\tfetchResponse\n\t\t\t\t) {\n\t\t\t\t\tsetResponse( fetchResponse.rendered );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.catch( ( error ) => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current\n\t\t\t\t) {\n\t\t\t\t\tsetResponse( {\n\t\t\t\t\t\terror: true,\n\t\t\t\t\t\terrorMsg: error.message,\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.finally( () => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current\n\t\t\t\t) {\n\t\t\t\t\tsetIsLoading( false );\n\t\t\t\t\t// Cancel the timeout to show the Spinner.\n\t\t\t\t\tsetShowLoader( false );\n\t\t\t\t\tclearTimeout( timeout );\n\t\t\t\t}\n\t\t\t} ) );\n\n\t\treturn fetchRequest;\n\t}, [] );\n\n\tconst debouncedFetchData = useDebounce( fetchData, 500 );\n\n\t// When the component unmounts, set isMountedRef to false. This will\n\t// let the async fetch callbacks know when to stop.\n\tuseEffect( () => {\n\t\tisMountedRef.current = true;\n\t\treturn () => {\n\t\t\tisMountedRef.current = false;\n\t\t};\n\t}, [] );\n\n\tuseEffect( () => {\n\t\t// Don't debounce the first fetch. This ensures that the first render\n\t\t// shows data as soon as possible.\n\t\tif ( prevProps === undefined ) {\n\t\t\tfetchData();\n\t\t} else if ( ! fastDeepEqual( prevProps, props ) ) {\n\t\t\tdebouncedFetchData();\n\t\t}\n\t} );\n\n\tconst hasResponse = !! response;\n\tconst hasEmptyResponse = response === '';\n\tconst hasError = !! response?.error;\n\n\tif ( isLoading ) {\n\t\treturn (\n\t\t\t<LoadingResponsePlaceholder { ...props } showLoader={ showLoader }>\n\t\t\t\t{ hasResponse && ! hasError && (\n\t\t\t\t\t<RawHTML className={ className }>{ response }</RawHTML>\n\t\t\t\t) }\n\t\t\t</LoadingResponsePlaceholder>\n\t\t);\n\t}\n\n\tif ( hasEmptyResponse || ! hasResponse ) {\n\t\treturn <EmptyResponsePlaceholder { ...props } />;\n\t}\n\n\tif ( hasError ) {\n\t\treturn <ErrorResponsePlaceholder response={ response } { ...props } />;\n\t}\n\n\treturn <RawHTML className={ className }>{ response }</RawHTML>;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -7,7 +7,7 @@ import fastDeepEqual from 'fast-deep-equal/es6';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { useDebounce, usePrevious } from '@wordpress/compose';
10
- import { RawHTML, useEffect, useRef, useState } from '@wordpress/element';
10
+ import { RawHTML, useCallback, useEffect, useLayoutEffect, useRef, useState } from '@wordpress/element';
11
11
  import { __, sprintf } from '@wordpress/i18n';
12
12
  import apiFetch from '@wordpress/api-fetch';
13
13
  import { addQueryArgs } from '@wordpress/url';
@@ -95,12 +95,7 @@ function DefaultLoadingResponsePlaceholder({
95
95
  }
96
96
  export default function ServerSideRender(props) {
97
97
  const {
98
- attributes,
99
- block,
100
98
  className,
101
- httpMethod = 'GET',
102
- urlQueryArgs,
103
- skipBlockSupportAttributes = false,
104
99
  EmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,
105
100
  ErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,
106
101
  LoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder
@@ -111,11 +106,22 @@ export default function ServerSideRender(props) {
111
106
  const [response, setResponse] = useState(null);
112
107
  const prevProps = usePrevious(props);
113
108
  const [isLoading, setIsLoading] = useState(false);
114
- function fetchData() {
109
+ const latestPropsRef = useRef(props);
110
+ useLayoutEffect(() => {
111
+ latestPropsRef.current = props;
112
+ }, [props]);
113
+ const fetchData = useCallback(() => {
115
114
  var _sanitizedAttributes, _sanitizedAttributes2;
116
115
  if (!isMountedRef.current) {
117
116
  return;
118
117
  }
118
+ const {
119
+ attributes,
120
+ block,
121
+ skipBlockSupportAttributes = false,
122
+ httpMethod = 'GET',
123
+ urlQueryArgs
124
+ } = latestPropsRef.current;
119
125
  setIsLoading(true);
120
126
 
121
127
  // Schedule showing the Spinner after 1 second.
@@ -162,7 +168,7 @@ export default function ServerSideRender(props) {
162
168
  }
163
169
  });
164
170
  return fetchRequest;
165
- }
171
+ }, []);
166
172
  const debouncedFetchData = useDebounce(fetchData, 500);
167
173
 
168
174
  // When the component unmounts, set isMountedRef to false. This will
@@ -184,12 +190,12 @@ export default function ServerSideRender(props) {
184
190
  });
185
191
  const hasResponse = !!response;
186
192
  const hasEmptyResponse = response === '';
187
- const hasError = response?.error;
193
+ const hasError = !!response?.error;
188
194
  if (isLoading) {
189
195
  return /*#__PURE__*/_jsx(LoadingResponsePlaceholder, {
190
196
  ...props,
191
197
  showLoader: showLoader,
192
- children: hasResponse && /*#__PURE__*/_jsx(RawHTML, {
198
+ children: hasResponse && !hasError && /*#__PURE__*/_jsx(RawHTML, {
193
199
  className: className,
194
200
  children: response
195
201
  })
@@ -1 +1 @@
1
- {"version":3,"names":["fastDeepEqual","useDebounce","usePrevious","RawHTML","useEffect","useRef","useState","__","sprintf","apiFetch","addQueryArgs","Placeholder","Spinner","__experimentalSanitizeBlockAttributes","jsx","_jsx","jsxs","_jsxs","EMPTY_OBJECT","rendererPath","block","attributes","urlQueryArgs","context","removeBlockSupportAttributes","backgroundColor","borderColor","fontFamily","fontSize","gradient","textColor","className","restAttributes","border","color","elements","spacing","typography","restStyles","style","DefaultEmptyResponsePlaceholder","children","DefaultErrorResponsePlaceholder","response","errorMessage","errorMsg","DefaultLoadingResponsePlaceholder","showLoader","position","top","left","marginTop","marginLeft","opacity","ServerSideRender","props","httpMethod","skipBlockSupportAttributes","EmptyResponsePlaceholder","ErrorResponsePlaceholder","LoadingResponsePlaceholder","isMountedRef","setShowLoader","fetchRequestRef","setResponse","prevProps","isLoading","setIsLoading","fetchData","_sanitizedAttributes","_sanitizedAttributes2","current","timeout","setTimeout","sanitizedAttributes","isPostRequest","urlAttributes","path","data","fetchRequest","method","then","fetchResponse","rendered","catch","error","message","finally","clearTimeout","debouncedFetchData","undefined","hasResponse","hasEmptyResponse","hasError"],"sources":["@wordpress/server-side-render/src/server-side-render.js"],"sourcesContent":["/**\n * External dependencies\n */\nimport fastDeepEqual from 'fast-deep-equal/es6';\n\n/**\n * WordPress dependencies\n */\nimport { useDebounce, usePrevious } from '@wordpress/compose';\nimport { RawHTML, useEffect, useRef, useState } from '@wordpress/element';\nimport { __, sprintf } from '@wordpress/i18n';\nimport apiFetch from '@wordpress/api-fetch';\nimport { addQueryArgs } from '@wordpress/url';\nimport { Placeholder, Spinner } from '@wordpress/components';\nimport { __experimentalSanitizeBlockAttributes } from '@wordpress/blocks';\n\nconst EMPTY_OBJECT = {};\n\nexport function rendererPath( block, attributes = null, urlQueryArgs = {} ) {\n\treturn addQueryArgs( `/wp/v2/block-renderer/${ block }`, {\n\t\tcontext: 'edit',\n\t\t...( null !== attributes ? { attributes } : {} ),\n\t\t...urlQueryArgs,\n\t} );\n}\n\nexport function removeBlockSupportAttributes( attributes ) {\n\tconst {\n\t\tbackgroundColor,\n\t\tborderColor,\n\t\tfontFamily,\n\t\tfontSize,\n\t\tgradient,\n\t\ttextColor,\n\t\tclassName,\n\t\t...restAttributes\n\t} = attributes;\n\n\tconst { border, color, elements, spacing, typography, ...restStyles } =\n\t\tattributes?.style || EMPTY_OBJECT;\n\n\treturn {\n\t\t...restAttributes,\n\t\tstyle: restStyles,\n\t};\n}\n\nfunction DefaultEmptyResponsePlaceholder( { className } ) {\n\treturn (\n\t\t<Placeholder className={ className }>\n\t\t\t{ __( 'Block rendered as empty.' ) }\n\t\t</Placeholder>\n\t);\n}\n\nfunction DefaultErrorResponsePlaceholder( { response, className } ) {\n\tconst errorMessage = sprintf(\n\t\t// translators: %s: error message describing the problem\n\t\t__( 'Error loading block: %s' ),\n\t\tresponse.errorMsg\n\t);\n\treturn <Placeholder className={ className }>{ errorMessage }</Placeholder>;\n}\n\nfunction DefaultLoadingResponsePlaceholder( { children, showLoader } ) {\n\treturn (\n\t\t<div style={ { position: 'relative' } }>\n\t\t\t{ showLoader && (\n\t\t\t\t<div\n\t\t\t\t\tstyle={ {\n\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\ttop: '50%',\n\t\t\t\t\t\tleft: '50%',\n\t\t\t\t\t\tmarginTop: '-9px',\n\t\t\t\t\t\tmarginLeft: '-9px',\n\t\t\t\t\t} }\n\t\t\t\t>\n\t\t\t\t\t<Spinner />\n\t\t\t\t</div>\n\t\t\t) }\n\t\t\t<div style={ { opacity: showLoader ? '0.3' : 1 } }>\n\t\t\t\t{ children }\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport default function ServerSideRender( props ) {\n\tconst {\n\t\tattributes,\n\t\tblock,\n\t\tclassName,\n\t\thttpMethod = 'GET',\n\t\turlQueryArgs,\n\t\tskipBlockSupportAttributes = false,\n\t\tEmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,\n\t\tErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,\n\t\tLoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder,\n\t} = props;\n\n\tconst isMountedRef = useRef( false );\n\tconst [ showLoader, setShowLoader ] = useState( false );\n\tconst fetchRequestRef = useRef();\n\tconst [ response, setResponse ] = useState( null );\n\tconst prevProps = usePrevious( props );\n\tconst [ isLoading, setIsLoading ] = useState( false );\n\n\tfunction fetchData() {\n\t\tif ( ! isMountedRef.current ) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetIsLoading( true );\n\n\t\t// Schedule showing the Spinner after 1 second.\n\t\tconst timeout = setTimeout( () => {\n\t\t\tsetShowLoader( true );\n\t\t}, 1000 );\n\n\t\tlet sanitizedAttributes =\n\t\t\tattributes &&\n\t\t\t__experimentalSanitizeBlockAttributes( block, attributes );\n\n\t\tif ( skipBlockSupportAttributes ) {\n\t\t\tsanitizedAttributes =\n\t\t\t\tremoveBlockSupportAttributes( sanitizedAttributes );\n\t\t}\n\n\t\t// If httpMethod is 'POST', send the attributes in the request body instead of the URL.\n\t\t// This allows sending a larger attributes object than in a GET request, where the attributes are in the URL.\n\t\tconst isPostRequest = 'POST' === httpMethod;\n\t\tconst urlAttributes = isPostRequest\n\t\t\t? null\n\t\t\t: sanitizedAttributes ?? null;\n\t\tconst path = rendererPath( block, urlAttributes, urlQueryArgs );\n\t\tconst data = isPostRequest\n\t\t\t? { attributes: sanitizedAttributes ?? null }\n\t\t\t: null;\n\n\t\t// Store the latest fetch request so that when we process it, we can\n\t\t// check if it is the current request, to avoid race conditions on slow networks.\n\t\tconst fetchRequest = ( fetchRequestRef.current = apiFetch( {\n\t\t\tpath,\n\t\t\tdata,\n\t\t\tmethod: isPostRequest ? 'POST' : 'GET',\n\t\t} )\n\t\t\t.then( ( fetchResponse ) => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current &&\n\t\t\t\t\tfetchResponse\n\t\t\t\t) {\n\t\t\t\t\tsetResponse( fetchResponse.rendered );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.catch( ( error ) => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current\n\t\t\t\t) {\n\t\t\t\t\tsetResponse( {\n\t\t\t\t\t\terror: true,\n\t\t\t\t\t\terrorMsg: error.message,\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.finally( () => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current\n\t\t\t\t) {\n\t\t\t\t\tsetIsLoading( false );\n\t\t\t\t\t// Cancel the timeout to show the Spinner.\n\t\t\t\t\tsetShowLoader( false );\n\t\t\t\t\tclearTimeout( timeout );\n\t\t\t\t}\n\t\t\t} ) );\n\n\t\treturn fetchRequest;\n\t}\n\n\tconst debouncedFetchData = useDebounce( fetchData, 500 );\n\n\t// When the component unmounts, set isMountedRef to false. This will\n\t// let the async fetch callbacks know when to stop.\n\tuseEffect( () => {\n\t\tisMountedRef.current = true;\n\t\treturn () => {\n\t\t\tisMountedRef.current = false;\n\t\t};\n\t}, [] );\n\n\tuseEffect( () => {\n\t\t// Don't debounce the first fetch. This ensures that the first render\n\t\t// shows data as soon as possible.\n\t\tif ( prevProps === undefined ) {\n\t\t\tfetchData();\n\t\t} else if ( ! fastDeepEqual( prevProps, props ) ) {\n\t\t\tdebouncedFetchData();\n\t\t}\n\t} );\n\n\tconst hasResponse = !! response;\n\tconst hasEmptyResponse = response === '';\n\tconst hasError = response?.error;\n\n\tif ( isLoading ) {\n\t\treturn (\n\t\t\t<LoadingResponsePlaceholder { ...props } showLoader={ showLoader }>\n\t\t\t\t{ hasResponse && (\n\t\t\t\t\t<RawHTML className={ className }>{ response }</RawHTML>\n\t\t\t\t) }\n\t\t\t</LoadingResponsePlaceholder>\n\t\t);\n\t}\n\n\tif ( hasEmptyResponse || ! hasResponse ) {\n\t\treturn <EmptyResponsePlaceholder { ...props } />;\n\t}\n\n\tif ( hasError ) {\n\t\treturn <ErrorResponsePlaceholder response={ response } { ...props } />;\n\t}\n\n\treturn <RawHTML className={ className }>{ response }</RawHTML>;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA,OAAOA,aAAa,MAAM,qBAAqB;;AAE/C;AACA;AACA;AACA,SAASC,WAAW,EAAEC,WAAW,QAAQ,oBAAoB;AAC7D,SAASC,OAAO,EAAEC,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,oBAAoB;AACzE,SAASC,EAAE,EAAEC,OAAO,QAAQ,iBAAiB;AAC7C,OAAOC,QAAQ,MAAM,sBAAsB;AAC3C,SAASC,YAAY,QAAQ,gBAAgB;AAC7C,SAASC,WAAW,EAAEC,OAAO,QAAQ,uBAAuB;AAC5D,SAASC,qCAAqC,QAAQ,mBAAmB;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAE1E,MAAMC,YAAY,GAAG,CAAC,CAAC;AAEvB,OAAO,SAASC,YAAYA,CAAEC,KAAK,EAAEC,UAAU,GAAG,IAAI,EAAEC,YAAY,GAAG,CAAC,CAAC,EAAG;EAC3E,OAAOZ,YAAY,CAAE,yBAA0BU,KAAK,EAAG,EAAE;IACxDG,OAAO,EAAE,MAAM;IACf,IAAK,IAAI,KAAKF,UAAU,GAAG;MAAEA;IAAW,CAAC,GAAG,CAAC,CAAC,CAAE;IAChD,GAAGC;EACJ,CAAE,CAAC;AACJ;AAEA,OAAO,SAASE,4BAA4BA,CAAEH,UAAU,EAAG;EAC1D,MAAM;IACLI,eAAe;IACfC,WAAW;IACXC,UAAU;IACVC,QAAQ;IACRC,QAAQ;IACRC,SAAS;IACTC,SAAS;IACT,GAAGC;EACJ,CAAC,GAAGX,UAAU;EAEd,MAAM;IAAEY,MAAM;IAAEC,KAAK;IAAEC,QAAQ;IAAEC,OAAO;IAAEC,UAAU;IAAE,GAAGC;EAAW,CAAC,GACpEjB,UAAU,EAAEkB,KAAK,IAAIrB,YAAY;EAElC,OAAO;IACN,GAAGc,cAAc;IACjBO,KAAK,EAAED;EACR,CAAC;AACF;AAEA,SAASE,+BAA+BA,CAAE;EAAET;AAAU,CAAC,EAAG;EACzD,oBACChB,IAAA,CAACJ,WAAW;IAACoB,SAAS,EAAGA,SAAW;IAAAU,QAAA,EACjClC,EAAE,CAAE,0BAA2B;EAAC,CACtB,CAAC;AAEhB;AAEA,SAASmC,+BAA+BA,CAAE;EAAEC,QAAQ;EAAEZ;AAAU,CAAC,EAAG;EACnE,MAAMa,YAAY,GAAGpC,OAAO;EAC3B;EACAD,EAAE,CAAE,yBAA0B,CAAC,EAC/BoC,QAAQ,CAACE,QACV,CAAC;EACD,oBAAO9B,IAAA,CAACJ,WAAW;IAACoB,SAAS,EAAGA,SAAW;IAAAU,QAAA,EAAGG;EAAY,CAAe,CAAC;AAC3E;AAEA,SAASE,iCAAiCA,CAAE;EAAEL,QAAQ;EAAEM;AAAW,CAAC,EAAG;EACtE,oBACC9B,KAAA;IAAKsB,KAAK,EAAG;MAAES,QAAQ,EAAE;IAAW,CAAG;IAAAP,QAAA,GACpCM,UAAU,iBACXhC,IAAA;MACCwB,KAAK,EAAG;QACPS,QAAQ,EAAE,UAAU;QACpBC,GAAG,EAAE,KAAK;QACVC,IAAI,EAAE,KAAK;QACXC,SAAS,EAAE,MAAM;QACjBC,UAAU,EAAE;MACb,CAAG;MAAAX,QAAA,eAEH1B,IAAA,CAACH,OAAO,IAAE;IAAC,CACP,CACL,eACDG,IAAA;MAAKwB,KAAK,EAAG;QAAEc,OAAO,EAAEN,UAAU,GAAG,KAAK,GAAG;MAAE,CAAG;MAAAN,QAAA,EAC/CA;IAAQ,CACN,CAAC;EAAA,CACF,CAAC;AAER;AAEA,eAAe,SAASa,gBAAgBA,CAAEC,KAAK,EAAG;EACjD,MAAM;IACLlC,UAAU;IACVD,KAAK;IACLW,SAAS;IACTyB,UAAU,GAAG,KAAK;IAClBlC,YAAY;IACZmC,0BAA0B,GAAG,KAAK;IAClCC,wBAAwB,GAAGlB,+BAA+B;IAC1DmB,wBAAwB,GAAGjB,+BAA+B;IAC1DkB,0BAA0B,GAAGd;EAC9B,CAAC,GAAGS,KAAK;EAET,MAAMM,YAAY,GAAGxD,MAAM,CAAE,KAAM,CAAC;EACpC,MAAM,CAAE0C,UAAU,EAAEe,aAAa,CAAE,GAAGxD,QAAQ,CAAE,KAAM,CAAC;EACvD,MAAMyD,eAAe,GAAG1D,MAAM,CAAC,CAAC;EAChC,MAAM,CAAEsC,QAAQ,EAAEqB,WAAW,CAAE,GAAG1D,QAAQ,CAAE,IAAK,CAAC;EAClD,MAAM2D,SAAS,GAAG/D,WAAW,CAAEqD,KAAM,CAAC;EACtC,MAAM,CAAEW,SAAS,EAAEC,YAAY,CAAE,GAAG7D,QAAQ,CAAE,KAAM,CAAC;EAErD,SAAS8D,SAASA,CAAA,EAAG;IAAA,IAAAC,oBAAA,EAAAC,qBAAA;IACpB,IAAK,CAAET,YAAY,CAACU,OAAO,EAAG;MAC7B;IACD;IAEAJ,YAAY,CAAE,IAAK,CAAC;;IAEpB;IACA,MAAMK,OAAO,GAAGC,UAAU,CAAE,MAAM;MACjCX,aAAa,CAAE,IAAK,CAAC;IACtB,CAAC,EAAE,IAAK,CAAC;IAET,IAAIY,mBAAmB,GACtBrD,UAAU,IACVR,qCAAqC,CAAEO,KAAK,EAAEC,UAAW,CAAC;IAE3D,IAAKoC,0BAA0B,EAAG;MACjCiB,mBAAmB,GAClBlD,4BAA4B,CAAEkD,mBAAoB,CAAC;IACrD;;IAEA;IACA;IACA,MAAMC,aAAa,GAAG,MAAM,KAAKnB,UAAU;IAC3C,MAAMoB,aAAa,GAAGD,aAAa,GAChC,IAAI,IAAAN,oBAAA,GACJK,mBAAmB,cAAAL,oBAAA,cAAAA,oBAAA,GAAI,IAAI;IAC9B,MAAMQ,IAAI,GAAG1D,YAAY,CAAEC,KAAK,EAAEwD,aAAa,EAAEtD,YAAa,CAAC;IAC/D,MAAMwD,IAAI,GAAGH,aAAa,GACvB;MAAEtD,UAAU,GAAAiD,qBAAA,GAAEI,mBAAmB,cAAAJ,qBAAA,cAAAA,qBAAA,GAAI;IAAK,CAAC,GAC3C,IAAI;;IAEP;IACA;IACA,MAAMS,YAAY,GAAKhB,eAAe,CAACQ,OAAO,GAAG9D,QAAQ,CAAE;MAC1DoE,IAAI;MACJC,IAAI;MACJE,MAAM,EAAEL,aAAa,GAAG,MAAM,GAAG;IAClC,CAAE,CAAC,CACDM,IAAI,CAAIC,aAAa,IAAM;MAC3B,IACCrB,YAAY,CAACU,OAAO,IACpBQ,YAAY,KAAKhB,eAAe,CAACQ,OAAO,IACxCW,aAAa,EACZ;QACDlB,WAAW,CAAEkB,aAAa,CAACC,QAAS,CAAC;MACtC;IACD,CAAE,CAAC,CACFC,KAAK,CAAIC,KAAK,IAAM;MACpB,IACCxB,YAAY,CAACU,OAAO,IACpBQ,YAAY,KAAKhB,eAAe,CAACQ,OAAO,EACvC;QACDP,WAAW,CAAE;UACZqB,KAAK,EAAE,IAAI;UACXxC,QAAQ,EAAEwC,KAAK,CAACC;QACjB,CAAE,CAAC;MACJ;IACD,CAAE,CAAC,CACFC,OAAO,CAAE,MAAM;MACf,IACC1B,YAAY,CAACU,OAAO,IACpBQ,YAAY,KAAKhB,eAAe,CAACQ,OAAO,EACvC;QACDJ,YAAY,CAAE,KAAM,CAAC;QACrB;QACAL,aAAa,CAAE,KAAM,CAAC;QACtB0B,YAAY,CAAEhB,OAAQ,CAAC;MACxB;IACD,CAAE,CAAG;IAEN,OAAOO,YAAY;EACpB;EAEA,MAAMU,kBAAkB,GAAGxF,WAAW,CAAEmE,SAAS,EAAE,GAAI,CAAC;;EAExD;EACA;EACAhE,SAAS,CAAE,MAAM;IAChByD,YAAY,CAACU,OAAO,GAAG,IAAI;IAC3B,OAAO,MAAM;MACZV,YAAY,CAACU,OAAO,GAAG,KAAK;IAC7B,CAAC;EACF,CAAC,EAAE,EAAG,CAAC;EAEPnE,SAAS,CAAE,MAAM;IAChB;IACA;IACA,IAAK6D,SAAS,KAAKyB,SAAS,EAAG;MAC9BtB,SAAS,CAAC,CAAC;IACZ,CAAC,MAAM,IAAK,CAAEpE,aAAa,CAAEiE,SAAS,EAAEV,KAAM,CAAC,EAAG;MACjDkC,kBAAkB,CAAC,CAAC;IACrB;EACD,CAAE,CAAC;EAEH,MAAME,WAAW,GAAG,CAAC,CAAEhD,QAAQ;EAC/B,MAAMiD,gBAAgB,GAAGjD,QAAQ,KAAK,EAAE;EACxC,MAAMkD,QAAQ,GAAGlD,QAAQ,EAAE0C,KAAK;EAEhC,IAAKnB,SAAS,EAAG;IAChB,oBACCnD,IAAA,CAAC6C,0BAA0B;MAAA,GAAML,KAAK;MAAGR,UAAU,EAAGA,UAAY;MAAAN,QAAA,EAC/DkD,WAAW,iBACZ5E,IAAA,CAACZ,OAAO;QAAC4B,SAAS,EAAGA,SAAW;QAAAU,QAAA,EAAGE;MAAQ,CAAW;IACtD,CAC0B,CAAC;EAE/B;EAEA,IAAKiD,gBAAgB,IAAI,CAAED,WAAW,EAAG;IACxC,oBAAO5E,IAAA,CAAC2C,wBAAwB;MAAA,GAAMH;IAAK,CAAI,CAAC;EACjD;EAEA,IAAKsC,QAAQ,EAAG;IACf,oBAAO9E,IAAA,CAAC4C,wBAAwB;MAAChB,QAAQ,EAAGA,QAAU;MAAA,GAAMY;IAAK,CAAI,CAAC;EACvE;EAEA,oBAAOxC,IAAA,CAACZ,OAAO;IAAC4B,SAAS,EAAGA,SAAW;IAAAU,QAAA,EAAGE;EAAQ,CAAW,CAAC;AAC/D","ignoreList":[]}
1
+ {"version":3,"names":["fastDeepEqual","useDebounce","usePrevious","RawHTML","useCallback","useEffect","useLayoutEffect","useRef","useState","__","sprintf","apiFetch","addQueryArgs","Placeholder","Spinner","__experimentalSanitizeBlockAttributes","jsx","_jsx","jsxs","_jsxs","EMPTY_OBJECT","rendererPath","block","attributes","urlQueryArgs","context","removeBlockSupportAttributes","backgroundColor","borderColor","fontFamily","fontSize","gradient","textColor","className","restAttributes","border","color","elements","spacing","typography","restStyles","style","DefaultEmptyResponsePlaceholder","children","DefaultErrorResponsePlaceholder","response","errorMessage","errorMsg","DefaultLoadingResponsePlaceholder","showLoader","position","top","left","marginTop","marginLeft","opacity","ServerSideRender","props","EmptyResponsePlaceholder","ErrorResponsePlaceholder","LoadingResponsePlaceholder","isMountedRef","setShowLoader","fetchRequestRef","setResponse","prevProps","isLoading","setIsLoading","latestPropsRef","current","fetchData","_sanitizedAttributes","_sanitizedAttributes2","skipBlockSupportAttributes","httpMethod","timeout","setTimeout","sanitizedAttributes","isPostRequest","urlAttributes","path","data","fetchRequest","method","then","fetchResponse","rendered","catch","error","message","finally","clearTimeout","debouncedFetchData","undefined","hasResponse","hasEmptyResponse","hasError"],"sources":["@wordpress/server-side-render/src/server-side-render.js"],"sourcesContent":["/**\n * External dependencies\n */\nimport fastDeepEqual from 'fast-deep-equal/es6';\n\n/**\n * WordPress dependencies\n */\nimport { useDebounce, usePrevious } from '@wordpress/compose';\nimport {\n\tRawHTML,\n\tuseCallback,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from '@wordpress/element';\nimport { __, sprintf } from '@wordpress/i18n';\nimport apiFetch from '@wordpress/api-fetch';\nimport { addQueryArgs } from '@wordpress/url';\nimport { Placeholder, Spinner } from '@wordpress/components';\nimport { __experimentalSanitizeBlockAttributes } from '@wordpress/blocks';\n\nconst EMPTY_OBJECT = {};\n\nexport function rendererPath( block, attributes = null, urlQueryArgs = {} ) {\n\treturn addQueryArgs( `/wp/v2/block-renderer/${ block }`, {\n\t\tcontext: 'edit',\n\t\t...( null !== attributes ? { attributes } : {} ),\n\t\t...urlQueryArgs,\n\t} );\n}\n\nexport function removeBlockSupportAttributes( attributes ) {\n\tconst {\n\t\tbackgroundColor,\n\t\tborderColor,\n\t\tfontFamily,\n\t\tfontSize,\n\t\tgradient,\n\t\ttextColor,\n\t\tclassName,\n\t\t...restAttributes\n\t} = attributes;\n\n\tconst { border, color, elements, spacing, typography, ...restStyles } =\n\t\tattributes?.style || EMPTY_OBJECT;\n\n\treturn {\n\t\t...restAttributes,\n\t\tstyle: restStyles,\n\t};\n}\n\nfunction DefaultEmptyResponsePlaceholder( { className } ) {\n\treturn (\n\t\t<Placeholder className={ className }>\n\t\t\t{ __( 'Block rendered as empty.' ) }\n\t\t</Placeholder>\n\t);\n}\n\nfunction DefaultErrorResponsePlaceholder( { response, className } ) {\n\tconst errorMessage = sprintf(\n\t\t// translators: %s: error message describing the problem\n\t\t__( 'Error loading block: %s' ),\n\t\tresponse.errorMsg\n\t);\n\treturn <Placeholder className={ className }>{ errorMessage }</Placeholder>;\n}\n\nfunction DefaultLoadingResponsePlaceholder( { children, showLoader } ) {\n\treturn (\n\t\t<div style={ { position: 'relative' } }>\n\t\t\t{ showLoader && (\n\t\t\t\t<div\n\t\t\t\t\tstyle={ {\n\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\ttop: '50%',\n\t\t\t\t\t\tleft: '50%',\n\t\t\t\t\t\tmarginTop: '-9px',\n\t\t\t\t\t\tmarginLeft: '-9px',\n\t\t\t\t\t} }\n\t\t\t\t>\n\t\t\t\t\t<Spinner />\n\t\t\t\t</div>\n\t\t\t) }\n\t\t\t<div style={ { opacity: showLoader ? '0.3' : 1 } }>\n\t\t\t\t{ children }\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport default function ServerSideRender( props ) {\n\tconst {\n\t\tclassName,\n\t\tEmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,\n\t\tErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,\n\t\tLoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder,\n\t} = props;\n\n\tconst isMountedRef = useRef( false );\n\tconst [ showLoader, setShowLoader ] = useState( false );\n\tconst fetchRequestRef = useRef();\n\tconst [ response, setResponse ] = useState( null );\n\tconst prevProps = usePrevious( props );\n\tconst [ isLoading, setIsLoading ] = useState( false );\n\tconst latestPropsRef = useRef( props );\n\n\tuseLayoutEffect( () => {\n\t\tlatestPropsRef.current = props;\n\t}, [ props ] );\n\n\tconst fetchData = useCallback( () => {\n\t\tif ( ! isMountedRef.current ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst {\n\t\t\tattributes,\n\t\t\tblock,\n\t\t\tskipBlockSupportAttributes = false,\n\t\t\thttpMethod = 'GET',\n\t\t\turlQueryArgs,\n\t\t} = latestPropsRef.current;\n\n\t\tsetIsLoading( true );\n\n\t\t// Schedule showing the Spinner after 1 second.\n\t\tconst timeout = setTimeout( () => {\n\t\t\tsetShowLoader( true );\n\t\t}, 1000 );\n\n\t\tlet sanitizedAttributes =\n\t\t\tattributes &&\n\t\t\t__experimentalSanitizeBlockAttributes( block, attributes );\n\n\t\tif ( skipBlockSupportAttributes ) {\n\t\t\tsanitizedAttributes =\n\t\t\t\tremoveBlockSupportAttributes( sanitizedAttributes );\n\t\t}\n\n\t\t// If httpMethod is 'POST', send the attributes in the request body instead of the URL.\n\t\t// This allows sending a larger attributes object than in a GET request, where the attributes are in the URL.\n\t\tconst isPostRequest = 'POST' === httpMethod;\n\t\tconst urlAttributes = isPostRequest\n\t\t\t? null\n\t\t\t: sanitizedAttributes ?? null;\n\t\tconst path = rendererPath( block, urlAttributes, urlQueryArgs );\n\t\tconst data = isPostRequest\n\t\t\t? { attributes: sanitizedAttributes ?? null }\n\t\t\t: null;\n\n\t\t// Store the latest fetch request so that when we process it, we can\n\t\t// check if it is the current request, to avoid race conditions on slow networks.\n\t\tconst fetchRequest = ( fetchRequestRef.current = apiFetch( {\n\t\t\tpath,\n\t\t\tdata,\n\t\t\tmethod: isPostRequest ? 'POST' : 'GET',\n\t\t} )\n\t\t\t.then( ( fetchResponse ) => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current &&\n\t\t\t\t\tfetchResponse\n\t\t\t\t) {\n\t\t\t\t\tsetResponse( fetchResponse.rendered );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.catch( ( error ) => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current\n\t\t\t\t) {\n\t\t\t\t\tsetResponse( {\n\t\t\t\t\t\terror: true,\n\t\t\t\t\t\terrorMsg: error.message,\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.finally( () => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current\n\t\t\t\t) {\n\t\t\t\t\tsetIsLoading( false );\n\t\t\t\t\t// Cancel the timeout to show the Spinner.\n\t\t\t\t\tsetShowLoader( false );\n\t\t\t\t\tclearTimeout( timeout );\n\t\t\t\t}\n\t\t\t} ) );\n\n\t\treturn fetchRequest;\n\t}, [] );\n\n\tconst debouncedFetchData = useDebounce( fetchData, 500 );\n\n\t// When the component unmounts, set isMountedRef to false. This will\n\t// let the async fetch callbacks know when to stop.\n\tuseEffect( () => {\n\t\tisMountedRef.current = true;\n\t\treturn () => {\n\t\t\tisMountedRef.current = false;\n\t\t};\n\t}, [] );\n\n\tuseEffect( () => {\n\t\t// Don't debounce the first fetch. This ensures that the first render\n\t\t// shows data as soon as possible.\n\t\tif ( prevProps === undefined ) {\n\t\t\tfetchData();\n\t\t} else if ( ! fastDeepEqual( prevProps, props ) ) {\n\t\t\tdebouncedFetchData();\n\t\t}\n\t} );\n\n\tconst hasResponse = !! response;\n\tconst hasEmptyResponse = response === '';\n\tconst hasError = !! response?.error;\n\n\tif ( isLoading ) {\n\t\treturn (\n\t\t\t<LoadingResponsePlaceholder { ...props } showLoader={ showLoader }>\n\t\t\t\t{ hasResponse && ! hasError && (\n\t\t\t\t\t<RawHTML className={ className }>{ response }</RawHTML>\n\t\t\t\t) }\n\t\t\t</LoadingResponsePlaceholder>\n\t\t);\n\t}\n\n\tif ( hasEmptyResponse || ! hasResponse ) {\n\t\treturn <EmptyResponsePlaceholder { ...props } />;\n\t}\n\n\tif ( hasError ) {\n\t\treturn <ErrorResponsePlaceholder response={ response } { ...props } />;\n\t}\n\n\treturn <RawHTML className={ className }>{ response }</RawHTML>;\n}\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/server-side-render",
3
- "version": "5.21.0",
3
+ "version": "5.23.0",
4
4
  "description": "The component used with WordPress to server-side render a preview of dynamic blocks to display in the editor.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -29,15 +29,15 @@
29
29
  "wpScript": true,
30
30
  "dependencies": {
31
31
  "@babel/runtime": "7.25.7",
32
- "@wordpress/api-fetch": "^7.21.0",
33
- "@wordpress/blocks": "^14.10.0",
34
- "@wordpress/components": "^29.7.0",
35
- "@wordpress/compose": "^7.21.0",
36
- "@wordpress/data": "^10.21.0",
37
- "@wordpress/deprecated": "^4.21.0",
38
- "@wordpress/element": "^6.21.0",
39
- "@wordpress/i18n": "^5.21.0",
40
- "@wordpress/url": "^4.21.0",
32
+ "@wordpress/api-fetch": "^7.23.0",
33
+ "@wordpress/blocks": "^14.12.0",
34
+ "@wordpress/components": "^29.9.0",
35
+ "@wordpress/compose": "^7.23.0",
36
+ "@wordpress/data": "^10.23.0",
37
+ "@wordpress/deprecated": "^4.23.0",
38
+ "@wordpress/element": "^6.23.0",
39
+ "@wordpress/i18n": "^5.23.0",
40
+ "@wordpress/url": "^4.23.0",
41
41
  "fast-deep-equal": "^3.1.3"
42
42
  },
43
43
  "peerDependencies": {
@@ -47,5 +47,5 @@
47
47
  "publishConfig": {
48
48
  "access": "public"
49
49
  },
50
- "gitHead": "104af00f9abcd7a4d36b87e648f148c72cc4ea5f"
50
+ "gitHead": "ab5c79cd40adbb68898536c50e035b0a734338ea"
51
51
  }
@@ -7,7 +7,14 @@ import fastDeepEqual from 'fast-deep-equal/es6';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { useDebounce, usePrevious } from '@wordpress/compose';
10
- import { RawHTML, useEffect, useRef, useState } from '@wordpress/element';
10
+ import {
11
+ RawHTML,
12
+ useCallback,
13
+ useEffect,
14
+ useLayoutEffect,
15
+ useRef,
16
+ useState,
17
+ } from '@wordpress/element';
11
18
  import { __, sprintf } from '@wordpress/i18n';
12
19
  import apiFetch from '@wordpress/api-fetch';
13
20
  import { addQueryArgs } from '@wordpress/url';
@@ -87,12 +94,7 @@ function DefaultLoadingResponsePlaceholder( { children, showLoader } ) {
87
94
 
88
95
  export default function ServerSideRender( props ) {
89
96
  const {
90
- attributes,
91
- block,
92
97
  className,
93
- httpMethod = 'GET',
94
- urlQueryArgs,
95
- skipBlockSupportAttributes = false,
96
98
  EmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,
97
99
  ErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,
98
100
  LoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder,
@@ -104,12 +106,25 @@ export default function ServerSideRender( props ) {
104
106
  const [ response, setResponse ] = useState( null );
105
107
  const prevProps = usePrevious( props );
106
108
  const [ isLoading, setIsLoading ] = useState( false );
109
+ const latestPropsRef = useRef( props );
107
110
 
108
- function fetchData() {
111
+ useLayoutEffect( () => {
112
+ latestPropsRef.current = props;
113
+ }, [ props ] );
114
+
115
+ const fetchData = useCallback( () => {
109
116
  if ( ! isMountedRef.current ) {
110
117
  return;
111
118
  }
112
119
 
120
+ const {
121
+ attributes,
122
+ block,
123
+ skipBlockSupportAttributes = false,
124
+ httpMethod = 'GET',
125
+ urlQueryArgs,
126
+ } = latestPropsRef.current;
127
+
113
128
  setIsLoading( true );
114
129
 
115
130
  // Schedule showing the Spinner after 1 second.
@@ -177,7 +192,7 @@ export default function ServerSideRender( props ) {
177
192
  } ) );
178
193
 
179
194
  return fetchRequest;
180
- }
195
+ }, [] );
181
196
 
182
197
  const debouncedFetchData = useDebounce( fetchData, 500 );
183
198
 
@@ -202,12 +217,12 @@ export default function ServerSideRender( props ) {
202
217
 
203
218
  const hasResponse = !! response;
204
219
  const hasEmptyResponse = response === '';
205
- const hasError = response?.error;
220
+ const hasError = !! response?.error;
206
221
 
207
222
  if ( isLoading ) {
208
223
  return (
209
224
  <LoadingResponsePlaceholder { ...props } showLoader={ showLoader }>
210
- { hasResponse && (
225
+ { hasResponse && ! hasError && (
211
226
  <RawHTML className={ className }>{ response }</RawHTML>
212
227
  ) }
213
228
  </LoadingResponsePlaceholder>