@@ -74,6 +74,14 @@ export default class ImageTool implements BlockTool {
7474 */
7575 private _data : ImageToolData ;
7676
77+ /**
78+ * Caption enabled state
79+ * Null when user has not toggled the caption tune
80+ * True when user has toggled the caption tune
81+ * False when user has toggled the caption tune
82+ */
83+ private isCaptionEnabled : boolean | null = null ;
84+
7785 /**
7886 * @param tool - tool properties got from editor.js
7987 * @param tool.data - previously saved data
@@ -192,10 +200,10 @@ export default class ImageTool implements BlockTool {
192200 */
193201 public render ( ) : HTMLDivElement {
194202 if ( this . config . features ?. caption === true || this . config . features ?. caption === undefined || ( this . config . features ?. caption === 'optional' && this . data . caption ) ) {
195- this . ui . applyTune ( 'caption' , true ) ;
203+ this . isCaptionEnabled = true ;
196204 }
197205
198- return this . ui . render ( this . data ) as HTMLDivElement ;
206+ return this . ui . render ( ) as HTMLDivElement ;
199207 }
200208
201209 /**
@@ -252,20 +260,45 @@ export default class ImageTool implements BlockTool {
252260 return featureKey == null || this . config . features ?. [ featureKey as keyof FeaturesConfig ] !== false ;
253261 } ) ;
254262
263+ /**
264+ * Check if the tune is active
265+ * @param tune - tune to check
266+ */
267+ const isActive = ( tune : ActionConfig ) : boolean => {
268+ let currentState = this . data [ tune . name as keyof ImageToolData ] as boolean ;
269+
270+ if ( tune . name === 'caption' ) {
271+ currentState = this . isCaptionEnabled ?? currentState ;
272+ }
273+
274+ return currentState ;
275+ } ;
276+
255277 return availableTunes . map ( tune => ( {
256278 icon : tune . icon ,
257279 label : this . api . i18n . t ( tune . title ) ,
258280 name : tune . name ,
259281 toggle : tune . toggle ,
260- isActive : this . data [ tune . name as keyof ImageToolData ] as boolean ,
282+ isActive : isActive ( tune ) ,
261283 onActivate : ( ) => {
262284 /** If it'a user defined tune, execute it's callback stored in action property */
263285 if ( typeof tune . action === 'function' ) {
264286 tune . action ( tune . name ) ;
265287
266288 return ;
267289 }
268- this . tuneToggled ( tune . name as keyof ImageToolData ) ;
290+ let newState = ! isActive ( tune ) ;
291+
292+ /**
293+ * For the caption tune, we can't rely on the this._data
294+ * because it can be manualy toggled by user
295+ */
296+ if ( tune . name === 'caption' ) {
297+ this . isCaptionEnabled = ! ( this . isCaptionEnabled ?? false ) ;
298+ newState = this . isCaptionEnabled ;
299+ }
300+
301+ this . tuneToggled ( tune . name as keyof ImageToolData , newState ) ;
269302 } ,
270303 } ) ) ;
271304 }
@@ -367,6 +400,10 @@ export default class ImageTool implements BlockTool {
367400
368401 this . setTune ( tune as keyof ImageToolData , value ) ;
369402 } ) ;
403+
404+ if ( data . caption ) {
405+ this . setTune ( 'caption' , true ) ;
406+ }
370407 }
371408
372409 /**
@@ -417,15 +454,21 @@ export default class ImageTool implements BlockTool {
417454 /**
418455 * Callback fired when Block Tune is activated
419456 * @param tuneName - tune that has been clicked
457+ * @param state - new state
420458 */
421- private tuneToggled ( tuneName : keyof ImageToolData ) : void {
422- // inverse tune state
423- this . setTune ( tuneName , ! ( this . _data [ tuneName ] as boolean ) ) ;
424-
425- // reset caption on toggle
426- if ( tuneName === 'caption' && ! this . _data [ tuneName ] ) {
427- this . _data . caption = '' ;
428- this . ui . fillCaption ( '' ) ;
459+ private tuneToggled ( tuneName : keyof ImageToolData , state : boolean ) : void {
460+ if ( tuneName === 'caption' ) {
461+ this . ui . applyTune ( tuneName , state ) ;
462+
463+ if ( state == false ) {
464+ this . _data . caption = '' ;
465+ this . ui . fillCaption ( '' ) ;
466+ }
467+ } else {
468+ /**
469+ * Inverse tune state
470+ */
471+ this . setTune ( tuneName , state ) ;
429472 }
430473 }
431474
0 commit comments