mirror of
https://github.com/opf/openproject.git
synced 2026-06-13 19:20:00 +00:00
Fix WP description edit scrolling to page bottom on activation
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.
This commit is contained in:
+18
-1
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user