Skip to content

Commit 73417d6

Browse files
INT-3352: Add support for tiny 8 (#470)
* INT-3352: Add support for tiny 8 * INT-3352: Update README.md and add changelog entry * INT-3352: skip failing tests until tiny 8 is released * Add 8.0 to peerdependencies * Set the cloud channel to 8 * Update docs * Tidy up * Revert package version * Set the default channel in storybook to 8 * Clean up * Update src/test/ts/browser/LoadTinyTest.ts Co-authored-by: Hamza Benkhaldoun <hamza0867@gmail.com> * Fix failing test --------- Co-authored-by: Ben Tran <ben.tran@tiny.cloud>
1 parent 0aa9fd2 commit 73417d6

File tree

12 files changed

+188
-523
lines changed

12 files changed

+188
-523
lines changed

.eslintrc.json

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"src/**/*.tsx"
77
],
88
"excludedFiles": [
9-
"src/demo/demo.ts"
9+
"src/demo/demo.ts",
10+
"src/**/*.stories.*"
1011
],
1112
"plugins": ["@typescript-eslint"],
1213
"extends": "plugin:@tinymce/standard",
@@ -18,6 +19,21 @@
1819
"@tinymce/prefer-fun": "off"
1920
}
2021
},
22+
{
23+
"files": [ "src/**/*.stories.*" ],
24+
"plugins": ["@typescript-eslint"],
25+
"extends": "plugin:@tinymce/standard",
26+
"parserOptions": {
27+
"project": "tsconfig.storybook.json",
28+
"sourceType": "module"
29+
},
30+
"rules": {
31+
"@tinymce/prefer-fun": "off",
32+
"no-console": "off",
33+
"@typescript-eslint/no-implied-eval": "off",
34+
"@typescript-eslint/no-unsafe-argument": "off"
35+
}
36+
},
2137
{
2238
"files": [
2339
"**/*.js"
@@ -43,4 +59,4 @@
4359
}
4460
}
4561
]
46-
}
62+
}

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
### Changed
11+
- Set the default cloudChannel to `'8'`. #INT-3352
12+
1013
## 6.2.0 - 2025-06-02
1114

1215
### Added

README.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,25 @@
44

