@@ -15,17 +15,19 @@ import {
15
15
} from '../constants' ;
16
16
import { normalizeToVNode , Fragment } from '../create-element' ;
17
17
import { setProperty } from './props' ;
18
- import { createInternal } from '../tree' ;
18
+ import { createInternal , getParentContext } from '../tree' ;
19
19
import options from '../options' ;
20
- import { ENABLE_CLASSES , rendererState } from '../component' ;
20
+ import { ENABLE_CLASSES } from '../component' ;
21
+ import { commitQueue } from './commit' ;
21
22
/**
22
23
* Diff two virtual nodes and apply proper changes to the DOM
23
24
* @param {import('../internal').Internal } internal The Internal node to mount
24
25
* @param {import('../internal').VNode | string } newVNode The new virtual node
26
+ * @param {import('../internal').PreactElement } parentDom The element into which this subtree is rendered
25
27
* @param {import('../internal').PreactNode } startDom
26
28
* @returns {import('../internal').PreactNode | null } pointer to the next DOM node to be hydrated (or null)
27
29
*/
28
- export function mount ( internal , newVNode , startDom ) {
30
+ export function mount ( internal , newVNode , parentDom , startDom ) {
29
31
if ( options . _diff ) options . _diff ( internal , newVNode ) ;
30
32
31
33
/** @type {import('../internal').PreactNode } */
@@ -36,29 +38,30 @@ export function mount(internal, newVNode, startDom) {
36
38
// Root nodes signal that an attempt to render into a specific DOM node on
37
39
// the page. Root nodes can occur anywhere in the tree and not just at the
38
40
// top.
39
- let prevParentDom = rendererState . _parentDom ;
40
- if ( internal . flags & TYPE_ROOT ) {
41
- rendererState . _parentDom = newVNode . props . _parentDom ;
42
-
43
- // Note: this is likely always true because we are inside mount()
44
- if ( rendererState . _parentDom !== prevParentDom ) {
45
- prevStartDom = startDom ;
46
- startDom = null ;
47
- }
41
+ if (
42
+ internal . flags & TYPE_ROOT &&
43
+ newVNode . props . _parentDom !== parentDom
44
+ ) {
45
+ parentDom = newVNode . props . _parentDom ;
46
+ prevStartDom = startDom ;
47
+ startDom = null ;
48
48
}
49
49
50
- let prevContext = rendererState . _context ;
51
-
52
- nextDomSibling = mountComponent ( internal , startDom ) ;
50
+ const renderResult = mountComponent ( internal , startDom ) ;
51
+ if ( renderResult === startDom ) {
52
+ nextDomSibling = startDom ;
53
+ } else {
54
+ nextDomSibling = mountChildren (
55
+ internal ,
56
+ renderResult ,
57
+ parentDom ,
58
+ startDom
59
+ ) ;
60
+ }
53
61
54
62
if ( internal . _commitCallbacks . length ) {
55
- rendererState . _commitQueue . push ( internal ) ;
63
+ commitQueue . push ( internal ) ;
56
64
}
57
-
58
- rendererState . _parentDom = prevParentDom ;
59
- // In the event this subtree creates a new context for its children, restore
60
- // the previous context for its siblings
61
- rendererState . _context = prevContext ;
62
65
} else {
63
66
// @TODO : we could just assign this as internal.dom here
64
67
let hydrateDom =
@@ -192,14 +195,12 @@ function mountElement(internal, dom) {
192
195
dom . innerHTML = newHtml . __html ;
193
196
}
194
197
} else if ( newChildren != null ) {
195
- const prevParentDom = rendererState . _parentDom ;
196
- rendererState . _parentDom = dom ;
197
198
mountChildren (
198
199
internal ,
199
200
Array . isArray ( newChildren ) ? newChildren : [ newChildren ] ,
201
+ dom ,
200
202
isNew ? null : dom . firstChild
201
203
) ;
202
- rendererState . _parentDom = prevParentDom ;
203
204
}
204
205
205
206
// (as above, don't diff props during hydration)
@@ -216,9 +217,10 @@ function mountElement(internal, dom) {
216
217
* Mount all children of an Internal
217
218
* @param {import('../internal').Internal } internal The parent Internal of the given children
218
219
* @param {import('../internal').ComponentChild[] } children
220
+ * @param {import('../internal').PreactElement } parentDom The element into which this subtree is rendered
219
221
* @param {import('../internal').PreactNode } startDom
220
222
*/
221
- export function mountChildren ( internal , children , startDom ) {
223
+ export function mountChildren ( internal , children , parentDom , startDom ) {
222
224
let internalChildren = ( internal . _children = [ ] ) ,
223
225
i ,
224
226
childVNode ,
@@ -240,7 +242,7 @@ export function mountChildren(internal, children, startDom) {
240
242
internalChildren [ i ] = childInternal ;
241
243
242
244
// Morph the old element into the new one, but don't append it to the dom yet
243
- mountedNextChild = mount ( childInternal , childVNode , startDom ) ;
245
+ mountedNextChild = mount ( childInternal , childVNode , parentDom , startDom ) ;
244
246
245
247
newDom = childInternal . _dom ;
246
248
@@ -253,7 +255,7 @@ export function mountChildren(internal, children, startDom) {
253
255
// The DOM the diff should begin with is now startDom (since we inserted
254
256
// newDom before startDom) so ignore mountedNextChild and continue with
255
257
// startDom
256
- rendererState . _parentDom . insertBefore ( newDom , startDom ) ;
258
+ parentDom . insertBefore ( newDom , startDom ) ;
257
259
}
258
260
259
261
if ( childInternal . ref ) {
@@ -297,13 +299,14 @@ function mountComponent(internal, startDom) {
297
299
298
300
// Necessary for createContext api. Setting this property will pass
299
301
// the context value as `this.context` just for this component.
302
+ let context = getParentContext ( internal ) ;
300
303
let tmp = type . contextType ;
301
- let provider = tmp && rendererState . _context [ tmp . _id ] ;
304
+ let provider = tmp && context [ tmp . _id ] ;
302
305
let componentContext = tmp
303
306
? provider
304
307
? provider . props . value
305
308
: tmp . _defaultValue
306
- : rendererState . _context ;
309
+ : context ;
307
310
308
311
if ( provider ) provider . _subs . add ( internal ) ;
309
312
@@ -379,11 +382,7 @@ function mountComponent(internal, startDom) {
379
382
c . state = c . _nextState ;
380
383
381
384
if ( c . getChildContext != null ) {
382
- rendererState . _context = internal . _context = Object . assign (
383
- { } ,
384
- rendererState . _context ,
385
- c . getChildContext ( )
386
- ) ;
385
+ internal . _context = Object . assign ( { } , context , c . getChildContext ( ) ) ;
387
386
}
388
387
389
388
if ( renderResult == null ) {
@@ -401,5 +400,5 @@ function mountComponent(internal, startDom) {
401
400
renderResult = [ renderResult ] ;
402
401
}
403
402
404
- return mountChildren ( internal , renderResult , startDom ) ;
403
+ return renderResult ;
405
404
}
0 commit comments