Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit81bc0a8

Browse files
WIP
1 parent11e8208 commit81bc0a8

File tree

3 files changed

+95
-61
lines changed

3 files changed

+95
-61
lines changed

‎src/constants.js‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,8 @@ export const PARENT = '__';
1414
exportconstVNODE='__v';
1515
exportconstDIRTY='__d';
1616
exportconstNEXT_STATE='__s';
17+
18+
// Rendering modes
19+
exportconstMODE_SYNC=0;
20+
exportconstMODE_ASYNC=1;
21+
exportconstMODE_STREAM=2;

‎src/index.js‎

Lines changed: 61 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import {
1414
DIFF,
1515
DIFFED,
1616
DIRTY,
17+
MODE_ASYNC,
18+
MODE_STREAM,
19+
MODE_SYNC,
1720
NEXT_STATE,
1821
PARENT,
1922
RENDER,
@@ -79,7 +82,7 @@ export function renderToString(vnode, context) {
7982
false,
8083
undefined,
8184
parent,
82-
false
85+
MODE_SYNC
8386
);
8487
}catch(e){
8588
if(e.then){
@@ -92,14 +95,57 @@ export function renderToString(vnode, context) {
9295
}
9396
}
9497

95-
constDEFAULT_RENDER_SLOT=(idx)=>
96-
`<!--preact-slot:${idx}--><!--/preact-slot:${idx}-->`;
98+
/**
99+
* Render Preact JSX + Components to an HTML string.
100+
*@param {VNode} vnodeJSX Element / VNode to render
101+
*@param {Object} [context={}] Initial root context object
102+
*@returns {Promise<string>} serialized HTML
103+
*/
104+
exportasyncfunctionrenderToStringAsync(vnode,context){
105+
constpreviousSkipEffects=prepare();
106+
107+
constparent=h(Fragment,null);
108+
parent[CHILDREN]=[vnode];
109+
110+
try{
111+
constrendered=_renderToString(
112+
vnode,
113+
context||EMPTY_OBJ,
114+
false,
115+
undefined,
116+
parent,
117+
MODE_ASYNC
118+
);
119+
120+
if(Array.isArray(rendered)){
121+
letcount=0;
122+
letresolved=rendered;
123+
124+
// Resolving nested Promises with a maximum depth of 25
125+
while(
126+
resolved.some((element)=>typeofelement.then==='function')&&
127+
count++<25
128+
){
129+
resolved=(awaitPromise.all(resolved)).flat();
130+
}
131+
132+
returnresolved.join('');
133+
}
134+
135+
returnrendered;
136+
}finally{
137+
finalize(vnode,previousSkipEffects);
138+
}
139+
}
140+
141+
constDEFAULT_RENDER_SLOT=(idx,content)=>
142+
`<!--p:slot:${idx}-->${content}<!--/p:slot:${idx}-->`;
97143

98144
/**
99145
* Render Preact JSX + Components to an HTML string.
100146
*@param {VNode} vnodeJSX Element / VNode to render
101147
*@param {Object} [context={}] Initial root context object
102-
*@param {(idx: number) => string} [renderSlot] Render slot marker
148+
*@param {(idx: number, content: string) => string} [renderSlot] Render slot marker
103149
*@returns {ReadableStream<string>|string} serialized HTML
104150
*/
105151
exportfunctionrenderToStream(
@@ -119,7 +165,7 @@ export function renderToStream(
119165
false,
120166
undefined,
121167
parent,
122-
true
168+
MODE_STREAM
123169
);
124170

125171
if(Array.isArray(rendered)){
@@ -180,49 +226,6 @@ export function renderToStream(
180226
}
181227
}
182228

183-
/**
184-
* Render Preact JSX + Components to an HTML string.
185-
*@param {VNode} vnodeJSX Element / VNode to render
186-
*@param {Object} [context={}] Initial root context object
187-
*@returns {Promise<string>} serialized HTML
188-
*/
189-
exportasyncfunctionrenderToStringAsync(vnode,context){
190-
constpreviousSkipEffects=prepare();
191-
192-
constparent=h(Fragment,null);
193-
parent[CHILDREN]=[vnode];
194-
195-
try{
196-
constrendered=_renderToString(
197-
vnode,
198-
context||EMPTY_OBJ,
199-
false,
200-
undefined,
201-
parent,
202-
true
203-
);
204-
205-
if(Array.isArray(rendered)){
206-
letcount=0;
207-
letresolved=rendered;
208-
209-
// Resolving nested Promises with a maximum depth of 25
210-
while(
211-
resolved.some((element)=>typeofelement.then==='function')&&
212-
count++<25
213-
){
214-
resolved=(awaitPromise.all(resolved)).flat();
215-
}
216-
217-
returnresolved.join('');
218-
}
219-
220-
returnrendered;
221-
}finally{
222-
finalize(vnode,previousSkipEffects);
223-
}
224-
}
225-
226229
// Installed as setState/forceUpdate for function components
227230
functionmarkAsDirty(){
228231
this.__d=true;
@@ -290,6 +293,7 @@ function renderClassComponent(vnode, context) {
290293
*@param {any} selectValue
291294
*@param {VNode} parent
292295
*@param {boolean} asyncMode
296+
*@param {number} renderMode
293297
*@returns {string | Promise<string> | (string | Promise<string>)[]}
294298
*/
295299
function_renderToString(
@@ -298,7 +302,7 @@ function _renderToString(
298302
isSvgMode,
299303
selectValue,
300304
parent,
301-
asyncMode
305+
renderMode
302306
){
303307
// Ignore non-rendered VNodes/values
304308
if(vnode==null||vnode===true||vnode===false||vnode===''){
@@ -326,7 +330,7 @@ function _renderToString(
326330
isSvgMode,
327331
selectValue,
328332
parent,
329-
asyncMode
333+
renderMode
330334
);
331335

332336
if(typeofchildRender==='string'){
@@ -391,7 +395,7 @@ function _renderToString(
391395
isSvgMode,
392396
selectValue,
393397
vnode,
394-
asyncMode
398+
renderMode
395399
);
396400
}else{
397401
// Values are pre-escaped by the JSX transform
@@ -472,7 +476,7 @@ function _renderToString(
472476
isSvgMode,
473477
selectValue,
474478
vnode,
475-
asyncMode
479+
renderMode
476480
);
477481
returnstr;
478482
}catch(err){
@@ -504,7 +508,7 @@ function _renderToString(
504508
isSvgMode,
505509
selectValue,
506510
vnode,
507-
asyncMode
511+
renderMode
508512
);
509513
}
510514

@@ -531,7 +535,7 @@ function _renderToString(
531535
isSvgMode,
532536
selectValue,
533537
vnode,
534-
asyncMode
538+
renderMode
535539
);
536540

537541
try{
@@ -545,10 +549,11 @@ function _renderToString(
545549

546550
returnstr;
547551
}catch(error){
548-
if(!asyncMode)throwerror;
552+
if(renderMode===MODE_SYNC)throwerror;
549553

550554
if(!error||typeoferror.then!=='function')throwerror;
551555

556+
console.log(renderMode,error);
552557
constrenderNestedChildren=()=>{
553558
try{
554559
returnrenderChildren();
@@ -699,7 +704,7 @@ function _renderToString(
699704
childSvgMode,
700705
selectValue,
701706
vnode,
702-
asyncMode
707+
renderMode
703708
);
704709
}
705710

‎test/compat/stream.test.js‎

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ async function drain(iter) {
1616
returnout;
1717
}
1818

19-
describe('streaming renderToString',()=>{
19+
describe('renderToStream',()=>{
2020
it('should render JSX after a suspense boundary',async()=>{
2121
const{ Suspender, suspended}=createSuspender();
2222

2323
constpromise=drain(
2424
renderToStream(
2525
<div>
2626
<h1>foo</h1>
27-
<Suspensefallback={<div>loading...</div>}>
27+
<Suspense>
2828
<Suspender>
2929
<divclass="foo">bar</div>
3030
</Suspender>
@@ -36,7 +36,7 @@ describe('streaming renderToString', () => {
3636
suspended.resolve();
3737
constrendered=awaitpromise;
3838
expect(rendered).to.deep.equal([
39-
'<div><h1>foo</h1><!--preact-slot:0--><!--/preact-slot:0--><p>baz</p></div>',
39+
'<div><h1>foo</h1><!--p:slot:0--><!--/p:slot:0--><p>baz</p></div>',
4040
'<div class="foo">bar</div>'
4141
]);
4242
});
@@ -50,7 +50,7 @@ describe('streaming renderToString', () => {
5050
<body>
5151
<div>
5252
<h1>foo</h1>
53-
<Suspensefallback={<div>loading...</div>}>
53+
<Suspense>
5454
<Suspender>
5555
<divclass="foo">bar</div>
5656
</Suspender>
@@ -64,9 +64,33 @@ describe('streaming renderToString', () => {
6464
suspended.resolve();
6565
constrendered=awaitpromise;
6666
expect(rendered).to.deep.equal([
67-
'<html><body><div><h1>foo</h1><!--preact-slot:0--><!--/preact-slot:0--><p>baz</p></div>',
67+
'<html><body><div><h1>foo</h1><!--p:slot:0--><!--/p:slot:0--><p>baz</p></div>',
6868
'<div class="foo">bar</div>',
6969
'</body></html>'
7070
]);
7171
});
72+
73+
it.only('should render suspense fallback in placeholder',async()=>{
74+
const{ Suspender, suspended}=createSuspender();
75+
76+
constpromise=drain(
77+
renderToStream(
78+
<div>
79+
<h1>foo</h1>
80+
<Suspensefallback={<p>loading...</p>}>
81+
<Suspender>
82+
<divclass="foo">bar</div>
83+
</Suspender>
84+
</Suspense>
85+
<p>baz</p>
86+
</div>
87+
)
88+
);
89+
suspended.resolve();
90+
constrendered=awaitpromise;
91+
expect(rendered).to.deep.equal([
92+
'<div><h1>foo</h1><!--p:slot:0--><!--/p:slot:0--><p>baz</p></div>',
93+
'<div class="foo">bar</div>'
94+
]);
95+
});
7296
});

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp