@@ -2,9 +2,12 @@ import * as React from 'react';
22import type { Bookmark , EditorEvent , TinyMCE , Editor as TinyMCEEditor } from 'tinymce' ;
33import { IEvents } from '../Events' ;
44import { ScriptItem , ScriptLoader } from '../ScriptLoader2' ;
5- import { getTinymce } from '../TinyMCE' ;
6- import { configHandlers , isBeforeInputEventAvailable , isFunction , isInDoc , isTextareaOrInput , mergePlugins , setMode , uuid } from '../Utils' ;
5+ import { configHandlers , isBeforeInputEventAvailable ,
6+ isFunction , isInDoc , isTextareaOrInput , mergePlugins ,
7+ setMode , uuid , isDisabledOptionSupported ,
8+ getTinymceOrError } from '../Utils' ;
79import { EditorPropTypes , IEditorPropTypes } from './EditorPropTypes' ;
10+ import { getTinymce } from '../TinyMCE' ;
811
912const changeEvents = 'change keyup compositionend setcontent CommentChange' ;
1013
@@ -14,14 +17,15 @@ interface DoNotUse<T extends string> {
1417 __brand : T ;
1518}
1619
17- type OmittedInitProps = 'selector' | 'target' | 'readonly' | 'license_key' ;
20+ type OmittedInitProps = 'selector' | 'target' | 'readonly' | 'disabled' | ' license_key';
1821
1922type EditorOptions = Parameters < TinyMCE [ 'init' ] > [ 0 ] ;
2023
2124export type InitOptions = Omit < OmitStringIndexSignature < EditorOptions > , OmittedInitProps > & {
2225 selector ?: DoNotUse < 'selector prop is handled internally by the component' > ;
2326 target ?: DoNotUse < 'target prop is handled internally by the component' > ;
24- readonly ?: DoNotUse < 'readonly prop is overridden by the component, use the `disabled` prop instead' > ;
27+ readonly ?: DoNotUse < 'readonly prop is overridden by the component' > ;
28+ disabled ?: DoNotUse < 'disabled prop is overridden by the component' > ;
2529 license_key ?: DoNotUse < 'license_key prop is overridden by the integration, use the `licenseKey` prop instead' > ;
2630} & { [ key : string ] : unknown } ;
2731
@@ -95,9 +99,14 @@ export interface IProps {
9599 toolbar : NonNullable < EditorOptions [ 'toolbar' ] > ;
96100 /**
97101 * @see {@link https://www.tiny.cloud/docs/tinymce/7/react-ref/#disabled React Tech Ref - disabled }
98- * @description Whether the editor should be " disabled" (read-only) .
102+ * @description Whether the editor should be disabled.
99103 */
100104 disabled : boolean ;
105+ /**
106+ * @see {@link https://www.tiny.cloud/docs/tinymce/7/react-ref/#readonly React Tech Ref - readonly }
107+ * @description Whether the editor should be readonly.
108+ */
109+ readonly : boolean ;
101110 /**
102111 * @see {@link https://www.tiny.cloud/docs/tinymce/7/react-ref/#textareaname React Tech Ref - textareaName }
103112 * @description Set the `name` attribute of the `textarea` element used for the editor in forms. Only valid in iframe mode.
@@ -209,9 +218,18 @@ export class Editor extends React.Component<IAllProps> {
209218 }
210219 } ) ;
211220 }
221+
222+ if ( this . props . readonly !== prevProps . readonly ) {
223+ const readonly = this . props . readonly ?? false ;
224+ setMode ( this . editor , readonly ? 'readonly' : 'design' ) ;
225+ }
226+
212227 if ( this . props . disabled !== prevProps . disabled ) {
213- const disabled = this . props . disabled ?? false ;
214- setMode ( this . editor , disabled ? 'readonly' : 'design' ) ;
228+ if ( isDisabledOptionSupported ( this . view ) ) {
229+ this . editor . options . set ( 'disabled' , this . props . disabled ) ;
230+ } else {
231+ setMode ( this . editor , this . props . disabled ? 'readonly' : 'design' ) ;
232+ }
215233 }
216234 }
217235 }
@@ -431,16 +449,16 @@ export class Editor extends React.Component<IAllProps> {
431449 return ;
432450 }
433451
434- const tinymce = getTinymce ( this . view ) ;
435- if ( ! tinymce ) {
436- throw new Error ( 'tinymce should have been loaded into global scope' ) ;
437- }
452+ const tinymce = getTinymceOrError ( this . view ) ;
438453
439454 const finalInit : EditorOptions = {
440455 ...this . props . init as Omit < InitOptions , OmittedInitProps > ,
441456 selector : undefined ,
442457 target,
443- readonly : this . props . disabled ,
458+ ...isDisabledOptionSupported ( this . view )
459+ ? { disabled : this . props . disabled , readonly : this . props . readonly }
460+ : { readonly : this . props . disabled || this . props . readonly }
461+ ,
444462 inline : this . inline ,
445463 plugins : mergePlugins ( this . props . init ?. plugins , this . props . plugins ) ,
446464 toolbar : this . props . toolbar ?? this . props . init ?. toolbar ,
@@ -477,8 +495,7 @@ export class Editor extends React.Component<IAllProps> {
477495 editor . undoManager . add ( ) ;
478496 editor . setDirty ( false ) ;
479497 }
480- const disabled = this . props . disabled ?? false ;
481- setMode ( this . editor , disabled ? 'readonly' : 'design' ) ;
498+
482499 // ensure existing init_instance_callback is called
483500 if ( this . props . init && isFunction ( this . props . init . init_instance_callback ) ) {
484501 this . props . init . init_instance_callback ( editor ) ;
0 commit comments