@@ -130,6 +130,7 @@ export class RegularLayout extends HTMLElement {
130130 private _presizeQueue : PresizeQueue ;
131131 private _overlayController : OverlayController ;
132132 private _maximized ?: string ;
133+ private _resize_observer ?: ResizeObserver ;
133134
134135 constructor ( ) {
135136 super ( ) ;
@@ -141,7 +142,13 @@ export class RegularLayout extends HTMLElement {
141142 this . _cursor_stylesheet = new CSSStyleSheet ( ) ;
142143 this . _cursor_override = false ;
143144 const event_name = `${ this . _physics . CUSTOM_EVENT_NAME_PREFIX } -before-resize` ;
144- this . _presizeQueue = new PresizeQueue ( this , event_name ) ;
145+ // Refresh the bounds cache once per layout transition, so consumers
146+ // reading coordinates from a `before-resize` handler always see the
147+ // element's current position - a `ResizeObserver` alone can't catch
148+ // position-only moves of the host.
149+ this . _presizeQueue = new PresizeQueue ( this , event_name , ( ) => {
150+ this . _dimensions = undefined ;
151+ } ) ;
145152 this . _overlayController = new OverlayController ( this . create_overlay_host ( ) ) ;
146153 this . _shadowRoot . adoptedStyleSheets = [
147154 this . _stylesheet ,
@@ -150,13 +157,19 @@ export class RegularLayout extends HTMLElement {
150157 }
151158
152159 connectedCallback ( ) {
160+ this . _resize_observer ??= new ResizeObserver ( ( ) => {
161+ this . _dimensions = undefined ;
162+ } ) ;
163+
164+ this . _resize_observer . observe ( this ) ;
153165 this . addEventListener ( "dblclick" , this . onDblClick ) ;
154166 this . addEventListener ( "pointerdown" , this . onPointerDown ) ;
155167 this . addEventListener ( "pointerup" , this . onPointerUp ) ;
156168 this . addEventListener ( "pointermove" , this . onPointerMove ) ;
157169 }
158170
159171 disconnectedCallback ( ) {
172+ this . _resize_observer ?. disconnect ( ) ;
160173 this . removeEventListener ( "dblclick" , this . onDblClick ) ;
161174 this . removeEventListener ( "pointerdown" , this . onPointerDown ) ;
162175 this . removeEventListener ( "pointerup" , this . onPointerUp ) ;
@@ -334,34 +347,54 @@ export class RegularLayout extends HTMLElement {
334347 * {@link save}, and any subsequent {@link restore} resets the layout to the
335348 * minimized (normal, multi-panel) view.
336349 *
350+ * Before applying, dispatches a cancelable `regular-layout-before-resize`
351+ * event (as {@link restore} does) whose paths describe the post-maximize
352+ * geometry - a single full-window entry for `name`. If the event is
353+ * cancelled via `preventDefault()`, the update is suspended until
354+ * {@link resumeResize} is called.
355+ *
337356 * Has no effect if `name` is not present in the current layout.
338357 *
339358 * @param name - The name of the panel to maximize.
340359 */
341- maximize = ( name : string ) => {
360+ maximize = async ( name : string ) => {
342361 if ( ! this . getPanel ( name ) ) {
343362 return ;
344363 }
345364
346- this . _maximized = name ;
347- this . _stylesheet . replaceSync (
348- create_css_maximize_layout ( name , this . _physics ) ,
349- ) ;
365+ // The post-maximize geometry as a `Layout`: `name` alone, full-window.
366+ // Panels hidden by the maximize are absent from the presize paths,
367+ // consistent with `calculate_presize_paths`' visible-panels-only
368+ // semantics.
369+ const layout : Layout = { type : "tab-layout" , tabs : [ name ] , selected : 0 } ;
370+ await this . _presizeQueue . run ( layout , ( ) => {
371+ this . _maximized = name ;
372+ this . _stylesheet . replaceSync (
373+ create_css_maximize_layout ( name , this . _physics ) ,
374+ ) ;
375+ } ) ;
350376 } ;
351377
352378 /**
353379 * Restores the normal multi-panel view after a {@link maximize}, without
354380 * altering the layout tree. No-op if no panel is currently maximized.
381+ *
382+ * Before applying, dispatches a cancelable `regular-layout-before-resize`
383+ * event (as {@link restore} does) with paths for the restored multi-panel
384+ * geometry. If the event is cancelled via `preventDefault()`, the update
385+ * is suspended until {@link resumeResize} is called.
355386 */
356- minimize = ( ) => {
387+ minimize = async ( ) => {
357388 if ( this . _maximized === undefined ) {
358389 return ;
359390 }
360391
361- this . _maximized = undefined ;
362- this . _stylesheet . replaceSync (
363- create_css_grid_layout ( this . _panel , undefined , this . _physics ) ,
364- ) ;
392+ await this . _presizeQueue . run ( this . _panel , ( ) => {
393+ this . _maximized = undefined ;
394+ this . _stylesheet . replaceSync (
395+ create_css_grid_layout ( this . _panel , undefined , this . _physics ) ,
396+ ) ;
397+ } ) ;
365398 } ;
366399
367400 /**
@@ -371,6 +404,7 @@ export class RegularLayout extends HTMLElement {
371404 * @param layout - The layout tree to restore
372405 */
373406 restoreSync = ( layout : Layout , _is_flattened : boolean = false ) => {
407+ this . _dimensions = undefined ;
374408 this . _maximized = undefined ;
375409 this . _panel = ! _is_flattened ? flatten ( layout ) : layout ;
376410 const css = create_css_grid_layout ( this . _panel , undefined , this . _physics ) ;
0 commit comments