Skip to content

Commit 9e2f049

Browse files
TINY-11907: add 'readonly' property
1 parent b563d89 commit 9e2f049

File tree

5 files changed

+96
-5
lines changed

5 files changed

+96
-5
lines changed

stories/Editor.stories.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { MatTabsModule } from '@angular/material/tabs';
1515
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
1616
import { ContainerComponent, ContentProjectionComponent } from './contentprojection/ContentProjection.component';
1717
import { BindingComponent } from './data-binding/DataBinding.component';
18+
import { ReadonlyComponent } from './readonly/Readonly.component';
1819

1920
const meta: Meta = {
2021
component: EditorComponent,
@@ -137,6 +138,20 @@ export const DisablingStory: StoryObj<EditorComponent> = {
137138
}
138139
};
139140

141+
export const ReadonlyStory: StoryObj<EditorComponent> = {
142+
name: 'Readonly',
143+
render: () => ({
144+
moduleMetadata: {
145+
imports: [ ReactiveFormsModule, FormsModule ],
146+
declarations: [ ReadonlyComponent ],
147+
},
148+
template: `<readonly/>`
149+
}),
150+
parameters: {
151+
notes: 'Example of toggling readonly state in the editor component'
152+
}
153+
};
154+
140155
export const ViewQueryStory: StoryObj<EditorComponent> = {
141156
name: 'View Query',
142157
render: () => ({
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<button (click)="toggleReadonly()">{{ isReadonly ? 'Escape readonly' : 'Enter readonly' }}</button>
2+
<editor
3+
[apiKey]="apiKey"
4+
[readonly]="isReadonly"
5+
[initialValue]="initialValue"
6+
[init]="{ height: 300 }"
7+
/>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Component } from '@angular/core';
2+
import { apiKey, sampleContent } from '../Settings';
3+
4+
@Component({
5+
selector: 'readonly',
6+
templateUrl: './Readonly.component.html',
7+
})
8+
export class ReadonlyComponent {
9+
public isReadonly = false;
10+
public apiKey = apiKey;
11+
public initialValue = sampleContent;
12+
public toggleReadonly = () => (this.isReadonly = !this.isReadonly);
13+
}

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,18 @@ export class EditorComponent extends Events implements AfterViewInit, ControlVal
6565
@Input() public modelEvents = 'change input undo redo';
6666
@Input() public allowedEvents?: string | string[];
6767
@Input() public ignoreEvents?: string | string[];
68+
@Input()
69+
public set readonly(val) {
70+
this._readonly = val;
71+
if (this._editor && this._editor.initialized) {
72+
setMode(this._editor, val ? 'readonly' : 'design');
73+
}
74+
}
75+
76+
public get readonly() {
77+
return this._readonly;
78+
}
79+
6880
@Input()
6981
public set disabled(val) {
7082
this._disabled = val;
@@ -90,6 +102,7 @@ export class EditorComponent extends Events implements AfterViewInit, ControlVal
90102
private _elementRef: ElementRef;
91103
private _element?: HTMLElement;
92104
private _disabled?: boolean;
105+
private _readonly?: boolean;
93106
private _editor?: TinyMCEEditor;
94107

95108
private onTouchedCallback = noop;
@@ -177,7 +190,10 @@ export class EditorComponent extends Events implements AfterViewInit, ControlVal
177190
selector: undefined,
178191
target: this._element,
179192
inline: this.inline,
180-
...( DisabledUtils.isDisabledOptionSupported() ? { disabled: this.disabled } : { readonly: this.disabled } ),
193+
...( DisabledUtils.isDisabledOptionSupported()
194+
? { disabled: this.disabled, readonly: this.readonly }
195+
: { readonly: this.disabled || this.readonly }
196+
),
181197
license_key: this.licenseKey,
182198
plugins: mergePlugins((this.init && this.init.plugins) as string, this.plugins),
183199
toolbar: this.toolbar || (this.init && this.init.toolbar),

tinymce-angular-component/src/test/ts/browser/DisabledPropertyTest.ts

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,14 @@ import { eachVersionContext, editorHook } from '../alien/TestHooks';
77
import { Editor } from 'tinymce';
88

99
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());
10+
const getMode = (editor: Editor) => {
11+
if (typeof editor.mode?.get === 'function') {
12+
return editor.mode.get();
13+
}
14+
return editor.readonly ? 'readonly' : 'design';
15+
};
16+
const assertDesignMode = (editor: Editor) => Assertions.assertEq('TinyMCE should be in design mode', 'design', getMode(editor));
17+
const assertReadonlyMode = (editor: Editor) => Assertions.assertEq('TinyMCE should be in readonly mode', 'readonly', getMode(editor));
1218
const assertDisabledOption = (editor: Editor, expected: boolean) =>
1319
Assertions.assertEq(`TinyMCE should have disabled option set to ${expected}`, expected, editor.options.get('disabled'));
1420

@@ -34,13 +40,23 @@ describe('DisabledPropertyTest', () => {
3440
fixture.detectChanges();
3541
assertDesignMode(editor);
3642
});
43+
44+
it(`[disabled]=true [readonly]=false triggers readonly mode`, async () => {
45+
const { editor } = await createFixture({ disabled: true, readonly: false });
46+
assertReadonlyMode(editor);
47+
});
48+
49+
it(`[disabled]=false [readonly]=true triggers readonly mode`, async () => {
50+
const { editor } = await createFixture({ disabled: false, readonly: true });
51+
assertReadonlyMode(editor);
52+
});
3753
});
3854

3955
eachVersionContext([ '7.6.0' ], () => {
4056
const createFixture = editorHook(EditorComponent);
4157

4258
it(`Component 'disabled' property is mapped to editor 'disabled' property`, async () => {
43-
const { editor } = await createFixture({ cloudChannel: '7.6.0', disabled: true });
59+
const { editor } = await createFixture({ disabled: true });
4460

4561
Assertions.assertEq('TinyMCE should have disabled option set to true', true, editor.options.get('disabled'));
4662
assertDesignMode(editor);
@@ -64,4 +80,28 @@ describe('DisabledPropertyTest', () => {
6480
assertDisabledOption(editor, false);
6581
});
6682
});
67-
});
83+
84+
eachVersionContext([ '4', '5', '6', '7' ], () => {
85+
const createFixture = editorHook(EditorComponent);
86+
87+
it(`Setting the 'readonly' property causing readonly mode`, async () => {
88+
const { editor } = await createFixture({ readonly: true });
89+
assertReadonlyMode(editor);
90+
});
91+
92+
it(`Toggling component's 'readonly' property is mapped to editor 'readonly' mode`, async () => {
93+
const fixture = await createFixture();
94+
const { editor } = fixture;
95+
96+
assertDesignMode(editor);
97+
98+
fixture.componentRef.setInput('readonly', true);
99+
fixture.detectChanges();
100+
assertReadonlyMode(editor);
101+
102+
fixture.componentRef.setInput('readonly', false);
103+
fixture.detectChanges();
104+
assertDesignMode(editor);
105+
});
106+
});
107+
});

0 commit comments

Comments
 (0)