@@ -1194,8 +1194,14 @@ export function getWatchedKeys(id, newProps, graphs) {
11941194 * See getCallbackByOutput for details.
11951195 */
11961196export function getUnfilteredLayoutCallbacks ( graphs , paths , layoutChunk , opts ) {
1197- const { outputsOnly, removedArrayInputsOnly, newPaths, chunkPath, oldPaths} =
1198- opts ;
1197+ const {
1198+ outputsOnly,
1199+ removedArrayInputsOnly,
1200+ newPaths,
1201+ chunkPath,
1202+ oldPaths,
1203+ oldLayout
1204+ } = opts ;
11991205 const foundCbIds = { } ;
12001206 const callbacks = [ ] ;
12011207
@@ -1241,7 +1247,25 @@ export function getUnfilteredLayoutCallbacks(graphs, paths, layoutChunk, opts) {
12411247 } ) ;
12421248 }
12431249
1244- function handleOneId ( id , outIdCallbacks , inIdCallbacks ) {
1250+ // Suppress initial call only when the component's output prop is unchanged
1251+ // (the component was preserved by a Patch operation). Full-replace
1252+ // returns new component instances whose props are reset to defaults, so their
1253+ // output props will differ from the old layout and the callback must still fire.
1254+ function isUnchangedOutputProp ( id , property , child ) {
1255+ if ( ! chunkPath || ! oldPaths || ! oldLayout ) return false ;
1256+ const oldPath = getPath ( oldPaths , id ) ;
1257+ if ( ! oldPath ) return false ;
1258+ const oldPropValue = path ( [ ...oldPath , 'props' , property ] , oldLayout ) ;
1259+ // If the prop was never set in the old layout (undefined), we cannot
1260+ // treat it as "unchanged" and the callback must still fire to populate it.
1261+ // This prevents incorrectly suppressing title callbacks and other output
1262+ // props that were undefined in both old and new layouts (undefined === undefined).
1263+ if ( oldPropValue === undefined ) return false ;
1264+ const newPropValue = child ? path ( [ 'props' , property ] , child ) : undefined ;
1265+ return oldPropValue === newPropValue ;
1266+ }
1267+
1268+ function handleOneId ( id , outIdCallbacks , inIdCallbacks , child ) {
12451269 if ( outIdCallbacks ) {
12461270 for ( const property in outIdCallbacks ) {
12471271 const cb = getCallbackByOutput ( graphs , paths , id , property ) ;
@@ -1250,11 +1274,9 @@ export function getUnfilteredLayoutCallbacks(graphs, paths, layoutChunk, opts) {
12501274 // unless specifically requested not to.
12511275 // ie this is the initial call of this callback even if it's
12521276 // not the page initialization but just a new layout chunk
1253- // Don't fire initial call for components that already existed before
1254- // this chunk update (e.g. existing MATCH items when Patch adds a new one).
12551277 if (
12561278 ! cb . callback . prevent_initial_call &&
1257- ! ( chunkPath && oldPaths && getPath ( oldPaths , id ) )
1279+ ! isUnchangedOutputProp ( id , property , child )
12581280 ) {
12591281 cb . initialCall = true ;
12601282 addCallback ( cb ) ;
@@ -1295,13 +1317,14 @@ export function getUnfilteredLayoutCallbacks(graphs, paths, layoutChunk, opts) {
12951317 const id = path ( [ 'props' , 'id' ] , child ) ;
12961318 if ( id ) {
12971319 if ( typeof id === 'string' && ! removedArrayInputsOnly ) {
1298- handleOneId ( id , graphs . outputMap [ id ] , graphs . inputMap [ id ] ) ;
1320+ handleOneId ( id , graphs . outputMap [ id ] , graphs . inputMap [ id ] , child ) ;
12991321 } else {
13001322 const keyStr = Object . keys ( id ) . sort ( ) . join ( ',' ) ;
13011323 handleOneId (
13021324 id ,
13031325 ! removedArrayInputsOnly && graphs . outputPatterns [ keyStr ] ,
1304- graphs . inputPatterns [ keyStr ]
1326+ graphs . inputPatterns [ keyStr ] ,
1327+ child
13051328 ) ;
13061329 }
13071330 }
0 commit comments