@@ -255,6 +255,21 @@ export function diff(
255255 ? cloneNode ( tmp . props . children )
256256 : tmp ;
257257
258+ // Teardown old html fragment markers if content changed or transitioning away
259+ if ( newType === Fragment && oldVNode . _dom && oldVNode . _dom . _endHtml ) {
260+ const endMarker = oldVNode . _dom . _endHtml ;
261+ oldDom = endMarker . nextSibling ;
262+ const newDSIH = newVNode . props . dangerouslySetInnerHTML ;
263+ if (
264+ ! newDSIH ||
265+ newDSIH . __html !== oldVNode . props . dangerouslySetInnerHTML . __html
266+ ) {
267+ removeRange ( oldVNode . _dom , endMarker ) ;
268+ } else {
269+ newVNode . _dom = oldVNode . _dom ;
270+ }
271+ }
272+
258273 if ( newType === Fragment && newVNode . props . dangerouslySetInnerHTML ) {
259274 const html = newVNode . props . dangerouslySetInnerHTML . __html ;
260275 newVNode . _children = [ ] ;
@@ -294,43 +309,25 @@ export function diff(
294309 startMarker . _endHtml = endMarker ;
295310 }
296311 oldDom = endMarker ? endMarker . nextSibling : NULL ;
297- } else if ( oldVNode . _dom && oldVNode . _dom . _endHtml ) {
298- // Update: old Fragment also had dangerouslySetInnerHTML
299- const startMarker = oldVNode . _dom ;
300- const endMarker = startMarker . _endHtml ;
301- newVNode . _dom = startMarker ;
312+ }
302313
303- if ( html !== oldVNode . props . dangerouslySetInnerHTML . __html ) {
304- // Clear content between markers
305- let node = startMarker . nextSibling ;
306- while ( node && node !== endMarker ) {
307- let next = node . nextSibling ;
308- removeNode ( node ) ;
309- node = next ;
310- }
311- setHtmlContent ( html , parentDom , endMarker ) ;
312- }
313- oldDom = endMarker . nextSibling ;
314- } else {
315- // First client-side mount
314+ // Mount: first render or update that cleared old markers
315+ if ( ! newVNode . _dom ) {
316316 const startMarker = document . createComment ( '$h' ) ;
317317 const endMarker = document . createComment ( '/$h' ) ;
318318 startMarker . _endHtml = endMarker ;
319319
320320 parentDom . insertBefore ( startMarker , oldDom ) ;
321- setHtmlContent ( html , parentDom , oldDom ) ;
321+ if ( html ) {
322+ const tpl = document . createElement ( 'template' ) ;
323+ tpl . innerHTML = html ;
324+ parentDom . insertBefore ( tpl . content , oldDom ) ;
325+ }
322326 parentDom . insertBefore ( endMarker , oldDom ) ;
323327
324328 newVNode . _dom = startMarker ;
325329 }
326330 } else {
327- // Reverse transition: old had dangerouslySetInnerHTML, new has normal children
328- if ( newType === Fragment && oldVNode . _dom && oldVNode . _dom . _endHtml ) {
329- const endMarker = oldVNode . _dom . _endHtml ;
330- oldDom = endMarker . nextSibling ;
331- removeRange ( oldVNode . _dom , endMarker ) ;
332- }
333-
334331 oldDom = diffChildren (
335332 parentDom ,
336333 isArray ( renderResult ) ? renderResult : [ renderResult ] ,
@@ -434,15 +431,6 @@ function removeRange(start, end) {
434431 }
435432}
436433
437- /** Parse `html` and insert the resulting nodes before `ref` in `parent`. */
438- function setHtmlContent ( html , parent , ref ) {
439- if ( html ) {
440- const tpl = document . createElement ( 'template' ) ;
441- tpl . innerHTML = html ;
442- parent . insertBefore ( tpl . content , ref ) ;
443- }
444- }
445-
446434/**
447435 * @param {Array<Component> } commitQueue List of components
448436 * which have callbacks to invoke in commitRoot
0 commit comments