@@ -1243,8 +1243,14 @@ export function getWatchedKeys(id, newProps, graphs) {
12431243 * See getCallbackByOutput for details.
12441244 */
12451245export function getUnfilteredLayoutCallbacks ( graphs , paths , layoutChunk , opts ) {
1246- const { outputsOnly, removedArrayInputsOnly, newPaths, chunkPath, oldPaths} =
1247- opts ;
1246+ const {
1247+ outputsOnly,
1248+ removedArrayInputsOnly,
1249+ newPaths,
1250+ chunkPath,
1251+ oldPaths,
1252+ oldLayout
1253+ } = opts ;
12481254 const foundCbIds = { } ;
12491255 const callbacks = [ ] ;
12501256
@@ -1290,7 +1296,25 @@ export function getUnfilteredLayoutCallbacks(graphs, paths, layoutChunk, opts) {
12901296 } ) ;
12911297 }
12921298
1293- function handleOneId ( id , outIdCallbacks , inIdCallbacks ) {
1299+ // Suppress initial call only when the component's output prop is unchanged
1300+ // (the component was preserved by a Patch operation). Full-replace
1301+ // returns new component instances whose props are reset to defaults, so their
1302+ // output props will differ from the old layout and the callback must still fire.
1303+ function isUnchangedOutputProp ( id , property , child ) {
1304+ if ( ! chunkPath || ! oldPaths || ! oldLayout ) return false ;
1305+ const oldPath = getPath ( oldPaths , id ) ;
1306+ if ( ! oldPath ) return false ;
1307+ const oldPropValue = path ( [ ...oldPath , 'props' , property ] , oldLayout ) ;
1308+ // If the prop was never set in the old layout (undefined), we cannot
1309+ // treat it as "unchanged" and the callback must still fire to populate it.
1310+ // This prevents incorrectly suppressing title callbacks and other output
1311+ // props that were undefined in both old and new layouts (undefined === undefined).
1312+ if ( oldPropValue === undefined ) return false ;
1313+ const newPropValue = child ? path ( [ 'props' , property ] , child ) : undefined ;
1314+ return oldPropValue === newPropValue ;
1315+ }
1316+
1317+ function handleOneId ( id , outIdCallbacks , inIdCallbacks , child ) {
12941318 if ( outIdCallbacks ) {
12951319 for ( const property in outIdCallbacks ) {
12961320 const cb = getCallbackByOutput ( graphs , paths , id , property ) ;
@@ -1299,11 +1323,9 @@ export function getUnfilteredLayoutCallbacks(graphs, paths, layoutChunk, opts) {
12991323 // unless specifically requested not to.
13001324 // ie this is the initial call of this callback even if it's
13011325 // not the page initialization but just a new layout chunk
1302- // Don't fire initial call for components that already existed before
1303- // this chunk update (e.g. existing MATCH items when Patch adds a new one).
13041326 if (
13051327 ! cb . callback . prevent_initial_call &&
1306- ! ( chunkPath && oldPaths && getPath ( oldPaths , id ) )
1328+ ! isUnchangedOutputProp ( id , property , child )
13071329 ) {
13081330 cb . initialCall = true ;
13091331 addCallback ( cb ) ;
@@ -1344,13 +1366,14 @@ export function getUnfilteredLayoutCallbacks(graphs, paths, layoutChunk, opts) {
13441366 const id = path ( [ 'props' , 'id' ] , child ) ;
13451367 if ( id ) {
13461368 if ( typeof id === 'string' && ! removedArrayInputsOnly ) {
1347- handleOneId ( id , graphs . outputMap [ id ] , graphs . inputMap [ id ] ) ;
1369+ handleOneId ( id , graphs . outputMap [ id ] , graphs . inputMap [ id ] , child ) ;
13481370 } else {
13491371 const keyStr = Object . keys ( id ) . sort ( ) . join ( ',' ) ;
13501372 handleOneId (
13511373 id ,
13521374 ! removedArrayInputsOnly && graphs . outputPatterns [ keyStr ] ,
1353- graphs . inputPatterns [ keyStr ]
1375+ graphs . inputPatterns [ keyStr ] ,
1376+ child
13541377 ) ;
13551378 }
13561379 }
0 commit comments