Skip to content

Commit da53800

Browse files
committed
Reverted changes to position discovery
1 parent 5d0b8e2 commit da53800

10 files changed

Lines changed: 48 additions & 78 deletions

File tree

packages/ng-diagram/projects/ng-diagram/src/lib/components/edge-label/base-edge-label/base-edge-label.component.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
untracked,
1313
} from '@angular/core';
1414
import { EdgeLabel } from '../../../../core/src';
15-
import { BatchDomObserverService, FlowCoreProviderService } from '../../../services';
15+
import { BatchResizeObserverService, FlowCoreProviderService } from '../../../services';
1616
import { NgDiagramBaseEdgeComponent } from '../../edge/base-edge/base-edge.component';
1717

1818
/**
@@ -47,7 +47,7 @@ export class NgDiagramBaseEdgeLabelComponent implements OnInit, OnDestroy {
4747
private readonly flowCoreProvider = inject(FlowCoreProviderService);
4848
private readonly hostElement = inject(ElementRef<HTMLElement>);
4949
private readonly edgeComponent = inject(NgDiagramBaseEdgeComponent);
50-
private readonly batchDomObserver = inject(BatchDomObserverService);
50+
private readonly batchResizeObserver = inject(BatchResizeObserverService);
5151

5252
/**
5353
* The unique identifier for the edge label.
@@ -120,12 +120,11 @@ export class NgDiagramBaseEdgeLabelComponent implements OnInit, OnDestroy {
120120
positionOnEdge: this.positionOnEdge(),
121121
});
122122

123-
this.batchDomObserver.observeResize(this.hostElement.nativeElement, {
123+
this.batchResizeObserver.observeResize(this.hostElement.nativeElement, {
124124
type: 'edge-label',
125125
edgeId: this.edgeId(),
126126
labelId: this.id(),
127127
});
128-
this.batchDomObserver.observeStyle(this.hostElement.nativeElement);
129128
}
130129

131130
/** @internal */
@@ -140,8 +139,7 @@ export class NgDiagramBaseEdgeLabelComponent implements OnInit, OnDestroy {
140139
}
141140

142141
flowCore.updater.deleteEdgeLabel(this.edgeId(), this.id());
143-
this.batchDomObserver.unobserveResize(this.hostElement.nativeElement);
144-
this.batchDomObserver.unobserveStyle(this.hostElement.nativeElement);
142+
this.batchResizeObserver.unobserveResize(this.hostElement.nativeElement);
145143
}
146144
}
147145

packages/ng-diagram/projects/ng-diagram/src/lib/components/port/ng-diagram-port.component.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
import { OriginPoint, Port } from '../../../core/src';
1717
import { LinkingInputDirective } from '../../directives/input-events/linking/linking.directive';
1818
import { FlowCoreProviderService } from '../../services';
19-
import { BatchDomObserverService } from '../../services/flow-resize-observer/batch-dom-observer.service';
19+
import { BatchResizeObserverService } from '../../services/flow-resize-observer/batched-resize-observer.service';
2020
import { NodeContextGuardBase } from '../../utils/node-context-guard.base';
2121

2222
/**
@@ -67,7 +67,7 @@ const originPointClassMap: Record<OriginPoint, string> = {
6767
export class NgDiagramPortComponent extends NodeContextGuardBase implements OnInit, OnDestroy, AfterContentInit {
6868
private readonly hostElement = inject(ElementRef<HTMLElement>);
6969
private readonly flowCoreProvider = inject(FlowCoreProviderService);
70-
private readonly batchDomObserver = inject(BatchDomObserverService);
70+
private readonly batchResizeObserver = inject(BatchResizeObserverService);
7171
private readonly linkingInputDirective = inject(LinkingInputDirective);
7272
protected readonly isInitialized = signal(false);
7373
protected readonly lastSide = signal<Port['side'] | undefined>(undefined);
@@ -76,7 +76,7 @@ export class NgDiagramPortComponent extends NodeContextGuardBase implements OnIn
7676
protected readonly nodeData = computed(() => this.nodeComponent?.node());
7777

7878
/**
79-
* The unique identifier for the port. test
79+
* The unique identifier for the port.
8080
*/
8181
id = input.required<Port['id']>();
8282

