Skip to content

Commit bc23fb2

Browse files
TINY-11907: add support for 'disabled' property
1 parent 63ee891 commit bc23fb2

File tree

6 files changed

+111
-9
lines changed

6 files changed

+111
-9
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767
"tinymce-5": "npm:tinymce@^5",
6868
"tinymce-6": "npm:tinymce@^6",
6969
"tinymce-7": "npm:tinymce@^7",
70+
"tinymce-7.5.0": "npm:[email protected]",
71+
"tinymce-7.6.0": "npm:[email protected]",
7072
"to-string-loader": "^1.1.5",
7173
"tslib": "^2.6.2",
7274
"typescript": "~5.5.4",

tinymce-angular-component/src/main/ts/editor/editor.component.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import {
1818
import { FormsModule, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
1919
import { Subject, takeUntil } from 'rxjs';
2020
import { getTinymce } from '../TinyMCE';
21-
import { listenTinyMCEEvent, bindHandlers, isTextarea, mergePlugins, uuid, noop, isNullOrUndefined } from '../utils/Utils';
21+
import { listenTinyMCEEvent, bindHandlers, isTextarea, mergePlugins, uuid, noop, isNullOrUndefined, setMode } from '../utils/Utils';
22+
import * as DisabledUtils from '../utils/DisabledUtils';
2223
import { EventObj, Events } from './Events';
2324
import { ScriptLoader } from '../utils/ScriptLoader';
2425
import type { Editor as TinyMCEEditor, TinyMCE } from 'tinymce';
@@ -68,11 +69,11 @@ export class EditorComponent extends Events implements AfterViewInit, ControlVal
6869
public set disabled(val) {
6970
this._disabled = val;
7071
if (this._editor && this._editor.initialized) {
71-
if (typeof this._editor.mode?.set === 'function') {
72-
this._editor.mode.set(val ? 'readonly' : 'design');
73-
} else if ('setMode' in this._editor && typeof this._editor.setMode === 'function') {
74-
this._editor.setMode(val ? 'readonly' : 'design');
72+
if (DisabledUtils.isDisabledOptionSupported()) {
73+
this._editor.options.set('disabled', val ?? false);
74+
return;
7575
}
76+
setMode(this._editor, val ? 'readonly' : 'design');
7677
}
7778
}
7879

@@ -176,7 +177,7 @@ export class EditorComponent extends Events implements AfterViewInit, ControlVal
176177
selector: undefined,
177178
target: this._element,
178179
inline: this.inline,
179-
readonly: this.disabled,
180+
...( DisabledUtils.isDisabledOptionSupported() ? { disabled: this.disabled } : { readonly: this.disabled } ),
180181
license_key: this.licenseKey,
181182
plugins: mergePlugins((this.init && this.init.plugins) as string, this.plugins),
182183
toolbar: this.toolbar || (this.init && this.init.toolbar),
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { TinyVer } from '@tinymce/miniature';
2+
import { getTinymce } from '../TinyMCE';
3+
import { TinyMCE } from 'tinymce';
4+
5+
const isDisabledOptionSupported = () => {
6+
const tiny: TinyMCE = getTinymce();
7+
return !TinyVer.isLessThan(tiny, '7.6.0');
8+
};
9+
10+
export {
11+
isDisabledOptionSupported
12+
};

tinymce-angular-component/src/main/ts/utils/Utils.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { HasEventTargetAddRemove } from 'rxjs/internal/observable/fromEvent';
1212

1313
import { EditorComponent } from '../editor/editor.component';
1414
import { validEvents, Events } from '../editor/Events';
15+
import { Editor } from 'tinymce';
1516

1617
// Caretaker note: `fromEvent` supports passing JQuery-style event targets, the editor has `on` and `off` methods which
1718
// will be invoked upon subscription and teardown.
@@ -47,10 +48,10 @@ const getValidEvents = (ctx: EditorComponent): (keyof Events)[] => {
4748
};
4849

4950
const parseStringProperty = (property: string | string[] | undefined, defaultValue: (keyof Events)[]): string[] => {
50-
if ( typeof property === 'string') {
51+
if (typeof property === 'string') {
5152
return property.split(',').map((value) => value.trim());
5253
}
53-
if ( Array.isArray(property)) {
54+
if (Array.isArray(property)) {
5455
return property;
5556
}
5657
return defaultValue;
@@ -91,6 +92,14 @@ const isObserved = (o: Subject<unknown>): boolean =>
9192
// checking if a subject has observers.
9293
o.observed || o.observers?.length > 0;
9394

95+
const setMode = (editor: Editor, mode: 'readonly' | 'design') => {
96+
if (typeof editor.mode?.set === 'function') {
97+
editor.mode.set(mode);
98+
} else if ('setMode' in editor && typeof editor.setMode === 'function') {
99+
editor.setMode(mode);
100+
}
101+
};
102+
94103
export {
95104
listenTinyMCEEvent,
96105
bindHandlers,
@@ -99,5 +108,6 @@ export {
99108
normalizePluginArray,
100109
mergePlugins,
101110
noop,
102-
isNullOrUndefined
111+
isNullOrUndefined,
112+
setMode
103113
};
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { Assertions } from '@ephox/agar';
2+
import '../alien/InitTestEnvironment';
3+
4+
import { EditorComponent } from '../../../main/ts/public_api';
5+
import { describe, it } from '@ephox/bedrock-client';
6+
import { eachVersionContext, editorHook } from '../alien/TestHooks';
7+
import { Editor } from 'tinymce';
8+
9+
describe('DisabledPropertyTest', () => {
10+
const assertDesignMode = (editor: Editor) => Assertions.assertEq('TinyMCE should be in design mode', 'design', editor.mode.get());
11+
const assertReadonlyMode = (editor: Editor) => Assertions.assertEq('TinyMCE should be in readonly mode', 'readonly', editor.mode.get());
12+
const assertDisabledOption = (editor: Editor, expected: boolean) =>
13+
Assertions.assertEq(`TinyMCE should have disabled option set to ${expected}`, expected, editor.options.get('disabled'));
14+
15+
eachVersionContext([ '7.5.0' ], () => {
16+
const createFixture = editorHook(EditorComponent);
17+
18+
it(`Component 'disabled' property is mapped to editor 'readonly' property`, async () => {
19+
const { editor } = await createFixture({ disabled: true });
20+
assertReadonlyMode(editor);
21+
});
22+
23+
it(`Toggling component's 'disabled' property is mapped to editor 'readonly' property`, async () => {
24+
const fixture = await createFixture();
25+
const { editor } = fixture;
26+
27+
assertDesignMode(editor);
28+
29+
fixture.componentRef.setInput('disabled', true);
30+
fixture.detectChanges();
31+
assertReadonlyMode(editor);
32+
33+
fixture.componentRef.setInput('disabled', false);
34+
fixture.detectChanges();
35+
assertDesignMode(editor);
36+
});
37+
});
38+
39+
eachVersionContext([ '7.6.0' ], () => {
40+
const createFixture = editorHook(EditorComponent);
41+
42+
it(`Component 'disabled' property is mapped to editor 'disabled' property`, async () => {
43+
const { editor } = await createFixture({ cloudChannel: '7.6.0', disabled: true });
44+
45+
Assertions.assertEq('TinyMCE should have disabled option set to true', true, editor.options.get('disabled'));
46+
assertDesignMode(editor);
47+
});
48+
49+
it(`Toggling component's 'disabled' property is mapped to editor 'disabled' property`, async () => {
50+
const fixture = await createFixture();
51+
const { editor } = fixture;
52+
53+
assertDesignMode(editor);
54+
assertDisabledOption(editor, false);
55+
56+
fixture.componentRef.setInput('disabled', true);
57+
fixture.detectChanges();
58+
assertDesignMode(editor);
59+
assertDisabledOption(editor, true);
60+
61+
fixture.componentRef.setInput('disabled', false);
62+
fixture.detectChanges();
63+
assertDesignMode(editor);
64+
assertDisabledOption(editor, false);
65+
});
66+
});
67+
});

yarn.lock

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13082,6 +13082,16 @@ tiny-invariant@^1.3.1, tiny-invariant@^1.3.3:
1308213082
resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-6.8.3.tgz#0025a4aaa4c24dc2a3e32e83dfda705d196fd802"
1308313083
integrity sha512-3fCHKAeqT+xNwBVESf6iDbDV0VNwZNmfrkx9c/6Gz5iB8piMfaO6s7FvoiTrj1hf1gVbfyLTnz1DooI6DhgINQ==
1308413084

13085+
"tinymce-7.5.0@npm:[email protected]":
13086+
version "7.5.0"
13087+
resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-7.5.0.tgz#56388d314399c288a100df4aaf468153f29477f1"
13088+
integrity sha512-A7iuQPIfeze5rO6bvnnPwP7TiWnPA9AGr8U/9ssLwrEG+FMYPzvLPt3RT8ktVn/wPSJkVBBSLCAZX2dAHb8YEA==
13089+
13090+
"tinymce-7.6.0@npm:[email protected]":
13091+
version "7.6.0"
13092+
resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-7.6.0.tgz#476069a3e98f46f3f6e7875ca878313d6b3345b9"
13093+
integrity sha512-kUrklnD7H8JbpSDEGRh51GKK6Mrf+pR9neSDzUHvXKV+2oRtMB7sqfAtEOnM0/WKdstwaX0qoNCZNo2H1Y0EFA==
13094+
1308513095
"tinymce-7@npm:tinymce@^7":
1308613096
version "7.1.2"
1308713097
resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-7.1.2.tgz#cb40e527dc03d6a0547a23c91231a946e50dae03"

0 commit comments

Comments
 (0)