@@ -12,17 +12,21 @@ function isNodeWithSize(node: LexicalNode): node is NodeHasSize&LexicalNode {
1212
1313class NodeResizer {
1414 protected context : EditorUiContext ;
15- protected dom : HTMLElement | null = null ;
15+ protected resizerDOM : HTMLElement | null = null ;
16+ protected targetDOM : HTMLElement | null = null ;
1617 protected scrollContainer : HTMLElement ;
1718
1819 protected mouseTracker : MouseDragTracker | null = null ;
1920 protected activeSelection : string = '' ;
21+ protected loadAbortController = new AbortController ( ) ;
2022
2123 constructor ( context : EditorUiContext ) {
2224 this . context = context ;
2325 this . scrollContainer = context . scrollDOM ;
2426
2527 this . onSelectionChange = this . onSelectionChange . bind ( this ) ;
28+ this . onTargetDOMLoad = this . onTargetDOMLoad . bind ( this ) ;
29+
2630 context . manager . onSelectionChange ( this . onSelectionChange ) ;
2731 }
2832
@@ -47,56 +51,68 @@ class NodeResizer {
4751 }
4852 }
4953
54+ onTargetDOMLoad ( ) : void {
55+ this . updateResizerPosition ( ) ;
56+ }
57+
5058 teardown ( ) {
5159 this . context . manager . offSelectionChange ( this . onSelectionChange ) ;
5260 this . hide ( ) ;
5361 }
5462
55- protected showForNode ( node : NodeHasSize & LexicalNode , dom : HTMLElement ) {
56- this . dom = this . buildDOM ( ) ;
63+ protected showForNode ( node : NodeHasSize & LexicalNode , targetDOM : HTMLElement ) {
64+ this . resizerDOM = this . buildDOM ( ) ;
65+ this . targetDOM = targetDOM ;
5766
5867 let ghost = el ( 'span' , { class : 'editor-node-resizer-ghost' } ) ;
5968 if ( $isImageNode ( node ) ) {
60- ghost = el ( 'img' , { src : dom . getAttribute ( 'src' ) , class : 'editor-node-resizer-ghost' } ) ;
69+ ghost = el ( 'img' , { src : targetDOM . getAttribute ( 'src' ) , class : 'editor-node-resizer-ghost' } ) ;
6170 }
62- this . dom . append ( ghost ) ;
71+ this . resizerDOM . append ( ghost ) ;
6372
64- this . context . scrollDOM . append ( this . dom ) ;
65- this . updateDOMPosition ( dom ) ;
73+ this . context . scrollDOM . append ( this . resizerDOM ) ;
74+ this . updateResizerPosition ( ) ;
6675
67- this . mouseTracker = this . setupTracker ( this . dom , node , dom ) ;
76+ this . mouseTracker = this . setupTracker ( this . resizerDOM , node , targetDOM ) ;
6877 this . activeSelection = node . getKey ( ) ;
78+
79+ if ( targetDOM . matches ( 'img, embed, iframe, object' ) ) {
80+ this . loadAbortController = new AbortController ( ) ;
81+ targetDOM . addEventListener ( 'load' , this . onTargetDOMLoad , { signal : this . loadAbortController . signal } ) ;
82+ }
6983 }
7084
71- protected updateDOMPosition ( nodeDOM : HTMLElement ) {
72- if ( ! this . dom ) {
85+ protected updateResizerPosition ( ) {
86+ if ( ! this . resizerDOM || ! this . targetDOM ) {
7387 return ;
7488 }
7589
7690 const scrollAreaRect = this . scrollContainer . getBoundingClientRect ( ) ;
77- const nodeRect = nodeDOM . getBoundingClientRect ( ) ;
91+ const nodeRect = this . targetDOM . getBoundingClientRect ( ) ;
7892 const top = nodeRect . top - ( scrollAreaRect . top - this . scrollContainer . scrollTop ) ;
7993 const left = nodeRect . left - scrollAreaRect . left ;
8094
81- this . dom . style . top = `${ top } px` ;
82- this . dom . style . left = `${ left } px` ;
83- this . dom . style . width = nodeRect . width + 'px' ;
84- this . dom . style . height = nodeRect . height + 'px' ;
95+ this . resizerDOM . style . top = `${ top } px` ;
96+ this . resizerDOM . style . left = `${ left } px` ;
97+ this . resizerDOM . style . width = nodeRect . width + 'px' ;
98+ this . resizerDOM . style . height = nodeRect . height + 'px' ;
8599 }
86100
87101 protected updateDOMSize ( width : number , height : number ) : void {
88- if ( ! this . dom ) {
102+ if ( ! this . resizerDOM ) {
89103 return ;
90104 }
91105
92- this . dom . style . width = width + 'px' ;
93- this . dom . style . height = height + 'px' ;
106+ this . resizerDOM . style . width = width + 'px' ;
107+ this . resizerDOM . style . height = height + 'px' ;
94108 }
95109
96110 protected hide ( ) {
97111 this . mouseTracker ?. teardown ( ) ;
98- this . dom ?. remove ( ) ;
112+ this . resizerDOM ?. remove ( ) ;
113+ this . targetDOM = null ;
99114 this . activeSelection = '' ;
115+ this . loadAbortController . abort ( ) ;
100116 }
101117
102118 protected buildDOM ( ) {
@@ -140,7 +156,7 @@ class NodeResizer {
140156
141157 return new MouseDragTracker ( container , '.editor-node-resizer-handle' , {
142158 down ( event : MouseEvent , handle : HTMLElement ) {
143- _this . dom ?. classList . add ( 'active' ) ;
159+ _this . resizerDOM ?. classList . add ( 'active' ) ;
144160 _this . context . editor . getEditorState ( ) . read ( ( ) => {
145161 const domRect = nodeDOM . getBoundingClientRect ( ) ;
146162 startingWidth = node . getWidth ( ) || domRect . width ;
@@ -165,10 +181,10 @@ class NodeResizer {
165181 node . setHeight ( hasHeight ? size . height : 0 ) ;
166182 _this . context . manager . triggerLayoutUpdate ( ) ;
167183 requestAnimationFrame ( ( ) => {
168- _this . updateDOMPosition ( nodeDOM ) ;
184+ _this . updateResizerPosition ( ) ;
169185 } )
170186 } ) ;
171- _this . dom ?. classList . remove ( 'active' ) ;
187+ _this . resizerDOM ?. classList . remove ( 'active' ) ;
172188 }
173189 } ) ;
174190 }
0 commit comments