@@ -138,7 +138,7 @@ export class NgDiagramPortComponent extends NodeContextGuardBase implements OnIn
138138
// When side or originPoint changes, CSS moves the port but doesn't resize it.
139139
// Force re-observation after DOM updates to pick up the new position.
140140
if (portChanges.side || originPointChanged) {
141-
this.batchDomObserver.invalidate(this.hostElement.nativeElement);
141+
this.batchResizeObserver.invalidate(this.hostElement.nativeElement);
142142
}
143143
});
144144

@@ -171,12 +171,11 @@ export class NgDiagramPortComponent extends NodeContextGuardBase implements OnIn
171171
side: this.side(),
172172
});
173173

174-
this.batchDomObserver.observeResize(this.hostElement.nativeElement, {
174+
this.batchResizeObserver.observeResize(this.hostElement.nativeElement, {
175175
type: 'port',
176176
nodeId: nodeData.id,
177177
portId: this.id(),
178178
});
179-
this.batchDomObserver.observeStyle(this.hostElement.nativeElement);
180179

181180
this.isInitialized.set(true);
182181
}
@@ -198,8 +197,7 @@ export class NgDiagramPortComponent extends NodeContextGuardBase implements OnIn
198197
return;
199198
}
200199

201-
this.batchDomObserver.unobserveResize(this.hostElement.nativeElement);
202-
this.batchDomObserver.unobserveStyle(this.hostElement.nativeElement);
200+
this.batchResizeObserver.unobserveResize(this.hostElement.nativeElement);
203201

204202
// Skip if node was deleted - ports are removed with the node
205203
const nodeStillExists = flowCore.getNodeById(nodeData.id);

packages/ng-diagram/projects/ng-diagram/src/lib/directives/node-size/node-size.directive.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { By } from '@angular/platform-browser';
44
import { type Node } from '../../../core/src';
55
import { beforeEach, describe, expect, it, vi } from 'vitest';
66
import { FlowCoreProviderService } from '../../services/flow-core-provider/flow-core-provider.service';
7-
import { BatchDomObserverService } from '../../services/flow-resize-observer/batch-dom-observer.service';
7+
import { BatchResizeObserverService } from '../../services/flow-resize-observer/batched-resize-observer.service';
88
import { DEFAULT_GROUP_SIZE, DEFAULT_NODE_SIZE, NodeSizeDirective } from './node-size.directive';
99

