-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Fix/issues#2151 #2339
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Fix/issues#2151 #2339
Changes from all commits
8bc0b84
eed6773
ac8dbba
902284a
15e51a5
9f43069
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -195,6 +195,9 @@ export class GraphModel { | |||||||||||||||||||||||||||||||||||||||||||||
| ((entries) => { | ||||||||||||||||||||||||||||||||||||||||||||||
| for (const entry of entries) { | ||||||||||||||||||||||||||||||||||||||||||||||
| if (entry.target === this.rootEl) { | ||||||||||||||||||||||||||||||||||||||||||||||
| // 检查元素是否仍在DOM中 | ||||||||||||||||||||||||||||||||||||||||||||||
| const isElementInDOM = document.body.contains(this.rootEl) | ||||||||||||||||||||||||||||||||||||||||||||||
| if (!isElementInDOM) return | ||||||||||||||||||||||||||||||||||||||||||||||
| this.resize() | ||||||||||||||||||||||||||||||||||||||||||||||
| this.eventCenter.emit('graph:resize', { | ||||||||||||||||||||||||||||||||||||||||||||||
| target: this.rootEl, | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1589,15 +1592,32 @@ export class GraphModel { | |||||||||||||||||||||||||||||||||||||||||||||
| * 重新设置画布的宽高 | ||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||
| @action resize(width?: number, height?: number): void { | ||||||||||||||||||||||||||||||||||||||||||||||
| this.width = width ?? this.rootEl.getBoundingClientRect().width | ||||||||||||||||||||||||||||||||||||||||||||||
| this.isContainerWidth = isNil(width) | ||||||||||||||||||||||||||||||||||||||||||||||
| this.height = height ?? this.rootEl.getBoundingClientRect().height | ||||||||||||||||||||||||||||||||||||||||||||||
| this.isContainerHeight = isNil(height) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| if (!this.width || !this.height) { | ||||||||||||||||||||||||||||||||||||||||||||||
| console.warn( | ||||||||||||||||||||||||||||||||||||||||||||||
| '渲染画布的时候无法获取画布宽高,请确认在container已挂载到DOM。@see https://github.com/didi/LogicFlow/issues/675', | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| // 检查当前实例是否已被销毁或rootEl不存在 | ||||||||||||||||||||||||||||||||||||||||||||||
| if (!this.rootEl) return | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // 检查元素是否仍在DOM中 | ||||||||||||||||||||||||||||||||||||||||||||||
| const isElementInDOM = document.body.contains(this.rootEl) | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
| const isElementInDOM = document.body.contains(this.rootEl) | |
| const isElementInDOM = this.rootEl.isConnected |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The visibility check using offsetParent !== null will return false for elements with position: fixed, even when they are visible on the screen. This could prevent legitimate resize operations from executing when the canvas uses fixed positioning. Consider using getComputedStyle(this.rootEl).display !== 'none' or checking both offsetParent and the element's fixed positioning status to handle this edge case.
| // 检查元素是否可见 | |
| const isVisible = this.rootEl.offsetParent !== null | |
| // 检查元素是否可见:兼容 position: fixed 的情况 | |
| const computedStyle = window.getComputedStyle(this.rootEl) | |
| const isVisible = | |
| computedStyle.display !== 'none' && | |
| computedStyle.visibility !== 'hidden' && | |
| (this.rootEl.offsetParent !== null || computedStyle.position === 'fixed') |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition if (isVisible && (!this.width || !this.height)) is redundant because the method already returns early when isVisible is false (line 1604). Since this code is only reached when isVisible is true, the check can be simplified to just if (!this.width || !this.height).
| if (isVisible && (!this.width || !this.height)) { | |
| if (!this.width || !this.height) { |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The visibility check using offsetParent !== null has limitations. It returns null for elements with position: fixed, even though they may be visible. Additionally, this check causes an early return that prevents the resize method from updating width and height when the element is temporarily hidden (e.g., in a hidden tab or collapsed panel), which may not be the intended behavior. Consider if resizing should still update internal state even when the element is not visible, or use a more robust visibility check that accounts for different CSS positioning.
| // 检查元素是否可见 | |
| const isVisible = this.rootEl.offsetParent !== null | |
| if (!isVisible) return | |
| try { | |
| this.width = width ?? this.rootEl.getBoundingClientRect().width | |
| this.isContainerWidth = isNil(width) | |
| this.height = height ?? this.rootEl.getBoundingClientRect().height | |
| this.isContainerHeight = isNil(height) | |
| // 只有在元素可见且应该有宽高的情况下才显示警告 | |
| if (isVisible && (!this.width || !this.height)) { | |
| try { | |
| this.width = width ?? this.rootEl.getBoundingClientRect().width | |
| this.isContainerWidth = isNil(width) | |
| this.height = height ?? this.rootEl.getBoundingClientRect().height | |
| this.isContainerHeight = isNil(height) | |
| // 当无法获取画布宽高时显示警告 | |
| if (!this.width || !this.height) { |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message is too generic and doesn't provide actionable information. It only states that an error occurred but doesn't explain what specific operation failed or what the developer should do to resolve it. Consider providing more specific information about what DOM operation failed and potential causes.
| // 捕获可能的DOM操作错误 | |
| console.warn('获取画布宽高时发生错误:', error) | |
| // 捕获可能的DOM操作错误,并提供更详细的上下文信息 | |
| const rootElInfo = this.rootEl | |
| ? `<${this.rootEl.tagName.toLowerCase()} id="${this.rootEl.id}"> (inDOM=${document.body.contains( | |
| this.rootEl, | |
| )}, visible=${this.rootEl.offsetParent !== null})` | |
| : 'rootEl is null/undefined' | |
| console.warn( | |
| '获取画布宽高时发生错误:无法通过 container.getBoundingClientRect() 计算画布尺寸。' + | |
| ' 这通常意味着 container 尚未挂载到 DOM、被 display:none 隐藏,或其尺寸为 0。' + | |
| ` container: ${rootElInfo}。原始错误:`, | |
| error, | |
| ) |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The try-catch block catches all errors but doesn't handle them meaningfully. The catch block only logs a warning, which means the method will silently fail to update width and height if getBoundingClientRect() throws an error. This could leave the component in an inconsistent state. Consider either re-throwing critical errors or implementing proper error recovery logic.
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new safety checks in the resize method (DOM existence check, visibility check, and error handling) lack test coverage. Consider adding tests that verify the behavior when: 1) rootEl is detached from DOM, 2) rootEl is hidden (offsetParent is null), and 3) getBoundingClientRect() operations might fail. This will ensure these defensive checks work as intended and prevent regressions.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ResizeObserver callback has duplicate DOM existence check logic. The same check
document.body.contains(this.rootEl)is performed both in the ResizeObserver callback (lines 199-200) and at the start of the resize method (lines 1599-1600). This creates redundant validation. Consider removing the check from the callback since the resize method will handle it, or document why both checks are necessary.