Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions packages/core-browser/__tests__/dom/fastdom.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { fastdom } from '@opensumi/ide-core-browser';

/**
* 用于 mock requestAnimationFrame 的表现,可以手动触发动画帧
*/
class AnimationFrameController {
private callbacks: Array<() => void> = [];
private currentFrame: number = 0;
private running: boolean = false;

constructor() {
this.run = this.run.bind(this);
}

/**
* 触发动画帧
*/
public run() {
if (this.running) {
return;
}
this.running = true;
this.callbacks.forEach((callback) => {
callback();
});
this.running = false;
this.currentFrame++;
}

/**
* 注册回调函数
* @param callback
*/

public register(callback: () => void) {
this.callbacks.push(callback);
}

/**
* 注销回调函数
* @param callback
*/

public unregister(callback: () => void) {
const index = this.callbacks.indexOf(callback);
if (index !== -1) {
this.callbacks.splice(index, 1);
}
}

/**
* 获取当前的动画帧
*/
public getCurrentFrame() {
return this.currentFrame;
}
}

describe('fastdom', () => {
it('should measure', () => {
const animationFrameController = new AnimationFrameController();

let originalAnimationFrame = global.requestAnimationFrame;
let originalCancelAnimationFrame = global.cancelAnimationFrame;

global.requestAnimationFrame = (callback) => {
animationFrameController.register(callback);
return 1;
};

global.cancelAnimationFrame = () => {};
let count = 0;
fastdom.measure(() => {
count++;
expect(count).toBe(1);

fastdom.measure(() => {
// will run on current frame
count++;
expect(count).toBe(3);
});

fastdom.measureAtNextFrame(() => {
// will run on next frame
count++;
expect(count).toBe(4);

fastdom.measure(() => {
count += 2;
expect(count).toBe(6);
});
fastdom.mutate(() => {
count += 3;
expect(count).toBe(9);
});
});
});

fastdom.mutate(() => {
count++;
expect(count).toBe(2);
});

animationFrameController.run();
animationFrameController.run();
expect(count).toBe(9);
animationFrameController.run();
animationFrameController.run();
expect(count).toBe(9);

global.requestAnimationFrame = originalAnimationFrame;
global.cancelAnimationFrame = originalCancelAnimationFrame;
});
});
1 change: 1 addition & 0 deletions packages/core-browser/src/bootstrap/app.view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export function App(props: AppProps) {
lastFrame = null;
allSlot.forEach((item) => {
eventBus.fire(new ResizeEvent({ slotLocation: item.slot }));
eventBus.fireDirective(ResizeEvent.createDirective(item.slot));
});
});
};
Expand Down
15 changes: 8 additions & 7 deletions packages/core-browser/src/components/layout/split-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ export const SplitPanel: React.FC<SplitPanelProps> = (props) => {
(location?: string) => {
if (location) {
eventBus.fire(new ResizeEvent({ slotLocation: location }));
eventBus.fireDirective(ResizeEvent.createDirective(location));
}
},
[eventBus],
Expand Down Expand Up @@ -332,20 +333,19 @@ export const SplitPanel: React.FC<SplitPanelProps> = (props) => {
if (rootRef.current) {
splitPanelService.setRootNode(rootRef.current);
}
const disposer = eventBus.on(ResizeEvent, (e) => {
if (e.payload.slotLocation === id) {
childList.forEach((c) => {
fireResizeEvent(getProp(c, 'slot') || getProp(c, 'id'));
});
}
const disposer = eventBus.onDirective(ResizeEvent.createDirective(id), () => {
childList.forEach((c) => {
fireResizeEvent(getProp(c, 'slot') || getProp(c, 'id'));
});
});
return () => {
disposer.dispose();
};
}, []);

const renderSplitPanel = React.useMemo(() => {
const { minResize, flexGrow, minSize, maxSize, savedSize, defaultSize, flex, noResize, slot, ...rest } = props;
const { minResize, flexGrow, minSize, maxSize, savedSize, defaultSize, flex, noResize, slot, headerSize, ...rest } =
props;

delete rest['resizeHandleClassName'];
delete rest['dynamicTarget'];
Expand All @@ -364,6 +364,7 @@ export const SplitPanel: React.FC<SplitPanelProps> = (props) => {
data-max-size={maxSize}
data-saved-size={savedSize}
data-default-size={defaultSize}
data-header-size={headerSize}
data-flex={flex}
data-flex-grow={flexGrow}
data-no-resize={noResize}
Expand Down
Loading