@@ -91,19 +91,26 @@ export const CustomBubbleMenu: React.FC<CustomBubbleMenuProps> = ({
9191 // 创建虚拟元素代表选区位置
9292 const virtualElement = {
9393 getBoundingClientRect : ( ) => {
94- const start = view . coordsAtPos ( from ) ;
95- const end = view . coordsAtPos ( to ) ;
96-
97- return {
98- top : Math . min ( start . top , end . top ) ,
99- bottom : Math . max ( start . bottom , end . bottom ) ,
100- left : Math . min ( start . left , end . left ) ,
101- right : Math . max ( start . right , end . right ) ,
102- width : Math . abs ( end . right - start . left ) ,
103- height : Math . abs ( end . bottom - start . top ) ,
104- x : Math . min ( start . left , end . left ) ,
105- y : Math . min ( start . top , end . top ) ,
106- } ;
94+ try {
95+ const docSize = state . doc . content . size ;
96+ const clampedFrom = Math . max ( 0 , Math . min ( from , docSize ) ) ;
97+ const clampedTo = Math . max ( 0 , Math . min ( to , docSize ) ) ;
98+ const start = view . coordsAtPos ( clampedFrom ) ;
99+ const end = view . coordsAtPos ( clampedTo ) ;
100+
101+ return {
102+ top : Math . min ( start . top , end . top ) ,
103+ bottom : Math . max ( start . bottom , end . bottom ) ,
104+ left : Math . min ( start . left , end . left ) ,
105+ right : Math . max ( start . right , end . right ) ,
106+ width : Math . abs ( end . right - start . left ) ,
107+ height : Math . abs ( end . bottom - start . top ) ,
108+ x : Math . min ( start . left , end . left ) ,
109+ y : Math . min ( start . top , end . top ) ,
110+ } ;
111+ } catch {
112+ return new DOMRect ( ) ;
113+ }
107114 } ,
108115 } ;
109116
@@ -163,22 +170,29 @@ export const CustomBubbleMenu: React.FC<CustomBubbleMenuProps> = ({
163170 const cleanup = autoUpdate (
164171 {
165172 getBoundingClientRect : ( ) => {
166- const { selection } = editor . state ;
167-
168- if ( selection . empty ) {
173+ try {
174+ const { selection } = editor . state ;
175+
176+ if ( selection . empty ) {
177+ return new DOMRect ( ) ;
178+ }
179+
180+ const { from, to } = selection ;
181+ const docSize = editor . state . doc . content . size ;
182+ const clampedFrom = Math . max ( 0 , Math . min ( from , docSize ) ) ;
183+ const clampedTo = Math . max ( 0 , Math . min ( to , docSize ) ) ;
184+ const start = editor . view . coordsAtPos ( clampedFrom ) ;
185+ const end = editor . view . coordsAtPos ( clampedTo ) ;
186+
187+ return new DOMRect (
188+ Math . min ( start . left , end . left ) ,
189+ Math . min ( start . top , end . top ) ,
190+ Math . abs ( end . right - start . left ) ,
191+ Math . abs ( end . bottom - start . top ) ,
192+ ) ;
193+ } catch {
169194 return new DOMRect ( ) ;
170195 }
171-
172- const { from, to } = selection ;
173- const start = editor . view . coordsAtPos ( from ) ;
174- const end = editor . view . coordsAtPos ( to ) ;
175-
176- return new DOMRect (
177- Math . min ( start . left , end . left ) ,
178- Math . min ( start . top , end . top ) ,
179- Math . abs ( end . right - start . left ) ,
180- Math . abs ( end . bottom - start . top ) ,
181- ) ;
182196 } ,
183197 } ,
184198 menuEl ,
0 commit comments