Skip to content

Commit cd8926c

Browse files
TINY-11908: Fix disabled prop not mapped to readonly mode in TinyMCE < 7.6 (#466)
* TINY-11908: Fix disabled prop not mapped to readonly mode when using with TinyMCE < 7.6 * TINY-11908: Fix test
1 parent 3bf70c1 commit cd8926c

File tree

5 files changed

+68
-27
lines changed

5 files changed

+68
-27
lines changed

CHANGELOG.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## Unreleased
99

1010
### Added
11-
- The readonly prop now maps to the readonly editor option. See: [Editor important options: readonly](https://www.tiny.cloud/docs/tinymce/latest/editor-important-options/#readonly)
11+
- New `readonly` prop that can be used to toggle the editor's `readonly` mode. #TINY-11908
1212

1313
### Changed
14-
- The disabled prop now maps to the disabled editor option. See: [Editor important options: disabled](https://www.tiny.cloud/docs/tinymce/latest/editor-important-options/#disabled)
14+
- `disabled` prop is now mapped to the editor's `disabled` option. #TINY-11908
1515

1616
## 6.1.0 - 2024-10-22
1717

@@ -24,7 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2424
## 6.0.0 - 2024-06-05
2525

2626
### Added
27-
- Add missing events: `onInput`, `onCommentChange`, `onCompositionEnd`, `onCompositionStart`, `onCompositionUpdate`
27+
- Added missing events: `onInput`, `onCommentChange`, `onCompositionEnd`, `onCompositionStart`, `onCompositionUpdate`.
2828

2929
### Changed
3030
- Default cloud channel to '7'

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@tinymce/tinymce-vue",
3-
"version": "7.0.0-rc",
3+
"version": "6.2.0-rc",
44
"description": "Official TinyMCE Vue 3 Component",
55
"private": false,
66
"repository": {

src/main/ts/Utils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ const mergePlugins = (initPlugins: string | string[] | undefined, inputPlugins?:
155155
const isNullOrUndefined = (value: any): value is null | undefined =>
156156
value === null || value === undefined;
157157

158-
const isDisabledOptionSupported = (editor: TinyMCEEditor): boolean => typeof editor.options.set === 'function' && editor.options.isRegistered('disabled');
158+
const isDisabledOptionSupported = (editor: TinyMCEEditor): boolean =>
159+
typeof editor.options?.set === 'function' && editor.options.isRegistered('disabled');
159160

160161
export {
161162
bindHandlers,

src/main/ts/components/Editor.ts

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@ const renderIframe = (ce: any, id: string, elementRef: Ref<Element | null>) =>
3030

3131
const defaultInitValues = { selector: undefined, target: undefined };
3232

33+
const setMode = (editor: TinyMCEEditor, mode: 'readonly' | 'design') => {
34+
if (typeof editor.mode?.set === 'function') {
35+
editor.mode.set(mode);
36+
} else {
37+
// TinyMCE v4
38+
(editor as any).setMode(mode);
39+
}
40+
};
41+
3342
export const Editor = defineComponent({
3443
props: editorProps,
3544
setup: (props: IPropTypes, ctx) => {
@@ -52,15 +61,20 @@ export const Editor = defineComponent({
5261
const content = getContent(mounting);
5362
const finalInit = {
5463
...conf,
55-
readonly: props.readonly,
5664
disabled: props.disabled,
65+
readonly: props.readonly,
5766
target: element.value,
5867
plugins: mergePlugins(conf.plugins, props.plugins),
5968
toolbar: props.toolbar || (conf.toolbar),
6069
inline: inlineEditor,
6170
license_key: props.licenseKey,
6271
setup: (editor: TinyMCEEditor) => {
6372
vueEditor = editor;
73+
74+
if (!isDisabledOptionSupported(vueEditor) && props.disabled === true) {
75+
setMode(vueEditor, 'readonly');
76+
}
77+
6478
editor.on('init', (e: EditorEvent<any>) => initEditor(e, props, ctx, editor, modelValue, content));
6579
if (typeof conf.setup === 'function') {
6680
conf.setup(editor);
@@ -74,24 +88,16 @@ export const Editor = defineComponent({
7488
mounting = false;
7589
};
7690
watch(readonly, (isReadonly) => {
77-
if (vueEditor !== null && isDisabledOptionSupported(vueEditor)) {
78-
if (typeof vueEditor.mode?.set === 'function') {
79-
vueEditor.mode.set(isReadonly ? 'readonly' : 'design');
80-
} else {
81-
(vueEditor as any).setMode(isReadonly ? 'readonly' : 'design');
82-
}
91+
if (vueEditor !== null) {
92+
setMode(vueEditor, isReadonly ? 'readonly' : 'design');
8393
}
8494
});
85-
watch(disabled, (disable) => {
95+
watch(disabled, (isDisabled) => {
8696
if (vueEditor !== null) {
8797
if (isDisabledOptionSupported(vueEditor)) {
88-
vueEditor.options.set('disabled', disable);
98+
vueEditor.options.set('disabled', isDisabled);
8999
} else {
90-
if (typeof vueEditor.mode?.set === 'function') {
91-
vueEditor.mode.set(disable ? 'readonly' : 'design');
92-
} else {
93-
(vueEditor as any).setMode(disable ? 'readonly' : 'design');
94-
}
100+
setMode(vueEditor, isDisabled ? 'readonly' : 'design');
95101
}
96102
}
97103
});

src/stories/Editor.stories.tsx

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,17 @@ export default {
5353
defaultValue: {summary: '5'}
5454
},
5555
defaultValue: '7',
56-
options: ['5', '5-dev', '5-testing', '6-testing', '6-stable', '7-dev', '7-testing', '7-stable'],
56+
options: ['5', '5-dev', '5-testing', '6-testing', '6-stable', '7-dev', '7-testing', '7-stable', '7.3', '7.4', '7.6'],
5757
control: { type: 'select'}
5858
},
59+
disabled: {
60+
defaultValue: false,
61+
control: 'boolean'
62+
},
63+
readonly: {
64+
defaultValue: false,
65+
control: 'boolean'
66+
},
5967
conf: {
6068
defaultValue: '{height: 300}',
6169
control: { type: 'text' }
@@ -158,11 +166,41 @@ export const Disable: Story = (args) => ({
158166
});
159167
const cc = args.channel || lastChannel;
160168
const conf = getConf(args.conf);
161-
const disabled = ref(false);
162-
const readonly = ref(false);
169+
const disabled = ref(args.disabled);
163170
const toggleDisabled = (_) => {
164171
disabled.value = !disabled.value;
165172
}
173+
174+
return {
175+
apiKey,
176+
content,
177+
cloudChannel: cc,
178+
conf,
179+
disabled,
180+
toggleDisabled
181+
}
182+
},
183+
template: `
184+
<div>
185+
<button @click="toggleDisabled">{{ disabled ? 'enable' : 'disable' }}</button>
186+
<editor
187+
api-key="${apiKey}"
188+
:disabled="disabled"
189+
:init="conf"
190+
v-model="content"
191+
/>
192+
</div>`
193+
});
194+
195+
export const Readonly: Story = (args) => ({
196+
components: { Editor },
197+
setup() {
198+
onBeforeMount(() => {
199+
loadTiny(args);
200+
});
201+
const cc = args.channel || lastChannel;
202+
const conf = getConf(args.conf);
203+
const readonly = ref(args.readonly);
166204
const toggleReadonly = (_) => {
167205
readonly.value = !readonly.value;
168206
}
@@ -171,20 +209,16 @@ export const Disable: Story = (args) => ({
171209
content,
172210
cloudChannel: cc,
173211
conf,
174-
disabled,
175212
readonly,
176-
toggleDisabled,
177213
toggleReadonly
178214
}
179215
},
180216
template: `
181217
<div>
182-
<button @click="toggleDisabled">{{ disabled ? 'enable' : 'disable' }}</button>
183218
<button @click="toggleReadonly">{{ readonly ? 'design' : 'readonly' }}</button>
184219
<editor
185220
api-key="${apiKey}"
186-
v-bind:disabled="disabled"
187-
v-bind:readonly="readonly"
221+
:readonly="readonly"
188222
:init="conf"
189223
v-model="content"
190224
/>

0 commit comments

Comments
 (0)