55
This package is a thin wrapper around [TinyMCE](https://github.com/tinymce/tinymce) to make it easier to use in a Vue application.
66

7-
* If you need detailed documentation on TinyMCE, see: [TinyMCE Documentation](https://www.tiny.cloud/docs/tinymce/7/).
8-
* For the TinyMCE Vue Quick Start, see: [TinyMCE Documentation - Vue Integration](https://www.tiny.cloud/docs/tinymce/7/vue-cloud).
9-
* For the TinyMCE Vue Technical Reference, see: [TinyMCE Documentation - TinyMCE Vue Technical Reference](https://www.tiny.cloud/docs/tinymce/7/vue-ref).
7+
* If you need detailed documentation on TinyMCE, see: [TinyMCE Documentation](https://www.tiny.cloud/docs/tinymce/latest/).
8+
* For the TinyMCE Vue Quick Start, see: [TinyMCE Documentation - Vue Integration](https://www.tiny.cloud/docs/tinymce/latest/vue-cloud).
9+
* For the TinyMCE Vue Technical Reference, see: [TinyMCE Documentation - TinyMCE Vue Technical Reference](https://www.tiny.cloud/docs/tinymce/latest/vue-ref).
1010
* For our quick demos, check out the TinyMCE Vue [Storybook](https://tinymce.github.io/tinymce-vue/).
1111

1212

13-
### Support
13+
### Tinymce version compatibility
1414

15-
Version 7.0 is intended to support the tinymce version 7.6 and above.
16-
Version 4.0 is intended to support Vue 3. For Vue 2.x and below please use previous versions of the wrapper.
15+
| tinymce | tinymce-vue version |
16+
| --- | --- |
17+
| 7.6 and above | 6.2 and above |
18+
| below 7.6 | Versions prior to 6.2 |
19+
20+
### Vue version compatibility
21+
22+
| vue | tinymce-vue |
23+
| --- | --- |
24+
| 3.x | 4.0 and above |
25+
| 2.x | Versions prior to 4.0 |
1726

1827
### Issues
1928

SECURITY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
## Reporting a Vulnerability
44

5-
For details on how to report security issues to Tiny, refer to the [Reporting TinyMCE security issues documentation](https://www.tiny.cloud/docs/tinymce/6/security/#reportingtinymcesecurityissues).
5+
For details on how to report security issues to Tiny, refer to the [Reporting TinyMCE security issues documentation](https://www.tiny.cloud/docs/tinymce/latest/security/#reportingtinymcesecurityissues).

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"LICENSE.txt"
3434
],
3535
"peerDependencies": {
36-
"tinymce": "^7.0.0 || ^6.0.0 || ^5.5.1",
36+
"tinymce": "^8.0.0 || ^7.0.0 || ^6.0.0 || ^5.5.1",
3737
"vue": "^3.0.0"
3838
},
3939
"peerDependenciesMeta": {
@@ -75,11 +75,12 @@
7575
"rollup-plugin-node-resolve": "^5.2.0",
7676
"rollup-plugin-typescript2": "^0.34.1",
7777
"rollup-plugin-uglify": "^6.0.0",
78-
"tinymce": "^7",
78+
"tinymce": "^8.0.0",
7979
"tinymce-4": "npm:tinymce@^4",
8080
"tinymce-5": "npm:tinymce@^5",
8181
"tinymce-6": "npm:tinymce@^6",
8282
"tinymce-7": "npm:tinymce@^7",
83+
"tinymce-8": "npm:tinymce@^8",
8384
"ts-loader": "^9.5.1",
8485
"ts-node": "^10.9.2",
8586
"tsconfig-paths-webpack-plugin": "^4.1.0",

src/main/ts/components/Editor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ export const Editor = defineComponent({
114114
if (getTinymce() !== null) {
115115
initWrapper();
116116
} else if (element.value && element.value.ownerDocument) {
117-
const channel = props.cloudChannel ? props.cloudChannel : '7';
117+
const channel = props.cloudChannel ? props.cloudChannel : '8';
118118
const apiKey = props.apiKey ? props.apiKey : 'no-api-key';
119119
const scriptSrc: string = isNullOrUndefined(props.tinymceScriptSrc) ?
120120
`https://cdn.tiny.cloud/1/${apiKey}/tinymce/${channel}/tinymce.min.js` :

src/stories/Editor.stories.tsx

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Story } from '@storybook/vue3';
22
import { onBeforeMount, ref } from 'vue';
33
import { ScriptLoader } from '../main/ts/ScriptLoader';
44

5-
import type { EditorEvent, Editor as TinyMCEEditor } from 'tinymce';
5+
import type { EditorEvent } from 'tinymce';
66
import { Editor } from '../main/ts/components/Editor';
77

88
const apiKey = 'qagffr3pkuv17a8on1afax661irst1hbr4e6tbv888sz91jc';
@@ -11,20 +11,22 @@ const content = `
1111
TinyMCE provides a <span style="text-decoration: underline;">full-featured</span> rich text editing experience, and a featherweight download.
1212
</h2>
1313
<p style="text-align: center;">
14-
<strong><span style="font-size: 14pt;"><span style="color: #7e8c8d; font-weight: 600;">No matter what you're building, TinyMCE has got you covered.</span></span></strong>
14+
<strong>
15+
<span style="font-size: 14pt;"><span style="color: #7e8c8d; font-weight: 600;">No matter what you're building, TinyMCE has got you covered.</span></span>
16+
</strong>
1517
</p>`;
1618

17-
let lastChannel = '5';
19+
let lastChannel = '8';
1820
const getConf = (stringConf: string) => {
19-
let conf = {};
21+
let conf = {};
2022
console.log('parsing: ', stringConf);
2123
try {
2224
conf = Function('"use strict";return (' + stringConf + ')')();
2325
} catch (err) {
2426
console.error('failed to parse configuration: ', err);
2527
}
2628
return conf;
27-
}
29+
};
2830

2931
const removeTiny = () => {
3032
delete (window as any).tinymce;
@@ -43,18 +45,17 @@ const loadTiny = (currentArgs: any) => {
4345
}
4446
};
4547

46-
4748
export default {
4849
title: 'Editor',
4950
component: Editor,
5051
argTypes: {
5152
channel: {
5253
table: {
53-
defaultValue: {summary: '5'}
54+
defaultValue: { summary: '5' }
5455
},
55-
defaultValue: '7',
56-
options: ['5', '5-dev', '5-testing', '6-testing', '6-stable', '7-dev', '7-testing', '7-stable', '7.3', '7.4', '7.6'],
57-
control: { type: 'select'}
56+
defaultValue: '8-stable',
57+
options: [ '5', '5-dev', '5-testing', '6-testing', '6-stable', '7-dev', '7-testing', '7-stable', '7.3', '7.4', '7.6', '8-dev', '8-testing', '8-stable' ],
58+
control: { type: 'select' }
5859
},
5960
disabled: {
6061
defaultValue: false,
@@ -80,8 +81,8 @@ export default {
8081
};
8182

8283
export const Iframe: Story = (args) => ({
83-
components: {Editor},
84-
setup() {
84+
components: { Editor },
85+
setup: () => {
8586
onBeforeMount(() => {
8687
loadTiny(args);
8788
});
@@ -92,14 +93,14 @@ export const Iframe: Story = (args) => ({
9293
content,
9394
cloudChannel: cc,
9495
conf
95-
}
96+
};
9697
},
9798
template: '<div ><p>Ready</p><editor :api-key="apiKey" :initialValue="content" :cloud-channel="cloudChannel" :init="conf" /></div>'
9899
});
99100

100101
export const Inline: Story = (args) => ({
101102
components: { Editor },
102-
setup() {
103+
setup: () => {
103104
onBeforeMount(() => {
104105
loadTiny(args);
105106
});
@@ -110,7 +111,7 @@ export const Inline: Story = (args) => ({
110111
content,
111112
cloudChannel: cc,
112113
conf
113-
}
114+
};
114115
},
115116
template: `
116117
<div style="padding-top: 100px;">
@@ -125,21 +126,23 @@ export const Inline: Story = (args) => ({
125126

126127
export const Controlled: Story = (args) => ({
127128
components: { Editor },
128-
setup() {
129+
setup: () => {
129130
onBeforeMount(() => {
130131
loadTiny(args);
131132
});
132133
const cc = args.channel || lastChannel;
133134
const conf = getConf(args.conf);
134-
const log = (e: EditorEvent<any>, editor: TinyMCEEditor) => {console.log(e);};
135+
const log = (e: EditorEvent<any>) => {
136+
console.log(e);
137+
};
135138
const controlledContent = ref(content);
136139
return {
137140
apiKey,
138141
content: controlledContent,
139142
cloudChannel: cc,
140143
conf,
141144
log
142-
}
145+
};
143146
},
144147
template: `
145148
<div>
@@ -160,16 +163,16 @@ export const Controlled: Story = (args) => ({
160163

161164
export const Disable: Story = (args) => ({
162165
components: { Editor },
163-
setup() {
166+
setup: () => {
164167
onBeforeMount(() => {
165168
loadTiny(args);
166169
});
167170
const cc = args.channel || lastChannel;
168171
const conf = getConf(args.conf);
169172
const disabled = ref(args.disabled);
170-
const toggleDisabled = (_) => {
173+
const toggleDisabled = () => {
171174
disabled.value = !disabled.value;
172-
}
175+
};
173176

174177
return {
175178
apiKey,
@@ -178,7 +181,7 @@ export const Disable: Story = (args) => ({
178181
conf,
179182
disabled,
180183
toggleDisabled
181-
}
184+
};
182185
},
183186
template: `
184187
<div>
@@ -194,24 +197,24 @@ export const Disable: Story = (args) => ({
194197

195198
export const Readonly: Story = (args) => ({
196199
components: { Editor },
197-
setup() {
200+
setup: () => {
198201
onBeforeMount(() => {
199202
loadTiny(args);
200203
});
201204
const cc = args.channel || lastChannel;
202205
const conf = getConf(args.conf);
203206
const readonly = ref(args.readonly);
204-
const toggleReadonly = (_) => {
207+
const toggleReadonly = () => {
205208
readonly.value = !readonly.value;
206-
}
209+
};
207210
return {
208211
apiKey,
209212
content,
210213
cloudChannel: cc,
211214
conf,
212215
readonly,
213216
toggleReadonly
214-
}
217+
};
215218
},
216219
template: `
217220
<div>

src/test/ts/alien/Loader.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,15 @@ const pRender = (data: Record<string, any> = {}, template: string = `<editor :in
4040
setup: (editor: any) => {
4141
originalSetup(editor);
4242
editor.on('SkinLoaded', () => {
43-
setTimeout(() => {
43+
// This is a workaround to avoid a race condition occurring in tinymce 8 where licenseKeyManager is still validating the license key
44+
// after global tinymce is removed in a clean up. Specifically, it happens when unloading/loading different versions of TinyMCE
45+
if (editor.licenseKeyManager) {
46+
editor.licenseKeyManager.validate({}).then(() => {
47+
resolve({ editor, vm });
48+
});
49+
} else {
4450
resolve({ editor, vm });
45-
}, 0);
51+
}
4652
});
4753
}
4854
}

src/test/ts/browser/InitTest.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ describe('Editor Component Initialization Tests', () => {
1313
Keyboard.keystroke(Keys.space(), {}, SugarElement.fromDom(vmContext.editor.getBody()) as SugarElement<Node>);
1414
};
1515

16-
Arr.each([ '4', '5', '6', '7' as const ], (version) => {
16+
Arr.each([ '4', '5', '6', '7', '8' ], (version) => {
1717
context(`Version: ${version}`, () => {
1818

1919
before(async () => {
@@ -32,6 +32,7 @@ describe('Editor Component Initialization Tests', () => {
3232
const vmContext = await pRender({}, `
3333
<editor
3434
:init="init"
35+
license-key="gpl"
3536
></editor>`);
3637
Assertions.assertEq('Editor should not be inline', false, vmContext.editor.inline);
3738
});
@@ -41,12 +42,13 @@ describe('Editor Component Initialization Tests', () => {
4142
<editor
4243
:init="init"
4344
:inline="true"
45+
license-key="gpl"
4446
></editor>`);
4547
Assertions.assertEq('Editor should be inline', true, vmContext.editor.inline);
4648
});
4749

4850
it('should be inline with inline option in init', async () => {
49-
const vmContext = await pRender({ init: { inline: true }});
51+
const vmContext = await pRender({ init: { inline: true, license_key: 'gpl' }});
5052
Assertions.assertEq('Editor should be inline', true, vmContext.editor.inline);
5153
});
5254

@@ -57,6 +59,7 @@ describe('Editor Component Initialization Tests', () => {
5759
<editor
5860
:init="init"
5961
api-key="${VALID_API_KEY}"
62+
license-key="gpl"
6063
@update:modelValue="content=$event"
6164
output-format="text"
6265
></editor>
@@ -71,6 +74,7 @@ describe('Editor Component Initialization Tests', () => {
7174
}, `
7275
<editor
7376
:init="init"
77+
license-key="gpl"
7478
api-key="${VALID_API_KEY}"
7579
@update:modelValue="content=$event"
7680
output-format="html"

0 commit comments

Comments
 (0)