1010
@Component({
@@ -21,7 +21,7 @@ describe('NodeSizeDirective', () => {
2121
let component: TestComponent;
2222
let element: HTMLElement;
2323

24-
let mockBatchDomObserver: {
24+
let mockBatchResizeObserver: {
2525
observeResize: ReturnType<typeof vi.fn>;
2626
unobserveResize: ReturnType<typeof vi.fn>;
2727
};
@@ -32,7 +32,7 @@ describe('NodeSizeDirective', () => {
3232
};
3333

3434
beforeEach(async () => {
35-
mockBatchDomObserver = {
35+
mockBatchResizeObserver = {
3636
observeResize: vi.fn(),
3737
unobserveResize: vi.fn(),
3838
};
@@ -52,7 +52,7 @@ describe('NodeSizeDirective', () => {
5252
await TestBed.configureTestingModule({
5353
imports: [TestComponent],
5454
providers: [
55-
{ provide: BatchDomObserverService, useValue: mockBatchDomObserver },
55+
{ provide: BatchResizeObserverService, useValue: mockBatchResizeObserver },
5656
{ provide: FlowCoreProviderService, useValue: mockFlowCoreProvider },
5757
],
5858
}).compileComponents();
@@ -177,15 +177,15 @@ describe('NodeSizeDirective', () => {
177177

178178
describe('Lifecycle', () => {
179179
it('should connect resize observer on init', () => {
180-
expect(mockBatchDomObserver.observeResize).toHaveBeenCalledWith(element, {
180+
expect(mockBatchResizeObserver.observeResize).toHaveBeenCalledWith(element, {
181181
type: 'node',
182182
nodeId: 'test-node',
183183
});
184184
});
185185

186186
it('should disconnect resize observer on destroy', () => {
187187
fixture.destroy();
188-
expect(mockBatchDomObserver.unobserveResize).toHaveBeenCalledWith(element);
188+
expect(mockBatchResizeObserver.unobserveResize).toHaveBeenCalledWith(element);
189189
});
190190
});
191191

packages/ng-diagram/projects/ng-diagram/src/lib/directives/node-size/node-size.directive.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { computed, Directive, effect, ElementRef, inject, input, OnDestroy, OnInit, Renderer2 } from '@angular/core';
22
import { DEFAULT_NODE_MIN_SIZE, isGroup, type Node } from '../../../core/src';
33
import { FlowCoreProviderService } from '../../services/flow-core-provider/flow-core-provider.service';
4-
import { BatchDomObserverService } from '../../services/flow-resize-observer/batch-dom-observer.service';
4+
import { BatchResizeObserverService } from '../../services/flow-resize-observer/batched-resize-observer.service';
55

66
export const DEFAULT_NODE_SIZE = { width: '11.25rem', height: '2rem' };
77
export const DEFAULT_GROUP_SIZE = { width: '9.0625rem', height: '9.0625rem' };
@@ -26,7 +26,7 @@ export const DEFAULT_GROUP_SIZE = { width: '9.0625rem', height: '9.0625rem' };
2626
export class NodeSizeDirective implements OnDestroy, OnInit {
2727
private readonly hostElement = inject(ElementRef<HTMLElement>);
2828
private readonly renderer = inject(Renderer2);
29-
private readonly batchDomObserver = inject(BatchDomObserverService);
29+
private readonly batchResizeObserver = inject(BatchResizeObserverService);
3030
private readonly flowCoreProvider = inject(FlowCoreProviderService);
3131

3232
node = input.required<Node>();
@@ -170,13 +170,13 @@ export class NodeSizeDirective implements OnDestroy, OnInit {
170170
* size-dependent features when nodes resize.
171171
*/
172172
private connectResizeObserver() {
173-
this.batchDomObserver.observeResize(this.hostElement.nativeElement, {
173+
this.batchResizeObserver.observeResize(this.hostElement.nativeElement, {
174174
type: 'node',
175175
nodeId: this.id(),
176176
});
177177
}
178178

179179
private disconnectResizeObserver() {
180-
this.batchDomObserver.unobserveResize(this.hostElement.nativeElement);
180+
this.batchResizeObserver.unobserveResize(this.hostElement.nativeElement);
181181
}
182182
}

packages/ng-diagram/projects/ng-diagram/src/lib/providers/ng-diagram.providers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { NgDiagramNodeService } from '../public-services/ng-diagram-node.service
66
import { NgDiagramSelectionService } from '../public-services/ng-diagram-selection.service';
77
import { NgDiagramViewportService } from '../public-services/ng-diagram-viewport.service';
88
import { NgDiagramService } from '../public-services/ng-diagram.service';
9-
import { BatchDomObserverService } from '../services';
9+
import { BatchResizeObserverService } from '../services';
1010
import { CursorPositionTrackerService } from '../services/cursor-position-tracker/cursor-position-tracker.service';
1111
import { FlowCoreProviderService } from '../services/flow-core-provider/flow-core-provider.service';
1212
import { FlowResizeBatchProcessorService } from '../services/flow-resize-observer/flow-resize-processor.service';
@@ -59,7 +59,7 @@ export function provideNgDiagram(): Provider[] {
5959
FlowResizeBatchProcessorService,
6060
NgDiagramService,
6161
CursorPositionTrackerService,
62-
BatchDomObserverService,
62+
BatchResizeObserverService,
6363
NgDiagramViewportService,
6464
NgDiagramModelService,
6565
NgDiagramSelectionService,

packages/ng-diagram/projects/ng-diagram/src/lib/services/flow-resize-observer/batch-dom-observer.service.spec.ts renamed to packages/ng-diagram/projects/ng-diagram/src/lib/services/flow-resize-observer/batched-resize-observer.service.spec.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { TestBed } from '@angular/core/testing';
22
import { afterEach, beforeEach, describe, expect, it, type Mock, vi } from 'vitest';
3-
import { BatchDomObserverService, type ObservedElementMetadata } from './batch-dom-observer.service';
3+
import { BatchResizeObserverService, type ObservedElementMetadata } from './batched-resize-observer.service';
44

5-
describe('BatchDomObserverService', () => {
6-
let service: BatchDomObserverService;
5+
describe('BatchResizeObserverService', () => {
6+
let service: BatchResizeObserverService;
77
let mockResizeObserver: {
88
observe: ReturnType<typeof vi.fn>;
99
unobserve: ReturnType<typeof vi.fn>;
@@ -27,10 +27,10 @@ describe('BatchDomObserverService', () => {
2727
global.cancelAnimationFrame = mockCancelAnimationFrame;
2828

2929
TestBed.configureTestingModule({
30-
providers: [BatchDomObserverService],
30+
providers: [BatchResizeObserverService],
3131
});
3232

33-
service = TestBed.inject(BatchDomObserverService);
33+
service = TestBed.inject(BatchResizeObserverService);
3434
});
3535

3636
afterEach(() => {
@@ -118,6 +118,7 @@ describe('BatchDomObserverService', () => {
118118
const resizeObserverCallback = (global.ResizeObserver as Mock).mock.calls[0][0];
119119

120120
service['rafId'] = 456;
121+
mockRequestAnimationFrame.mockClear();
121122

122123
resizeObserverCallback(mockEntries);
123124

packages/ng-diagram/projects/ng-diagram/src/lib/services/flow-resize-observer/batch-dom-observer.service.ts renamed to packages/ng-diagram/projects/ng-diagram/src/lib/services/flow-resize-observer/batched-resize-observer.service.ts

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Injectable, NgZone, OnDestroy, inject } from '@angular/core';
1+
import { inject, Injectable, NgZone, OnDestroy } from '@angular/core';
22

33
export type BatchProcessor = (entries: ResizeObserverEntry[]) => void;
44

@@ -19,19 +19,17 @@ export type ObservedElementMetadata =
1919
};
2020

2121
@Injectable()
22-
export class BatchDomObserverService implements OnDestroy {
22+
export class BatchResizeObserverService implements OnDestroy {
2323
private readonly ngZone = inject(NgZone);
2424

2525
private observer: ResizeObserver | null = null;
26-
private styleObserver: MutationObserver | null = null;
2726
private observedElements = new WeakMap<Element, ObservedElementMetadata>();
28-
private styleObservedElements = new Set<Element>();
2927
private batchProcessor?: BatchProcessor;
3028
private rafId: number | null = null;
3129
private pendingEntries: ResizeObserverEntry[] = [];
3230

3331
constructor() {
34-
// Create observers outside Angular zone for performance
32+
// Create observer outside Angular zone for performance
3533
this.ngZone.runOutsideAngular(() => {
3634
this.observer = new ResizeObserver((entries) => {
3735
// Collect all entries
@@ -61,16 +59,6 @@ export class BatchDomObserverService implements OnDestroy {
6159
});
6260
}
6361
});
64-
65-
// Detects CSS-driven position changes (e.g., style.top binding) that don't trigger ResizeObserver.
66-
this.styleObserver = new MutationObserver((mutations) => {
67-
for (const mutation of mutations) {
68-
const element = mutation.target as Element;
69-
if (this.styleObservedElements.has(element)) {
70-
this.invalidate(element);
71-
}
72-
}
73-
});
7462
});
7563
}
7664

@@ -97,20 +85,6 @@ export class BatchDomObserverService implements OnDestroy {
9785
// WeakMap automatically handles cleanup
9886
}
9987

100-
/**
101-
* Observe an element's style attribute for changes.
102-
* When the style changes, the element is automatically invalidated
103-
* to trigger a position re-measurement via ResizeObserver.
104-
*/
105-
observeStyle(element: Element): void {
106-
this.styleObservedElements.add(element);
107-
this.styleObserver?.observe(element, { attributes: true, attributeFilter: ['style'] });
108-
}
109-
110-
unobserveStyle(element: Element): void {
111-
this.styleObservedElements.delete(element);
112-
}
113-
11488
/**
11589
* Force ResizeObserver to re-deliver an observation for the element.
11690
* Useful when an element's position changed without a size change,
@@ -148,6 +122,5 @@ export class BatchDomObserverService implements OnDestroy {
148122
cancelAnimationFrame(this.rafId);
149123
}
150124
this.observer?.disconnect();
151-
this.styleObserver?.disconnect();
152125
}
153126
}

0 commit comments

Comments
 (0)