From 88a1837c898ac4f73e0b223ddd1e97e62d9d7960 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Thu, 11 Jun 2026 18:47:34 +0200 Subject: [PATCH] Fix WP description edit scrolling to page bottom on activation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://community.openproject.org/wp/OP-19226 When clicking the description to enter inline edit mode, the display container (holding the read-only description text) is immediately hidden via [hidden]="active", removing its full height from the layout. At the same time, the edit container becomes visible but is initially empty — the Angular portal that renders CKEditor resolves asynchronously, after detectChanges() has already flushed. This causes a temporary collapse of the page height. If the current scroll position exceeds the new page maximum, the browser clamps window.scrollY to the new bottom. By the time CKEditor finishes rendering and the page height recovers, the scroll position is already stuck at the bottom. This behaviour was observed in Firefox only; Chrome does not clamp the scroll position in the same way when page height shrinks. Safari was not tested. Fix by capturing the display container's height before detectChanges() runs and setting it as min-height on the inner block wrapper div. This keeps the page height stable throughout the transition so the browser has no reason to clamp the scroll. The min-height is cleared when the field is deactivated. Note: min-height must be applied to the wrapper div (display:block), not to the host element op-editable-attribute-field, which is display:inline and ignores min-height. --- .../editable-attribute-field.component.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/shared/components/fields/edit/field/editable-attribute-field.component.ts b/frontend/src/app/shared/components/fields/edit/field/editable-attribute-field.component.ts index e1382bc5143..2f72c61ea8d 100644 --- a/frontend/src/app/shared/components/fields/edit/field/editable-attribute-field.component.ts +++ b/frontend/src/app/shared/components/fields/edit/field/editable-attribute-field.component.ts @@ -90,6 +90,24 @@ export class EditableAttributeFieldComponent extends UntilDestroyedMixin impleme public destroyed = false; public setActive(active = true):void { + if (active && !this.active) { + // When switching to edit mode, the display container collapses immediately + // (display:none) while the edit portal renders asynchronously. This shrinks + // the page height and the browser clamps scroll to the new maximum, causing + // the page to jump to the bottom. Preserve the wrapper height to prevent this. + // Note: min-height must be set on the block wrapper div, not the host element + // (op-editable-attribute-field is display:inline and ignores min-height). + const wrapperEl = this.displayContainer.nativeElement.parentElement; + const height = this.displayContainer.nativeElement.offsetHeight; + if (wrapperEl && height > 0) { + wrapperEl.style.minHeight = `${height}px`; + } + } else if (!active) { + const wrapperEl = this.displayContainer.nativeElement.parentElement; + if (wrapperEl) { + wrapperEl.style.minHeight = ''; + } + } this.active = active; if (!this.componentDestroyed) { this.cdRef.detectChanges(); @@ -226,4 +244,3 @@ export class EditableAttributeFieldComponent extends UntilDestroyedMixin impleme return this.schemaCache.of(this.resource); } } -