@wordpress/server-side-render 3.0.2 → 3.0.3
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/README.md
CHANGED
|
@@ -18,7 +18,7 @@ Install the module
|
|
|
18
18
|
npm install @wordpress/server-side-render --save
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
_This package assumes that your code will run in an **ES2015+** environment. If you're using an environment that has limited or no support for
|
|
21
|
+
_This package assumes that your code will run in an **ES2015+** environment. If you're using an environment that has limited or no support for such language features and APIs, you should include [the polyfill shipped in `@wordpress/babel-preset-default`](https://github.com/WordPress/gutenberg/tree/HEAD/packages/babel-preset-default#polyfill) in your code._
|
|
22
22
|
|
|
23
23
|
## Usage
|
|
24
24
|
|
|
@@ -58,6 +58,7 @@ The HTTP request method to use, either 'GET' or 'POST'. It's 'GET' by default. T
|
|
|
58
58
|
- Required: No
|
|
59
59
|
|
|
60
60
|
#### Example:
|
|
61
|
+
|
|
61
62
|
```php
|
|
62
63
|
function add_rest_method( $endpoints ) {
|
|
63
64
|
if ( is_wp_version_compatible( '5.5' ) ) {
|
|
@@ -108,9 +109,7 @@ The component is rendered while the API request is being processed (loading stat
|
|
|
108
109
|
|
|
109
110
|
```jsx
|
|
110
111
|
const MyServerSideRender = () => (
|
|
111
|
-
<ServerSideRender
|
|
112
|
-
LoadingResponsePlaceholder={ MyAmazingPlaceholder }
|
|
113
|
-
/>
|
|
112
|
+
<ServerSideRender LoadingResponsePlaceholder={ MyAmazingPlaceholder } />
|
|
114
113
|
);
|
|
115
114
|
```
|
|
116
115
|
|
|
@@ -63,11 +63,26 @@ function DefaultErrorResponsePlaceholder({
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
function DefaultLoadingResponsePlaceholder({
|
|
66
|
-
|
|
66
|
+
children,
|
|
67
|
+
showLoader
|
|
67
68
|
}) {
|
|
68
|
-
return (0, _element.createElement)(
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
return (0, _element.createElement)("div", {
|
|
70
|
+
style: {
|
|
71
|
+
position: 'relative'
|
|
72
|
+
}
|
|
73
|
+
}, showLoader && (0, _element.createElement)("div", {
|
|
74
|
+
style: {
|
|
75
|
+
position: 'absolute',
|
|
76
|
+
top: '50%',
|
|
77
|
+
left: '50%',
|
|
78
|
+
marginTop: '-9px',
|
|
79
|
+
marginLeft: '-9px'
|
|
80
|
+
}
|
|
81
|
+
}, (0, _element.createElement)(_components.Spinner, null)), (0, _element.createElement)("div", {
|
|
82
|
+
style: {
|
|
83
|
+
opacity: showLoader ? '0.3' : 1
|
|
84
|
+
}
|
|
85
|
+
}, children));
|
|
71
86
|
}
|
|
72
87
|
|
|
73
88
|
function ServerSideRender(props) {
|
|
@@ -82,8 +97,10 @@ function ServerSideRender(props) {
|
|
|
82
97
|
LoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder
|
|
83
98
|
} = props;
|
|
84
99
|
const isMountedRef = (0, _element.useRef)(true);
|
|
100
|
+
const [showLoader, setShowLoader] = (0, _element.useState)(false);
|
|
85
101
|
const fetchRequestRef = (0, _element.useRef)();
|
|
86
102
|
const [response, setResponse] = (0, _element.useState)(null);
|
|
103
|
+
const prevResponse = (0, _compose.usePrevious)(response);
|
|
87
104
|
const prevProps = (0, _compose.usePrevious)(props);
|
|
88
105
|
|
|
89
106
|
function fetchData() {
|
|
@@ -140,11 +157,31 @@ function ServerSideRender(props) {
|
|
|
140
157
|
debouncedFetchData();
|
|
141
158
|
}
|
|
142
159
|
});
|
|
160
|
+
/**
|
|
161
|
+
* Effect to handle showing the loading placeholder.
|
|
162
|
+
* Show it only if there is no previous response or
|
|
163
|
+
* the request takes more than one second.
|
|
164
|
+
*/
|
|
165
|
+
|
|
166
|
+
(0, _element.useEffect)(() => {
|
|
167
|
+
if (response !== null) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const timeout = setTimeout(() => {
|
|
172
|
+
setShowLoader(true);
|
|
173
|
+
}, 1000);
|
|
174
|
+
return () => clearTimeout(timeout);
|
|
175
|
+
}, [response]);
|
|
143
176
|
|
|
144
177
|
if (response === '') {
|
|
145
178
|
return (0, _element.createElement)(EmptyResponsePlaceholder, props);
|
|
146
179
|
} else if (!response) {
|
|
147
|
-
return (0, _element.createElement)(LoadingResponsePlaceholder, props
|
|
180
|
+
return (0, _element.createElement)(LoadingResponsePlaceholder, (0, _extends2.default)({}, props, {
|
|
181
|
+
showLoader: !prevResponse || showLoader
|
|
182
|
+
}), !!prevResponse && (0, _element.createElement)(_element.RawHTML, {
|
|
183
|
+
className: className
|
|
184
|
+
}, prevResponse));
|
|
148
185
|
} else if (response.error) {
|
|
149
186
|
return (0, _element.createElement)(ErrorResponsePlaceholder, (0, _extends2.default)({
|
|
150
187
|
response: response
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["@wordpress/server-side-render/src/server-side-render.js"],"names":["rendererPath","block","attributes","urlQueryArgs","context","DefaultEmptyResponsePlaceholder","className","DefaultErrorResponsePlaceholder","response","errorMessage","errorMsg","DefaultLoadingResponsePlaceholder","ServerSideRender","props","httpMethod","EmptyResponsePlaceholder","ErrorResponsePlaceholder","LoadingResponsePlaceholder","isMountedRef","fetchRequestRef","setResponse","prevProps","fetchData","current","sanitizedAttributes","isPostRequest","urlAttributes","path","data","fetchRequest","method","then","fetchResponse","rendered","catch","error","message","debouncedFetchData","undefined"],"mappings":";;;;;;;;;;AASA;;;;AANA;;AAKA;;AAEA;;AACA;;AACA;;AACA;;AACA;;AAdA;AACA;AACA;;AAGA;AACA;AACA;AASO,SAASA,YAAT,CAAuBC,KAAvB,EAA8BC,UAAU,GAAG,IAA3C,EAAiDC,YAAY,GAAG,EAAhE,EAAqE;AAC3E,SAAO,uBAAe,yBAAyBF,KAAO,EAA/C,EAAkD;AACxDG,IAAAA,OAAO,EAAE,MAD+C;AAExD,QAAK,SAASF,UAAT,GAAsB;AAAEA,MAAAA;AAAF,KAAtB,GAAuC,EAA5C,CAFwD;AAGxD,OAAGC;AAHqD,GAAlD,CAAP;AAKA;;AAED,SAASE,+BAAT,CAA0C;AAAEC,EAAAA;AAAF,CAA1C,EAA0D;AACzD,SACC,4BAAC,uBAAD;AAAa,IAAA,SAAS,EAAGA;AAAzB,KACG,cAAI,0BAAJ,CADH,CADD;AAKA;;AAED,SAASC,+BAAT,CAA0C;AAAEC,EAAAA,QAAF;AAAYF,EAAAA;AAAZ,CAA1C,EAAoE;AACnE,QAAMG,YAAY,GAAG,oBACpB;AACA,gBAAI,yBAAJ,CAFoB,EAGpBD,QAAQ,CAACE,QAHW,CAArB;AAKA,SAAO,4BAAC,uBAAD;AAAa,IAAA,SAAS,EAAGJ;AAAzB,KAAuCG,YAAvC,CAAP;AACA;;AAED,SAASE,iCAAT,CAA4C;AAAEL,EAAAA;AAAF,CAA5C,EAA4D;AAC3D,SACC,4BAAC,uBAAD;AAAa,IAAA,SAAS,EAAGA;AAAzB,KACC,4BAAC,mBAAD,OADD,CADD;AAKA;;AAEc,SAASM,gBAAT,CAA2BC,KAA3B,EAAmC;AACjD,QAAM;AACLX,IAAAA,UADK;AAELD,IAAAA,KAFK;AAGLK,IAAAA,SAHK;AAILQ,IAAAA,UAAU,GAAG,KAJR;AAKLX,IAAAA,YALK;AAMLY,IAAAA,wBAAwB,GAAGV,+BANtB;AAOLW,IAAAA,wBAAwB,GAAGT,+BAPtB;AAQLU,IAAAA,0BAA0B,GAAGN;AARxB,MASFE,KATJ;AAWA,QAAMK,YAAY,GAAG,qBAAQ,IAAR,CAArB;AACA,QAAMC,eAAe,GAAG,sBAAxB;AACA,QAAM,CAAEX,QAAF,EAAYY,WAAZ,IAA4B,uBAAU,IAAV,CAAlC;AACA,QAAMC,SAAS,GAAG,0BAAaR,KAAb,CAAlB;;AAEA,WAASS,SAAT,GAAqB;AACpB,QAAK,CAAEJ,YAAY,CAACK,OAApB,EAA8B;AAC7B;AACA;;AACD,QAAK,SAASf,QAAd,EAAyB;AACxBY,MAAAA,WAAW,CAAE,IAAF,CAAX;AACA;;AAED,UAAMI,mBAAmB,GACxBtB,UAAU,IACV,mDAAuCD,KAAvC,EAA8CC,UAA9C,CAFD,CARoB,CAYpB;AACA;;AACA,UAAMuB,aAAa,GAAG,WAAWX,UAAjC;AACA,UAAMY,aAAa,GAAGD,aAAa,GAChC,IADgC,GAEhCD,mBAFgC,aAEhCA,mBAFgC,cAEhCA,mBAFgC,GAET,IAF1B;AAGA,UAAMG,IAAI,GAAG3B,YAAY,CAAEC,KAAF,EAASyB,aAAT,EAAwBvB,YAAxB,CAAzB;AACA,UAAMyB,IAAI,GAAGH,aAAa,GACvB;AAAEvB,MAAAA,UAAU,EAAEsB,mBAAF,aAAEA,mBAAF,cAAEA,mBAAF,GAAyB;AAArC,KADuB,GAEvB,IAFH,CAnBoB,CAuBpB;AACA;;AACA,UAAMK,YAAY,GAAKV,eAAe,CAACI,OAAhB,GAA0B,uBAAU;AAC1DI,MAAAA,IAD0D;AAE1DC,MAAAA,IAF0D;AAG1DE,MAAAA,MAAM,EAAEL,aAAa,GAAG,MAAH,GAAY;AAHyB,KAAV,EAK/CM,IAL+C,CAKvCC,aAAF,IAAqB;AAC3B,UACCd,YAAY,CAACK,OAAb,IACAM,YAAY,KAAKV,eAAe,CAACI,OADjC,IAEAS,aAHD,EAIE;AACDZ,QAAAA,WAAW,CAAEY,aAAa,CAACC,QAAhB,CAAX;AACA;AACD,KAb+C,EAc/CC,KAd+C,CActCC,KAAF,IAAa;AACpB,UACCjB,YAAY,CAACK,OAAb,IACAM,YAAY,KAAKV,eAAe,CAACI,OAFlC,EAGE;AACDH,QAAAA,WAAW,CAAE;AACZe,UAAAA,KAAK,EAAE,IADK;AAEZzB,UAAAA,QAAQ,EAAEyB,KAAK,CAACC;AAFJ,SAAF,CAAX;AAIA;AACD,KAxB+C,CAAjD;AA0BA,WAAOP,YAAP;AACA;;AAED,QAAMQ,kBAAkB,GAAG,0BAAaf,SAAb,EAAwB,GAAxB,CAA3B,CAvEiD,CAyEjD;AACA;;AACA,0BACC,MAAM,MAAM;AACXJ,IAAAA,YAAY,CAACK,OAAb,GAAuB,KAAvB;AACA,GAHF,EAIC,EAJD;AAOA,0BAAW,MAAM;AAChB;AACA;AACA,QAAKF,SAAS,KAAKiB,SAAnB,EAA+B;AAC9BhB,MAAAA,SAAS;AACT,KAFD,MAEO,IAAK,CAAE,qBAASD,SAAT,EAAoBR,KAApB,CAAP,EAAqC;AAC3CwB,MAAAA,kBAAkB;AAClB;AACD,GARD;;AAUA,MAAK7B,QAAQ,KAAK,EAAlB,EAAuB;AACtB,WAAO,4BAAC,wBAAD,EAA+BK,KAA/B,CAAP;AACA,GAFD,MAEO,IAAK,CAAEL,QAAP,EAAkB;AACxB,WAAO,4BAAC,0BAAD,EAAiCK,KAAjC,CAAP;AACA,GAFM,MAEA,IAAKL,QAAQ,CAAC2B,KAAd,EAAsB;AAC5B,WAAO,4BAAC,wBAAD;AAA0B,MAAA,QAAQ,EAAG3B;AAArC,OAAqDK,KAArD,EAAP;AACA;;AAED,SAAO,4BAAC,gBAAD;AAAS,IAAA,SAAS,EAAGP;AAArB,KAAmCE,QAAnC,CAAP;AACA","sourcesContent":["/**\n * External dependencies\n */\nimport { isEqual } from 'lodash';\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\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\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( { className } ) {\n\treturn (\n\t\t<Placeholder className={ className }>\n\t\t\t<Spinner />\n\t\t</Placeholder>\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\tEmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,\n\t\tErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,\n\t\tLoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder,\n\t} = props;\n\n\tconst isMountedRef = useRef( true );\n\tconst fetchRequestRef = useRef();\n\tconst [ response, setResponse ] = useState( null );\n\tconst prevProps = usePrevious( props );\n\n\tfunction fetchData() {\n\t\tif ( ! isMountedRef.current ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( null !== response ) {\n\t\t\tsetResponse( null );\n\t\t}\n\n\t\tconst sanitizedAttributes =\n\t\t\tattributes &&\n\t\t\t__experimentalSanitizeBlockAttributes( block, attributes );\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\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\t() => () => {\n\t\t\tisMountedRef.current = false;\n\t\t},\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 ( ! isEqual( prevProps, props ) ) {\n\t\t\tdebouncedFetchData();\n\t\t}\n\t} );\n\n\tif ( response === '' ) {\n\t\treturn <EmptyResponsePlaceholder { ...props } />;\n\t} else if ( ! response ) {\n\t\treturn <LoadingResponsePlaceholder { ...props } />;\n\t} else if ( response.error ) {\n\t\treturn <ErrorResponsePlaceholder response={ response } { ...props } />;\n\t}\n\n\treturn <RawHTML className={ className }>{ response }</RawHTML>;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["@wordpress/server-side-render/src/server-side-render.js"],"names":["rendererPath","block","attributes","urlQueryArgs","context","DefaultEmptyResponsePlaceholder","className","DefaultErrorResponsePlaceholder","response","errorMessage","errorMsg","DefaultLoadingResponsePlaceholder","children","showLoader","position","top","left","marginTop","marginLeft","opacity","ServerSideRender","props","httpMethod","EmptyResponsePlaceholder","ErrorResponsePlaceholder","LoadingResponsePlaceholder","isMountedRef","setShowLoader","fetchRequestRef","setResponse","prevResponse","prevProps","fetchData","current","sanitizedAttributes","isPostRequest","urlAttributes","path","data","fetchRequest","method","then","fetchResponse","rendered","catch","error","message","debouncedFetchData","undefined","timeout","setTimeout","clearTimeout"],"mappings":";;;;;;;;;;AASA;;;;AANA;;AAKA;;AAEA;;AACA;;AACA;;AACA;;AACA;;AAdA;AACA;AACA;;AAGA;AACA;AACA;AASO,SAASA,YAAT,CAAuBC,KAAvB,EAA8BC,UAAU,GAAG,IAA3C,EAAiDC,YAAY,GAAG,EAAhE,EAAqE;AAC3E,SAAO,uBAAe,yBAAyBF,KAAO,EAA/C,EAAkD;AACxDG,IAAAA,OAAO,EAAE,MAD+C;AAExD,QAAK,SAASF,UAAT,GAAsB;AAAEA,MAAAA;AAAF,KAAtB,GAAuC,EAA5C,CAFwD;AAGxD,OAAGC;AAHqD,GAAlD,CAAP;AAKA;;AAED,SAASE,+BAAT,CAA0C;AAAEC,EAAAA;AAAF,CAA1C,EAA0D;AACzD,SACC,4BAAC,uBAAD;AAAa,IAAA,SAAS,EAAGA;AAAzB,KACG,cAAI,0BAAJ,CADH,CADD;AAKA;;AAED,SAASC,+BAAT,CAA0C;AAAEC,EAAAA,QAAF;AAAYF,EAAAA;AAAZ,CAA1C,EAAoE;AACnE,QAAMG,YAAY,GAAG,oBACpB;AACA,gBAAI,yBAAJ,CAFoB,EAGpBD,QAAQ,CAACE,QAHW,CAArB;AAKA,SAAO,4BAAC,uBAAD;AAAa,IAAA,SAAS,EAAGJ;AAAzB,KAAuCG,YAAvC,CAAP;AACA;;AAED,SAASE,iCAAT,CAA4C;AAAEC,EAAAA,QAAF;AAAYC,EAAAA;AAAZ,CAA5C,EAAuE;AACtE,SACC;AAAK,IAAA,KAAK,EAAG;AAAEC,MAAAA,QAAQ,EAAE;AAAZ;AAAb,KACGD,UAAU,IACX;AACC,IAAA,KAAK,EAAG;AACPC,MAAAA,QAAQ,EAAE,UADH;AAEPC,MAAAA,GAAG,EAAE,KAFE;AAGPC,MAAAA,IAAI,EAAE,KAHC;AAIPC,MAAAA,SAAS,EAAE,MAJJ;AAKPC,MAAAA,UAAU,EAAE;AALL;AADT,KASC,4BAAC,mBAAD,OATD,CAFF,EAcC;AAAK,IAAA,KAAK,EAAG;AAAEC,MAAAA,OAAO,EAAEN,UAAU,GAAG,KAAH,GAAW;AAAhC;AAAb,KACGD,QADH,CAdD,CADD;AAoBA;;AAEc,SAASQ,gBAAT,CAA2BC,KAA3B,EAAmC;AACjD,QAAM;AACLnB,IAAAA,UADK;AAELD,IAAAA,KAFK;AAGLK,IAAAA,SAHK;AAILgB,IAAAA,UAAU,GAAG,KAJR;AAKLnB,IAAAA,YALK;AAMLoB,IAAAA,wBAAwB,GAAGlB,+BANtB;AAOLmB,IAAAA,wBAAwB,GAAGjB,+BAPtB;AAQLkB,IAAAA,0BAA0B,GAAGd;AARxB,MASFU,KATJ;AAWA,QAAMK,YAAY,GAAG,qBAAQ,IAAR,CAArB;AACA,QAAM,CAAEb,UAAF,EAAcc,aAAd,IAAgC,uBAAU,KAAV,CAAtC;AACA,QAAMC,eAAe,GAAG,sBAAxB;AACA,QAAM,CAAEpB,QAAF,EAAYqB,WAAZ,IAA4B,uBAAU,IAAV,CAAlC;AACA,QAAMC,YAAY,GAAG,0BAAatB,QAAb,CAArB;AACA,QAAMuB,SAAS,GAAG,0BAAaV,KAAb,CAAlB;;AAEA,WAASW,SAAT,GAAqB;AACpB,QAAK,CAAEN,YAAY,CAACO,OAApB,EAA8B;AAC7B;AACA;;AACD,QAAK,SAASzB,QAAd,EAAyB;AACxBqB,MAAAA,WAAW,CAAE,IAAF,CAAX;AACA;;AAED,UAAMK,mBAAmB,GACxBhC,UAAU,IACV,mDAAuCD,KAAvC,EAA8CC,UAA9C,CAFD,CARoB,CAYpB;AACA;;AACA,UAAMiC,aAAa,GAAG,WAAWb,UAAjC;AACA,UAAMc,aAAa,GAAGD,aAAa,GAChC,IADgC,GAEhCD,mBAFgC,aAEhCA,mBAFgC,cAEhCA,mBAFgC,GAET,IAF1B;AAGA,UAAMG,IAAI,GAAGrC,YAAY,CAAEC,KAAF,EAASmC,aAAT,EAAwBjC,YAAxB,CAAzB;AACA,UAAMmC,IAAI,GAAGH,aAAa,GACvB;AAAEjC,MAAAA,UAAU,EAAEgC,mBAAF,aAAEA,mBAAF,cAAEA,mBAAF,GAAyB;AAArC,KADuB,GAEvB,IAFH,CAnBoB,CAuBpB;AACA;;AACA,UAAMK,YAAY,GAAKX,eAAe,CAACK,OAAhB,GAA0B,uBAAU;AAC1DI,MAAAA,IAD0D;AAE1DC,MAAAA,IAF0D;AAG1DE,MAAAA,MAAM,EAAEL,aAAa,GAAG,MAAH,GAAY;AAHyB,KAAV,EAK/CM,IAL+C,CAKvCC,aAAF,IAAqB;AAC3B,UACChB,YAAY,CAACO,OAAb,IACAM,YAAY,KAAKX,eAAe,CAACK,OADjC,IAEAS,aAHD,EAIE;AACDb,QAAAA,WAAW,CAAEa,aAAa,CAACC,QAAhB,CAAX;AACA;AACD,KAb+C,EAc/CC,KAd+C,CActCC,KAAF,IAAa;AACpB,UACCnB,YAAY,CAACO,OAAb,IACAM,YAAY,KAAKX,eAAe,CAACK,OAFlC,EAGE;AACDJ,QAAAA,WAAW,CAAE;AACZgB,UAAAA,KAAK,EAAE,IADK;AAEZnC,UAAAA,QAAQ,EAAEmC,KAAK,CAACC;AAFJ,SAAF,CAAX;AAIA;AACD,KAxB+C,CAAjD;AA0BA,WAAOP,YAAP;AACA;;AAED,QAAMQ,kBAAkB,GAAG,0BAAaf,SAAb,EAAwB,GAAxB,CAA3B,CAzEiD,CA2EjD;AACA;;AACA,0BACC,MAAM,MAAM;AACXN,IAAAA,YAAY,CAACO,OAAb,GAAuB,KAAvB;AACA,GAHF,EAIC,EAJD;AAOA,0BAAW,MAAM;AAChB;AACA;AACA,QAAKF,SAAS,KAAKiB,SAAnB,EAA+B;AAC9BhB,MAAAA,SAAS;AACT,KAFD,MAEO,IAAK,CAAE,qBAASD,SAAT,EAAoBV,KAApB,CAAP,EAAqC;AAC3C0B,MAAAA,kBAAkB;AAClB;AACD,GARD;AAUA;AACD;AACA;AACA;AACA;;AACC,0BAAW,MAAM;AAChB,QAAKvC,QAAQ,KAAK,IAAlB,EAAyB;AACxB;AACA;;AACD,UAAMyC,OAAO,GAAGC,UAAU,CAAE,MAAM;AACjCvB,MAAAA,aAAa,CAAE,IAAF,CAAb;AACA,KAFyB,EAEvB,IAFuB,CAA1B;AAGA,WAAO,MAAMwB,YAAY,CAAEF,OAAF,CAAzB;AACA,GARD,EAQG,CAAEzC,QAAF,CARH;;AAUA,MAAKA,QAAQ,KAAK,EAAlB,EAAuB;AACtB,WAAO,4BAAC,wBAAD,EAA+Ba,KAA/B,CAAP;AACA,GAFD,MAEO,IAAK,CAAEb,QAAP,EAAkB;AACxB,WACC,4BAAC,0BAAD,6BACMa,KADN;AAEC,MAAA,UAAU,EAAG,CAAES,YAAF,IAAkBjB;AAFhC,QAIG,CAAC,CAAEiB,YAAH,IACD,4BAAC,gBAAD;AAAS,MAAA,SAAS,EAAGxB;AAArB,OAAmCwB,YAAnC,CALF,CADD;AAUA,GAXM,MAWA,IAAKtB,QAAQ,CAACqC,KAAd,EAAsB;AAC5B,WAAO,4BAAC,wBAAD;AAA0B,MAAA,QAAQ,EAAGrC;AAArC,OAAqDa,KAArD,EAAP;AACA;;AAED,SAAO,4BAAC,gBAAD;AAAS,IAAA,SAAS,EAAGf;AAArB,KAAmCE,QAAnC,CAAP;AACA","sourcesContent":["/**\n * External dependencies\n */\nimport { isEqual } from 'lodash';\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\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\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\tEmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,\n\t\tErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,\n\t\tLoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder,\n\t} = props;\n\n\tconst isMountedRef = useRef( true );\n\tconst [ showLoader, setShowLoader ] = useState( false );\n\tconst fetchRequestRef = useRef();\n\tconst [ response, setResponse ] = useState( null );\n\tconst prevResponse = usePrevious( response );\n\tconst prevProps = usePrevious( props );\n\n\tfunction fetchData() {\n\t\tif ( ! isMountedRef.current ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( null !== response ) {\n\t\t\tsetResponse( null );\n\t\t}\n\n\t\tconst sanitizedAttributes =\n\t\t\tattributes &&\n\t\t\t__experimentalSanitizeBlockAttributes( block, attributes );\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\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\t() => () => {\n\t\t\tisMountedRef.current = false;\n\t\t},\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 ( ! isEqual( prevProps, props ) ) {\n\t\t\tdebouncedFetchData();\n\t\t}\n\t} );\n\n\t/**\n\t * Effect to handle showing the loading placeholder.\n\t * Show it only if there is no previous response or\n\t * the request takes more than one second.\n\t */\n\tuseEffect( () => {\n\t\tif ( response !== null ) {\n\t\t\treturn;\n\t\t}\n\t\tconst timeout = setTimeout( () => {\n\t\t\tsetShowLoader( true );\n\t\t}, 1000 );\n\t\treturn () => clearTimeout( timeout );\n\t}, [ response ] );\n\n\tif ( response === '' ) {\n\t\treturn <EmptyResponsePlaceholder { ...props } />;\n\t} else if ( ! response ) {\n\t\treturn (\n\t\t\t<LoadingResponsePlaceholder\n\t\t\t\t{ ...props }\n\t\t\t\tshowLoader={ ! prevResponse || showLoader }\n\t\t\t>\n\t\t\t\t{ !! prevResponse && (\n\t\t\t\t\t<RawHTML className={ className }>{ prevResponse }</RawHTML>\n\t\t\t\t) }\n\t\t\t</LoadingResponsePlaceholder>\n\t\t);\n\t} else if ( response.error ) {\n\t\treturn <ErrorResponsePlaceholder response={ response } { ...props } />;\n\t}\n\n\treturn <RawHTML className={ className }>{ response }</RawHTML>;\n}\n"]}
|
|
@@ -46,11 +46,26 @@ function DefaultErrorResponsePlaceholder({
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
function DefaultLoadingResponsePlaceholder({
|
|
49
|
-
|
|
49
|
+
children,
|
|
50
|
+
showLoader
|
|
50
51
|
}) {
|
|
51
|
-
return createElement(
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
return createElement("div", {
|
|
53
|
+
style: {
|
|
54
|
+
position: 'relative'
|
|
55
|
+
}
|
|
56
|
+
}, showLoader && createElement("div", {
|
|
57
|
+
style: {
|
|
58
|
+
position: 'absolute',
|
|
59
|
+
top: '50%',
|
|
60
|
+
left: '50%',
|
|
61
|
+
marginTop: '-9px',
|
|
62
|
+
marginLeft: '-9px'
|
|
63
|
+
}
|
|
64
|
+
}, createElement(Spinner, null)), createElement("div", {
|
|
65
|
+
style: {
|
|
66
|
+
opacity: showLoader ? '0.3' : 1
|
|
67
|
+
}
|
|
68
|
+
}, children));
|
|
54
69
|
}
|
|
55
70
|
|
|
56
71
|
export default function ServerSideRender(props) {
|
|
@@ -65,8 +80,10 @@ export default function ServerSideRender(props) {
|
|
|
65
80
|
LoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder
|
|
66
81
|
} = props;
|
|
67
82
|
const isMountedRef = useRef(true);
|
|
83
|
+
const [showLoader, setShowLoader] = useState(false);
|
|
68
84
|
const fetchRequestRef = useRef();
|
|
69
85
|
const [response, setResponse] = useState(null);
|
|
86
|
+
const prevResponse = usePrevious(response);
|
|
70
87
|
const prevProps = usePrevious(props);
|
|
71
88
|
|
|
72
89
|
function fetchData() {
|
|
@@ -124,11 +141,31 @@ export default function ServerSideRender(props) {
|
|
|
124
141
|
debouncedFetchData();
|
|
125
142
|
}
|
|
126
143
|
});
|
|
144
|
+
/**
|
|
145
|
+
* Effect to handle showing the loading placeholder.
|
|
146
|
+
* Show it only if there is no previous response or
|
|
147
|
+
* the request takes more than one second.
|
|
148
|
+
*/
|
|
149
|
+
|
|
150
|
+
useEffect(() => {
|
|
151
|
+
if (response !== null) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const timeout = setTimeout(() => {
|
|
156
|
+
setShowLoader(true);
|
|
157
|
+
}, 1000);
|
|
158
|
+
return () => clearTimeout(timeout);
|
|
159
|
+
}, [response]);
|
|
127
160
|
|
|
128
161
|
if (response === '') {
|
|
129
162
|
return createElement(EmptyResponsePlaceholder, props);
|
|
130
163
|
} else if (!response) {
|
|
131
|
-
return createElement(LoadingResponsePlaceholder, props
|
|
164
|
+
return createElement(LoadingResponsePlaceholder, _extends({}, props, {
|
|
165
|
+
showLoader: !prevResponse || showLoader
|
|
166
|
+
}), !!prevResponse && createElement(RawHTML, {
|
|
167
|
+
className: className
|
|
168
|
+
}, prevResponse));
|
|
132
169
|
} else if (response.error) {
|
|
133
170
|
return createElement(ErrorResponsePlaceholder, _extends({
|
|
134
171
|
response: response
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["@wordpress/server-side-render/src/server-side-render.js"],"names":["isEqual","useDebounce","usePrevious","RawHTML","useEffect","useRef","useState","__","sprintf","apiFetch","addQueryArgs","Placeholder","Spinner","__experimentalSanitizeBlockAttributes","rendererPath","block","attributes","urlQueryArgs","context","DefaultEmptyResponsePlaceholder","className","DefaultErrorResponsePlaceholder","response","errorMessage","errorMsg","DefaultLoadingResponsePlaceholder","ServerSideRender","props","httpMethod","EmptyResponsePlaceholder","ErrorResponsePlaceholder","LoadingResponsePlaceholder","isMountedRef","fetchRequestRef","setResponse","prevProps","fetchData","current","sanitizedAttributes","isPostRequest","urlAttributes","path","data","fetchRequest","method","then","fetchResponse","rendered","catch","error","message","debouncedFetchData","undefined"],"mappings":"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","sourcesContent":["/**\n * External dependencies\n */\nimport { isEqual } from 'lodash';\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\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\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( { className } ) {\n\treturn (\n\t\t<Placeholder className={ className }>\n\t\t\t<Spinner />\n\t\t</Placeholder>\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\tEmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,\n\t\tErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,\n\t\tLoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder,\n\t} = props;\n\n\tconst isMountedRef = useRef( true );\n\tconst fetchRequestRef = useRef();\n\tconst [ response, setResponse ] = useState( null );\n\tconst prevProps = usePrevious( props );\n\n\tfunction fetchData() {\n\t\tif ( ! isMountedRef.current ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( null !== response ) {\n\t\t\tsetResponse( null );\n\t\t}\n\n\t\tconst sanitizedAttributes =\n\t\t\tattributes &&\n\t\t\t__experimentalSanitizeBlockAttributes( block, attributes );\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\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\t() => () => {\n\t\t\tisMountedRef.current = false;\n\t\t},\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 ( ! isEqual( prevProps, props ) ) {\n\t\t\tdebouncedFetchData();\n\t\t}\n\t} );\n\n\tif ( response === '' ) {\n\t\treturn <EmptyResponsePlaceholder { ...props } />;\n\t} else if ( ! response ) {\n\t\treturn <LoadingResponsePlaceholder { ...props } />;\n\t} else if ( response.error ) {\n\t\treturn <ErrorResponsePlaceholder response={ response } { ...props } />;\n\t}\n\n\treturn <RawHTML className={ className }>{ response }</RawHTML>;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["@wordpress/server-side-render/src/server-side-render.js"],"names":["isEqual","useDebounce","usePrevious","RawHTML","useEffect","useRef","useState","__","sprintf","apiFetch","addQueryArgs","Placeholder","Spinner","__experimentalSanitizeBlockAttributes","rendererPath","block","attributes","urlQueryArgs","context","DefaultEmptyResponsePlaceholder","className","DefaultErrorResponsePlaceholder","response","errorMessage","errorMsg","DefaultLoadingResponsePlaceholder","children","showLoader","position","top","left","marginTop","marginLeft","opacity","ServerSideRender","props","httpMethod","EmptyResponsePlaceholder","ErrorResponsePlaceholder","LoadingResponsePlaceholder","isMountedRef","setShowLoader","fetchRequestRef","setResponse","prevResponse","prevProps","fetchData","current","sanitizedAttributes","isPostRequest","urlAttributes","path","data","fetchRequest","method","then","fetchResponse","rendered","catch","error","message","debouncedFetchData","undefined","timeout","setTimeout","clearTimeout"],"mappings":"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","sourcesContent":["/**\n * External dependencies\n */\nimport { isEqual } from 'lodash';\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\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\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\tEmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,\n\t\tErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,\n\t\tLoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder,\n\t} = props;\n\n\tconst isMountedRef = useRef( true );\n\tconst [ showLoader, setShowLoader ] = useState( false );\n\tconst fetchRequestRef = useRef();\n\tconst [ response, setResponse ] = useState( null );\n\tconst prevResponse = usePrevious( response );\n\tconst prevProps = usePrevious( props );\n\n\tfunction fetchData() {\n\t\tif ( ! isMountedRef.current ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( null !== response ) {\n\t\t\tsetResponse( null );\n\t\t}\n\n\t\tconst sanitizedAttributes =\n\t\t\tattributes &&\n\t\t\t__experimentalSanitizeBlockAttributes( block, attributes );\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\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\t() => () => {\n\t\t\tisMountedRef.current = false;\n\t\t},\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 ( ! isEqual( prevProps, props ) ) {\n\t\t\tdebouncedFetchData();\n\t\t}\n\t} );\n\n\t/**\n\t * Effect to handle showing the loading placeholder.\n\t * Show it only if there is no previous response or\n\t * the request takes more than one second.\n\t */\n\tuseEffect( () => {\n\t\tif ( response !== null ) {\n\t\t\treturn;\n\t\t}\n\t\tconst timeout = setTimeout( () => {\n\t\t\tsetShowLoader( true );\n\t\t}, 1000 );\n\t\treturn () => clearTimeout( timeout );\n\t}, [ response ] );\n\n\tif ( response === '' ) {\n\t\treturn <EmptyResponsePlaceholder { ...props } />;\n\t} else if ( ! response ) {\n\t\treturn (\n\t\t\t<LoadingResponsePlaceholder\n\t\t\t\t{ ...props }\n\t\t\t\tshowLoader={ ! prevResponse || showLoader }\n\t\t\t>\n\t\t\t\t{ !! prevResponse && (\n\t\t\t\t\t<RawHTML className={ className }>{ prevResponse }</RawHTML>\n\t\t\t\t) }\n\t\t\t</LoadingResponsePlaceholder>\n\t\t);\n\t} else if ( response.error ) {\n\t\treturn <ErrorResponsePlaceholder response={ response } { ...props } />;\n\t}\n\n\treturn <RawHTML className={ className }>{ response }</RawHTML>;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/server-side-render",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.3",
|
|
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",
|
|
@@ -27,19 +27,19 @@
|
|
|
27
27
|
"react-native": "src/index",
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@babel/runtime": "^7.13.10",
|
|
30
|
-
"@wordpress/api-fetch": "^5.2.
|
|
31
|
-
"@wordpress/blocks": "^11.1.
|
|
32
|
-
"@wordpress/components": "^
|
|
33
|
-
"@wordpress/compose": "^5.0.
|
|
34
|
-
"@wordpress/data": "^6.1.
|
|
35
|
-
"@wordpress/deprecated": "^3.2.
|
|
36
|
-
"@wordpress/element": "^4.0.
|
|
37
|
-
"@wordpress/i18n": "^4.2.
|
|
38
|
-
"@wordpress/url": "^3.2.
|
|
30
|
+
"@wordpress/api-fetch": "^5.2.3",
|
|
31
|
+
"@wordpress/blocks": "^11.1.1",
|
|
32
|
+
"@wordpress/components": "^18.0.0",
|
|
33
|
+
"@wordpress/compose": "^5.0.3",
|
|
34
|
+
"@wordpress/data": "^6.1.1",
|
|
35
|
+
"@wordpress/deprecated": "^3.2.2",
|
|
36
|
+
"@wordpress/element": "^4.0.2",
|
|
37
|
+
"@wordpress/i18n": "^4.2.3",
|
|
38
|
+
"@wordpress/url": "^3.2.3",
|
|
39
39
|
"lodash": "^4.17.21"
|
|
40
40
|
},
|
|
41
41
|
"publishConfig": {
|
|
42
42
|
"access": "public"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "8f7f052bc04e3f4eb50f479ced14be1489b9fa79"
|
|
45
45
|
}
|
|
@@ -39,11 +39,26 @@ function DefaultErrorResponsePlaceholder( { response, className } ) {
|
|
|
39
39
|
return <Placeholder className={ className }>{ errorMessage }</Placeholder>;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
function DefaultLoadingResponsePlaceholder( {
|
|
42
|
+
function DefaultLoadingResponsePlaceholder( { children, showLoader } ) {
|
|
43
43
|
return (
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
<div style={ { position: 'relative' } }>
|
|
45
|
+
{ showLoader && (
|
|
46
|
+
<div
|
|
47
|
+
style={ {
|
|
48
|
+
position: 'absolute',
|
|
49
|
+
top: '50%',
|
|
50
|
+
left: '50%',
|
|
51
|
+
marginTop: '-9px',
|
|
52
|
+
marginLeft: '-9px',
|
|
53
|
+
} }
|
|
54
|
+
>
|
|
55
|
+
<Spinner />
|
|
56
|
+
</div>
|
|
57
|
+
) }
|
|
58
|
+
<div style={ { opacity: showLoader ? '0.3' : 1 } }>
|
|
59
|
+
{ children }
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
47
62
|
);
|
|
48
63
|
}
|
|
49
64
|
|
|
@@ -60,8 +75,10 @@ export default function ServerSideRender( props ) {
|
|
|
60
75
|
} = props;
|
|
61
76
|
|
|
62
77
|
const isMountedRef = useRef( true );
|
|
78
|
+
const [ showLoader, setShowLoader ] = useState( false );
|
|
63
79
|
const fetchRequestRef = useRef();
|
|
64
80
|
const [ response, setResponse ] = useState( null );
|
|
81
|
+
const prevResponse = usePrevious( response );
|
|
65
82
|
const prevProps = usePrevious( props );
|
|
66
83
|
|
|
67
84
|
function fetchData() {
|
|
@@ -139,10 +156,34 @@ export default function ServerSideRender( props ) {
|
|
|
139
156
|
}
|
|
140
157
|
} );
|
|
141
158
|
|
|
159
|
+
/**
|
|
160
|
+
* Effect to handle showing the loading placeholder.
|
|
161
|
+
* Show it only if there is no previous response or
|
|
162
|
+
* the request takes more than one second.
|
|
163
|
+
*/
|
|
164
|
+
useEffect( () => {
|
|
165
|
+
if ( response !== null ) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const timeout = setTimeout( () => {
|
|
169
|
+
setShowLoader( true );
|
|
170
|
+
}, 1000 );
|
|
171
|
+
return () => clearTimeout( timeout );
|
|
172
|
+
}, [ response ] );
|
|
173
|
+
|
|
142
174
|
if ( response === '' ) {
|
|
143
175
|
return <EmptyResponsePlaceholder { ...props } />;
|
|
144
176
|
} else if ( ! response ) {
|
|
145
|
-
return
|
|
177
|
+
return (
|
|
178
|
+
<LoadingResponsePlaceholder
|
|
179
|
+
{ ...props }
|
|
180
|
+
showLoader={ ! prevResponse || showLoader }
|
|
181
|
+
>
|
|
182
|
+
{ !! prevResponse && (
|
|
183
|
+
<RawHTML className={ className }>{ prevResponse }</RawHTML>
|
|
184
|
+
) }
|
|
185
|
+
</LoadingResponsePlaceholder>
|
|
186
|
+
);
|
|
146
187
|
} else if ( response.error ) {
|
|
147
188
|
return <ErrorResponsePlaceholder response={ response } { ...props } />;
|
|
148
189
|
}
|