Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

## 2.3.0 - 2026-05-28

### Changed

- Updated to support jQuery 4. #INT-3359
Expand Down
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ mixedBeehiveFlow(
],
testPrefix: 'Tiny-jQuery',
platforms: [
[ browser: 'chrome', headless: true ],
[ browser: 'chrome', provider: 'lambdatest', os: 'macOS Sonoma', buckets: 1 ],
[ browser: 'firefox', provider: 'aws', buckets: 1 ],
[ browser: 'safari', provider: 'lambdatest', os: 'macOS Sonoma', buckets: 1 ]
],
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tinymce/tinymce-jquery",
"version": "2.3.0-rc",
"version": "2.3.0",
"description": "Official TinyMCE integration for jQuery",
"main": "dist/tinymce-jquery.js",
"files": [
Expand Down
6 changes: 4 additions & 2 deletions src/test/ts/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ export const createEditor = async (action: (targetElm: JQuery<HTMLElement>, edit
const targetElm = $(ce.dom);
const editors = await targetElm.tinymce({
license_key: 'gpl',
base_url: '/project/node_modules/tinymce',
script_url: '/project/node_modules/tinymce/tinymce.js',
});
await Waiter.pTryUntil('Editor should be initialized', () => editors[0]?.initialized);

await Waiter.pTryUntilPredicate('Editor should be initialized', () => editors[0]?.initialized === true);

try {
const maybeAsync = action(targetElm, editors[0]);
if (maybeAsync) {
Expand Down
39 changes: 32 additions & 7 deletions src/test/ts/browser/JqEmptyTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ describe('Check jQuery\'s `.empty()` function', () => {
it('check empty works on a inline editor with content', async () => {
await createHTML(`<section><div id="editor"><p>Hello</p><p>World</p></div></section>`, async (root) => {
const elm = $('div#editor');
const ed = (await elm.tinymce({ inline: true }))[0];
const ed = (await elm.tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
inline: true
}))[0];
try {
Assertions.assertEq('Expected editor to have content', `<p>Hello</p>\n<p>World</p>`, ed.getContent());
elm.empty();
Expand All @@ -56,7 +60,10 @@ describe('Check jQuery\'s `.empty()` function', () => {
// eslint-disable-next-line max-len
await createHTML(`<section><div id="container"><p>Before</p><div><textarea id="editor">&lt;p&gt;Hello&lt;/p&gt;&lt;p&gt;World&lt;/p&gt;</textarea></div><p>After</p></div><p>Extra</p></section>`, async (root) => {
const edElm = $('textarea#editor');
const ed = (await edElm.tinymce({ }))[0];
const ed = (await edElm.tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
}))[0];
try {
Assertions.assertEq('Expected editor to have content', `<p>Hello</p>\n<p>World</p>`, ed.getContent());
const container = $('div#container');
Expand All @@ -73,7 +80,11 @@ describe('Check jQuery\'s `.empty()` function', () => {
// eslint-disable-next-line max-len
await createHTML(`<section><div id="container"><p>Before</p><div><div id="editor"><p>Hello</p><p>World</p></div></div><p>After</p></div><p>Extra</p></section>`, async (root) => {
const edElm = $('div#editor');
const ed = (await edElm.tinymce({ inline: true }))[0];
const ed = (await edElm.tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
inline: true
}))[0];
try {
Assertions.assertEq('Expected editor to have content', `<p>Hello</p>\n<p>World</p>`, ed.getContent());
const container = $('div#container');
Expand Down Expand Up @@ -113,8 +124,15 @@ describe('Check jQuery\'s `.empty()` function', () => {
const normal = $('textarea.editor');
const eds: Editor[] = [];
try {
eds.push(...await inline.tinymce({ inline: true }));
eds.push(...await normal.tinymce({ }));
eds.push(...await inline.tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
inline: true
}));
eds.push(...await normal.tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js'
}));
for (let i = 0; i < eds.length; i++) {
Assertions.assertEq(`Expected editor ${i} to have content`, `<p>Content1</p>\n<p>Content2</p>`, eds[i].getContent());
}
Expand All @@ -139,7 +157,10 @@ describe('Check jQuery\'s `.empty()` function', () => {
it('check normal editors before and after are left alone', async () => {
// eslint-disable-next-line max-len
await createHTML(`<section><textarea class="editor">&lt;p&gt;Editor Content&lt;/p&gt;</textarea><div id="container"><p>Container Content</p></div><textarea class="editor">&lt;p&gt;Editor Content&lt;/p&gt;</textarea></section>`, async () => {
const eds = await $('textarea.editor').tinymce({ });
const eds = await $('textarea.editor').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
});
try {
for (let i = 0; i < eds.length; i++) {
Assertions.assertEq(`Expected editor ${i} to have content`, `<p>Editor Content</p>`, eds[i].getContent());
Expand All @@ -162,7 +183,11 @@ describe('Check jQuery\'s `.empty()` function', () => {
it('check inline editors before and after are left alone', async () => {
// eslint-disable-next-line max-len
await createHTML(`<section><div class="editor"><p>Editor Content</p></div><div id="container"><p>Container Content</p></div><div class="editor"><p>Editor Content</p></div></section>`, async () => {
const eds = await $('div.editor').tinymce({ inline: true });
const eds = await $('div.editor').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
inline: true
});
try {
for (let i = 0; i < eds.length; i++) {
Assertions.assertEq(`Expected editor ${i} to have content`, `<p>Editor Content</p>`, eds[i].getContent());
Expand Down
95 changes: 79 additions & 16 deletions src/test/ts/browser/JqRemoveTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ describe('Check jQuery\'s `.remove()` function', () => {
await createHTML(`<section><div id="target"><p>Before</p><textarea id="editor">&lt;p&gt;Content&lt;/p&gt;</textarea></div></section>`, async (root) => {
const target = $('div#target');
const elm = $('textarea#editor');
const ed = (await elm.tinymce({ }))[0];
const ed = (await elm.tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
}))[0];
try {
Assertions.assertEq('Expected editor to contain content', `<p>Content</p>`, ed.getContent());
target.remove();
Expand All @@ -51,7 +54,11 @@ describe('Check jQuery\'s `.remove()` function', () => {
await createHTML(`<section><div id="target"><p>Before</p><div id="editor"><p>Content</p></div></div></section>`, async (root) => {
const target = $('div#target');
const elm = $('div#editor');
const ed = (await elm.tinymce({ inline: true }))[0];
const ed = (await elm.tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
inline: true
}))[0];
try {
Assertions.assertStructure('Expected root to initially contain everything',
ApproxStructure.fromHtml(`<section><div id="target"><p>Before</p><div id="editor"><p>Content</p></div></div></section>`),
Expand All @@ -74,9 +81,18 @@ describe('Check jQuery\'s `.remove()` function', () => {
const target = $('div.target');
const eds: Editor[] = [];
try {
eds.push((await $('textarea#editor1').tinymce({ }))[0]);
eds.push((await $('textarea#editor2').tinymce({ }))[0]);
eds.push((await $('textarea#editor3').tinymce({ }))[0]);
eds.push((await $('textarea#editor1').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js'
}))[0]);
eds.push((await $('textarea#editor2').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js'
}))[0]);
eds.push((await $('textarea#editor3').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js'
}))[0]);
Assertions.assertEq('Expected editor 1 to contain content', `<p>Content</p>`, eds[0].getContent());
Assertions.assertEq('Expected editor 2 to contain content', `<p>Content</p>`, eds[1].getContent());
Assertions.assertEq('Expected editor 3 to contain content', `<p>Content</p>`, eds[2].getContent());
Expand All @@ -102,9 +118,21 @@ describe('Check jQuery\'s `.remove()` function', () => {
const target = $('div.target');
const eds: Editor[] = [];
try {
eds.push((await $('div#editor1').tinymce({ inline: true }))[0]);
eds.push((await $('div#editor2').tinymce({ inline: true }))[0]);
eds.push((await $('div#editor3').tinymce({ inline: true }))[0]);
eds.push((await $('div#editor1').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
inline: true
}))[0]);
eds.push((await $('div#editor2').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
inline: true
}))[0]);
eds.push((await $('div#editor3').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
inline: true
}))[0]);
Assertions.assertStructure('Expected root to initially contain everything',
ApproxStructure.fromHtml('<section>' +
'<div class="target"><div id="editor1"><p>Content</p></div></div>' +
Expand Down Expand Up @@ -135,7 +163,10 @@ describe('Check jQuery\'s `.remove()` function', () => {
it('check works without selector on normal editors', async () => {
await createHTML(`<section><textarea id="editor">&lt;p&gt;Content&lt;/p&gt;</textarea></section>`, async (root) => {
const elm = $('textarea#editor');
const ed = (await elm.tinymce({ }))[0];
const ed = (await elm.tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js'
}))[0];
try {
Assertions.assertEq('Expected editor to contain content', `<p>Content</p>`, ed.getContent());
elm.remove();
Expand All @@ -149,7 +180,11 @@ describe('Check jQuery\'s `.remove()` function', () => {
it('check works without selector on inline editors', async () => {
await createHTML(`<section><div id="editor"><p>Content</p></div></section>`, async (root) => {
const elm = $('div#editor');
const ed = (await elm.tinymce({ }))[0];
const ed = (await elm.tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
inline: true
}))[0];
try {
Assertions.assertEq('Expected editor to contain content', `<p>Content</p>`, ed.getContent());
elm.remove();
Expand All @@ -169,9 +204,18 @@ describe('Check jQuery\'s `.remove()` function', () => {
const target = $('section.container textarea');
const eds: Editor[] = [];
try {
eds.push((await $('textarea#editor1').tinymce({ }))[0]);
eds.push((await $('textarea#editor2').tinymce({ }))[0]);
eds.push((await $('textarea#editor3').tinymce({ }))[0]);
eds.push((await $('textarea#editor1').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js'
}))[0]);
eds.push((await $('textarea#editor2').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js'
}))[0]);
eds.push((await $('textarea#editor3').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js'
}))[0]);
Assertions.assertEq('Expected editor 1 to contain content', `<p>Content</p>`, eds[0].getContent());
Assertions.assertEq('Expected editor 2 to contain content', `<p>Content</p>`, eds[1].getContent());
Assertions.assertEq('Expected editor 3 to contain content', `<p>Content</p>`, eds[2].getContent());
Expand All @@ -197,9 +241,28 @@ describe('Check jQuery\'s `.remove()` function', () => {
const target = $('section.container div');
const eds: Editor[] = [];
try {
eds.push((await $('div#editor1').tinymce({ inline: true }))[0]);
eds.push((await $('div#editor2').tinymce({ inline: true }))[0]);
eds.push((await $('div#editor3').tinymce({ inline: true }))[0]);
eds.push((await $('div#editor1').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
inline: true }))[0]);
eds.push((await $('div#editor2').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
inline: true }))[0]);
eds.push((await $('div#editor3').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
inline: true }))[0]);
eds.push((await $('div#editor2').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
inline: true
}))[0]);
eds.push((await $('div#editor3').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
inline: true
}))[0]);
Assertions.assertStructure('Expected root to initially contain everything',
ApproxStructure.fromHtml('<section class="container">' +
'<div id="editor1"><p>Content</p></div>' +
Expand Down
35 changes: 28 additions & 7 deletions src/test/ts/browser/JqTextTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ describe('Check jQuery\'s `.text()` function', () => {
it('gets the text of TinyMCE and two divs', async () => {
await createHTML(`<section><div><p>Before</p></div><div id="editor"><p>Middle</p></div><div><p>After</p></div></section>`, async (root) => {
const divs = $(root).find('div');
const ed = (await $('#editor').tinymce({ }))[0];
const ed = (await $('#editor').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
}))[0];
try {
Assertions.assertEq('Expected matching text', 'BeforeMiddleAfter', divs.text());
} finally {
Expand All @@ -54,7 +57,10 @@ describe('Check jQuery\'s `.text()` function', () => {
it('sets the content of multiple things simultaneously', async () => {
await createHTML(`<section><div>Before</div><div id="editor"></div></section>`, async (root) => {
const divs = root.querySelectorAll('div');
const ed = (await $('#editor').tinymce({ }))[0];
const ed = (await $('#editor').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
}))[0];
try {
$(divs).text('Hello');
Assertions.assertEq('Expected matching html', 'Hello', divs[0].innerHTML);
Expand All @@ -80,7 +86,10 @@ describe('Check jQuery\'s `.text()` function', () => {
it('sets the content of multiple things simultaneously', async () => {
await createHTML(`<section><div>Before</div><div id="editor"></div></section>`, async (root) => {
const divs = root.querySelectorAll('div');
const ed = (await $('#editor').tinymce({ }))[0];
const ed = (await $('#editor').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
}))[0];
try {
$(divs).text(9007199254740991);
Assertions.assertEq('Expected matching html', '9007199254740991', divs[0].innerHTML);
Expand All @@ -106,7 +115,10 @@ describe('Check jQuery\'s `.text()` function', () => {
it('sets the content of multiple things simultaneously', async () => {
await createHTML(`<section><div>Before</div><div id="editor"></div></section>`, async (root) => {
const divs = root.querySelectorAll('div');
const ed = (await $('#editor').tinymce({ }))[0];
const ed = (await $('#editor').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js'
}))[0];
try {
$(divs).text(true);
Assertions.assertEq('Expected matching html', 'true', divs[0].innerHTML);
Expand Down Expand Up @@ -144,7 +156,10 @@ describe('Check jQuery\'s `.text()` function', () => {
it('sets the content of multiple things simultaneously', async () => {
await createHTML(`<section><div>Content</div><div id="editor">Content</div></section>`, async (root) => {
const divs = root.querySelectorAll('div');
const ed = (await $('#editor').tinymce({ }))[0];
const ed = (await $('#editor').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js'
}))[0];
try {
$(divs).text(function (index, prevValue) {
Assertions.assertEq('Expected matching this', divs[index], this);
Expand Down Expand Up @@ -186,7 +201,10 @@ describe('Check jQuery\'s `.text()` function', () => {
it('sets the content of multiple things simultaneously', async () => {
await createHTML(`<section><div>Content</div><div id="editor">Content</div></section>`, async (root) => {
const divs = root.querySelectorAll('div');
const ed = (await $('#editor').tinymce({ }))[0];
const ed = (await $('#editor').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js'
}))[0];
try {
$(divs).text(function (index, prevValue) {
Assertions.assertEq('Expected matching this', divs[index], this);
Expand Down Expand Up @@ -229,7 +247,10 @@ describe('Check jQuery\'s `.text()` function', () => {
it('sets the content of multiple things simultaneously', async () => {
await createHTML(`<section><div>Content</div><div id="editor">Content</div></section>`, async (root) => {
const divs = root.querySelectorAll('div');
const ed = (await $('#editor').tinymce({ }))[0];
const ed = (await $('#editor').tinymce({
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js'
}))[0];
try {
$(divs).text(function (index, prevValue) {
Assertions.assertEq('Expected matching this', divs[index], this);
Expand Down
1 change: 0 additions & 1 deletion src/test/ts/browser/LoadTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ describe('LoadTest', () => {
const ce = SugarElement.fromTag('div');
Class.add(ce, 'test-editor');
Insert.append(SugarBody.body(), ce);

await new Promise<void>((resolve) => {
$('div.test-editor').tinymce({
license_key: 'gpl',
Expand Down
5 changes: 4 additions & 1 deletion src/test/ts/browser/OriginalTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ describe('OriginalTest', () => {
});

it('applyPatch is only called once', () => {
const options = {};
const options = {
license_key: 'gpl',
script_url: '/project/node_modules/tinymce/tinymce.js',
};

$('#elm1').tinymce(options).catch((err) => {
/* eslint-disable-next-line no-console */
Expand Down
Loading