Fix false "unsaved changes" warning from Query Loop queryId churn on load#23
Conversation
Playwright test resultsDetails
|
withUniqueQueryId forced every core/query block's queryId to a strictly index-based value (postId*1000 + index + 1) on load, rewriting it via setAttributes whenever it didn't match. For any page whose saved queryIds are not perfectly sequential — e.g. after a query block is deleted or reordered, leaving a gap or a duplicate — this rewrote the ids on every editor open, marking the post dirty before the user made any change. That surfaced a "Leave site?" warning on load and triggered continuous background autosaves. Only assign a new queryId when the current one is missing or already used by an earlier query block; leave already-unique ids untouched. This mirrors the server-side deduplicate_query_ids() behaviour, is idempotent, and still fixes genuinely duplicated ids (e.g. from copy-pasting a query block).
b81685f to
64d4c9f
Compare
|
Heads-up on a change of approach since the last review 👇 After testing the original fix (registering the I've rewritten the branch to a single focused commit with the real fix, and updated the title/description accordingly. The fix mirrors the existing server-side Re-review appreciated when you get a chance 🙏 |
|
Updated to add a test for this case |
mattheu
left a comment
There was a problem hiding this comment.
This change seems good to me. @roborourke Would love a second pair of eyes though if you have a chance.
roborourke
left a comment
There was a problem hiding this comment.
Great, we can perhaps lose the console statements in the test but it's not a blocker for me.
Removed console.log statements for query IDs and editor state checks.
Problem
Opening any page/post that contains Query Loop blocks in the editor immediately shows the "Leave site? Changes that you made may not be saved." warning — before the user makes any edit.
isEditedPostDirty()returnstrueon load, and WordPress fires continuous background autosaves as a side effect.Root cause
withUniqueQueryId(src/index.js) forced everycore/queryblock'squeryIdto a strictly index-based value (postId * 1000 + index + 1) on load, rewriting it viasetAttributeswhenever it didn't match:For any page whose saved
queryIds aren't perfectly sequential — e.g. after a query block was deleted or reordered, leaving a gap or a duplicate — this rewrites the ids on every editor open. Setting an attribute (even to a value that leaves the serialized markup unchanged) records a block edit → the post is marked dirty on load → the "Leave site?" warning and endless autosaves. It never converges, because the recomputed ids keep disagreeing with what's stored.Fix
Only assign a new
queryIdwhen the current one is missing or already used by an earlier query block; leave already-unique ids untouched. This:deduplicate_query_ids(), which already only overrides aqueryIdwhen it's a duplicate ("preserves the original value when possible… improving interoperability"). The editor was the inconsistent side.The change is editor-only — front-end rendering continues to use the untouched server-side dedup, so published sites are unaffected.
Testing
queryId):isEditedPostDirty()goestrue→falseon load; no warning; no autosave churn; queryIds stay stable across reloads.unique-query-idand all other relevant tests pass. The 2exclude-with-post-infailures are pre-existing onmain(the test env auto-pulls Advanced Query Loop's latest zip, whose post-selection UI changed and no longer matches the test selector) — unrelated to this change.Note
This supersedes the earlier approach in this PR (registering the
hmQueryLoopattribute server-side). That was based on an incorrect diagnosis and did not fix the issue; the real cause is the queryId churn above. The branch history was rewritten to a single focused commit. (Branch name is now a cosmetic mismatch.)