From 6d49d192ee627e7db8c1009222ccc34a9c873da2 Mon Sep 17 00:00:00 2001 From: Spocke Date: Thu, 29 Feb 2024 14:43:48 +0100 Subject: [PATCH 01/15] TINY-10712: Updated build.properties --- build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.properties b/build.properties index 4aa93a4451d..eb55c629573 100644 --- a/build.properties +++ b/build.properties @@ -1 +1 @@ -primaryBranch=develop +primaryBranch=main From 73250c0d6f0d50c06b599471bdbe41186b28525c Mon Sep 17 00:00:00 2001 From: Spocke Date: Thu, 29 Feb 2024 14:55:29 +0100 Subject: [PATCH 02/15] TINY-10712: Prepare for TinyMCE 7.1.x development --- modules/tinymce/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/tinymce/package.json b/modules/tinymce/package.json index 7ddec54e665..ebff610ec96 100644 --- a/modules/tinymce/package.json +++ b/modules/tinymce/package.json @@ -1,6 +1,6 @@ { "name": "tinymce", - "version": "7.0.0", + "version": "7.1.0", "private": true, "repository": { "type": "git", From b4e4a24c3278fafa176dee5911a674c849283c56 Mon Sep 17 00:00:00 2001 From: Daniel Oakman <141111365+danoaky-tiny@users.noreply.github.com> Date: Fri, 1 Mar 2024 12:57:41 +1100 Subject: [PATCH 03/15] TINY-10436: Remove `force_hex_color` option and enforce colors to always be HEX (#9414) * TINY-10436: Remove `force_hex_color` option and leave it like it was set to "always" * TINY-10436: Remove `ForceHexColorText.ts` * TINY-10436: Fix `StylesTest.ts` to reflect changes to forced HEX colors * TINY-10436: Enforce lower case on converted HEX colours * TINY-10436: fix tests that expect RGB instead of HEX * TINY-10436: Added changelog * TINY-10436: fixed a word * TINY-10436: Fixed typo * TINY-10436: rgba colors are handled the same way as they were in v5 * TINY-10436: Corrected a comment * TINY-10436: More test assertions and renamed test label * TINY-10436: Fix test after merge from develop * TINY-10436: Addressed Safari v15 expected color differences --- .../tinymce-TINY-10436-2024-02-27.yaml | 7 + .../src/core/main/ts/api/OptionTypes.ts | 4 - .../tinymce/src/core/main/ts/api/Options.ts | 13 +- .../src/core/main/ts/api/dom/DOMUtils.ts | 4 +- .../src/core/main/ts/api/html/Styles.ts | 15 +- .../src/core/main/ts/init/InitContentBody.ts | 1 - .../test/ts/browser/FormatterApplyTest.ts | 78 +++++------ .../test/ts/browser/FormatterRemoveTest.ts | 4 +- .../test/ts/browser/FormattingCommandsTest.ts | 6 +- .../ts/browser/fmt/FormatNoneditableTest.ts | 6 +- .../core/test/ts/browser/html/StylesTest.ts | 60 ++++---- .../test/ts/browser/paste/PasteStylesTest.ts | 4 +- .../core/test/ts/browser/paste/PasteTest.ts | 10 +- .../ui/TableCellBackgroundColorTest.ts | 4 +- .../ts/browser/ui/TableCellBorderColorTest.ts | 5 +- .../test/ts/browser/ui/TableDialogTest.ts | 53 ++++--- .../test/ts/browser/ui/TableRowDialogTest.ts | 4 +- .../ts/browser/editor/ForceHexColorTest.ts | 131 ------------------ 18 files changed, 136 insertions(+), 273 deletions(-) create mode 100644 .changes/unreleased/tinymce-TINY-10436-2024-02-27.yaml delete mode 100644 modules/tinymce/src/themes/silver/test/ts/browser/editor/ForceHexColorTest.ts diff --git a/.changes/unreleased/tinymce-TINY-10436-2024-02-27.yaml b/.changes/unreleased/tinymce-TINY-10436-2024-02-27.yaml new file mode 100644 index 00000000000..5aa0baf2041 --- /dev/null +++ b/.changes/unreleased/tinymce-TINY-10436-2024-02-27.yaml @@ -0,0 +1,7 @@ +project: tinymce +kind: Removed +body: Removed `force_hex_color` option, with the default now being all colors are forced + to HEX format and as lower case +time: 2024-02-27T16:23:33.051971748+11:00 +custom: + Issue: TINY-10436 diff --git a/modules/tinymce/src/core/main/ts/api/OptionTypes.ts b/modules/tinymce/src/core/main/ts/api/OptionTypes.ts index 14784996a2b..dcdf1ca8120 100644 --- a/modules/tinymce/src/core/main/ts/api/OptionTypes.ts +++ b/modules/tinymce/src/core/main/ts/api/OptionTypes.ts @@ -44,8 +44,6 @@ export interface ToolbarGroup { export type ToolbarMode = 'floating' | 'sliding' | 'scrolling' | 'wrap'; export type ToolbarLocation = 'top' | 'bottom' | 'auto'; -export type ForceHexColor = 'always' | 'rgb_only' | 'off'; - interface BaseEditorOptions { a11y_advanced_options?: boolean; add_form_submit_trigger?: boolean; @@ -121,7 +119,6 @@ interface BaseEditorOptions { font_size_style_values?: string; font_size_formats?: string; font_size_input_default_unit?: string; - force_hex_color?: ForceHexColor; forced_root_block?: string; forced_root_block_attrs?: Record; formats?: Formats; @@ -310,7 +307,6 @@ export interface EditorOptions extends NormalizedEditorOptions { font_size_style_values: string; forced_root_block: string; forced_root_block_attrs: Record; - force_hex_color: ForceHexColor; format_noneditable_selector: string; height: number | string; highlight_on_focus: boolean; diff --git a/modules/tinymce/src/core/main/ts/api/Options.ts b/modules/tinymce/src/core/main/ts/api/Options.ts index 47b73423c36..37dbd137ec6 100644 --- a/modules/tinymce/src/core/main/ts/api/Options.ts +++ b/modules/tinymce/src/core/main/ts/api/Options.ts @@ -5,7 +5,7 @@ import * as Pattern from '../textpatterns/core/Pattern'; import * as PatternTypes from '../textpatterns/core/PatternTypes'; import DOMUtils from './dom/DOMUtils'; import Editor from './Editor'; -import { EditorOptions, ForceHexColor } from './OptionTypes'; +import { EditorOptions } from './OptionTypes'; import I18n from './util/I18n'; import Tools from './util/Tools'; @@ -833,15 +833,6 @@ const register = (editor: Editor): void => { default: '' }); - registerOption('force_hex_color', { - processor: (value) => { - const options: ForceHexColor[] = [ 'always', 'rgb_only', 'off' ]; - const valid = Arr.contains(options, value); - return valid ? { value, valid } : { valid: false, message: `Must be one of: ${options.join(', ')}.` }; - }, - default: 'off', - }); - registerOption('sandbox_iframes', { processor: 'boolean', default: true @@ -984,7 +975,6 @@ const getAllowedImageFileTypes = (editor: Editor): string[] => Tools.explode(edi const hasTableTabNavigation = option('table_tab_navigation'); const getDetailsInitialState = option('details_initial_state'); const getDetailsSerializedState = option('details_serialized_state'); -const shouldForceHexColor = option('force_hex_color'); const shouldSandboxIframes = option('sandbox_iframes'); const getSandboxIframesExclusions = (editor: Editor): string[] => editor.options.get('sandbox_iframes_exclusions'); const shouldConvertUnsafeEmbeds = option('convert_unsafe_embeds'); @@ -1095,7 +1085,6 @@ export { getDetailsInitialState, getDetailsSerializedState, shouldUseDocumentWrite, - shouldForceHexColor, shouldSandboxIframes, getLicenseKey, getSandboxIframesExclusions, diff --git a/modules/tinymce/src/core/main/ts/api/dom/DOMUtils.ts b/modules/tinymce/src/core/main/ts/api/dom/DOMUtils.ts index a613d44e3f6..9c4b60b82be 100644 --- a/modules/tinymce/src/core/main/ts/api/dom/DOMUtils.ts +++ b/modules/tinymce/src/core/main/ts/api/dom/DOMUtils.ts @@ -11,7 +11,7 @@ import { GeomRect } from '../geom/Rect'; import Entities from '../html/Entities'; import Schema from '../html/Schema'; import Styles, { StyleMap } from '../html/Styles'; -import { ForceHexColor, URLConverter } from '../OptionTypes'; +import { URLConverter } from '../OptionTypes'; import { MappedEvent } from '../util/EventDispatcher'; import Tools from '../util/Tools'; import EventUtils, { EventUtilsCallback } from './EventUtils'; @@ -64,7 +64,6 @@ export interface DOMUtilsSettings { onSetAttrib: (event: SetAttribEvent) => void; contentCssCors: boolean; referrerPolicy: ReferrerPolicy; - force_hex_color: ForceHexColor; } export type Target = Node | Window; @@ -339,7 +338,6 @@ const DOMUtils = (doc: Document, settings: Partial = {}): DOMU const styles = Styles({ url_converter: settings.url_converter, url_converter_scope: settings.url_converter_scope, - force_hex_color: settings.force_hex_color, }, settings.schema); const events = settings.ownEvents ? new EventUtils() : EventUtils.Event; diff --git a/modules/tinymce/src/core/main/ts/api/html/Styles.ts b/modules/tinymce/src/core/main/ts/api/html/Styles.ts index 228ce1df7f9..06a922f5df4 100644 --- a/modules/tinymce/src/core/main/ts/api/html/Styles.ts +++ b/modules/tinymce/src/core/main/ts/api/html/Styles.ts @@ -17,9 +17,9 @@ */ import { RgbaColour, Transformations } from '@ephox/acid'; -import { Obj, Type, Unicode } from '@ephox/katamari'; +import { Obj, Unicode } from '@ephox/katamari'; -import { ForceHexColor, URLConverter } from '../OptionTypes'; +import { URLConverter } from '../OptionTypes'; import Schema, { SchemaMap } from './Schema'; export type StyleMap = Record; @@ -29,7 +29,6 @@ export interface StylesSettings { allow_svg_data_urls?: boolean; url_converter?: URLConverter; url_converter_scope?: any; - force_hex_color?: ForceHexColor; } interface Styles { @@ -43,6 +42,7 @@ const Styles = (settings: StylesSettings = {}, schema?: Schema): Styles => { const urlOrStrRegExp = /(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi; const styleRegExp = /\s*([^:]+):\s*([^;]+);?/g; const trimRightRegExp = /\s+$/; + const rgbaRegExp = /rgba *\(/i; const encodingLookup: Record = {}; let validStyles: Record | undefined; let invalidStyles: Record | undefined; @@ -265,13 +265,10 @@ const Styles = (settings: StylesSettings = {}, schema?: Schema): Styles => { value = value.toLowerCase(); } - // Convert RGB/RGBA colors to HEX - if (Type.isString(settings.force_hex_color) && settings.force_hex_color !== 'off') { + // Convert RGB colors to HEX + if (!rgbaRegExp.test(value)) { RgbaColour.fromString(value).each((rgba) => { - // Always convert or only convert if there will be no loss of information from the alpha channel - if (settings.force_hex_color === 'always' || rgba.alpha === 1) { - value = Transformations.rgbaToHexString(RgbaColour.toString(rgba)); - } + value = Transformations.rgbaToHexString(RgbaColour.toString(rgba)).toLowerCase(); }); } diff --git a/modules/tinymce/src/core/main/ts/init/InitContentBody.ts b/modules/tinymce/src/core/main/ts/init/InitContentBody.ts index a491b5dbed9..cbe1113a2be 100644 --- a/modules/tinymce/src/core/main/ts/init/InitContentBody.ts +++ b/modules/tinymce/src/core/main/ts/init/InitContentBody.ts @@ -448,7 +448,6 @@ const contentBodyLoaded = (editor: Editor): void => { onSetAttrib: (e) => { editor.dispatch('SetAttrib', e); }, - force_hex_color: Options.shouldForceHexColor(editor), }); editor.parser = createParser(editor); diff --git a/modules/tinymce/src/core/test/ts/browser/FormatterApplyTest.ts b/modules/tinymce/src/core/test/ts/browser/FormatterApplyTest.ts index 7d91fd2b42a..f7a97ed44f9 100644 --- a/modules/tinymce/src/core/test/ts/browser/FormatterApplyTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/FormatterApplyTest.ts @@ -249,7 +249,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { rng.setEnd(editor.dom.select('p')[0].firstChild as Text, 4); editor.selection.setRng(rng); editor.formatter.apply('format'); - assert.equal(getContent(editor), '

1234

', 'Inline element with styles'); + assert.equal(getContent(editor), '

1234

', 'Inline element with styles'); }); it('Inline element with attributes and styles', () => { @@ -273,7 +273,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.formatter.apply('format'); assert.equal( getContent(editor), - '

1234

', + '

1234

', 'Inline element with attributes and styles' ); }); @@ -483,7 +483,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.formatter.apply('format'); assert.equal( getContent(editor), - '

a1234b

', + '

a1234b

', 'Inline element merged with child 2' ); }); @@ -523,7 +523,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { rng.setEnd(editor.getBody(), 1); editor.selection.setRng(rng); editor.formatter.apply('format'); - assert.equal(getContent(editor), '

1234

'); + assert.equal(getContent(editor), '

1234

'); }); it('Inline element merged with child 5', () => { @@ -540,7 +540,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { rng.setEnd(editor.getBody(), 1); editor.selection.setRng(rng); editor.formatter.apply('format'); - assert.equal(getContent(editor), '

1234

', 'Inline element merged with child 5'); + assert.equal(getContent(editor), '

1234

', 'Inline element merged with child 5'); }); it('Inline element with attributes merged with child 1', () => { @@ -678,7 +678,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.formatter.apply('format'); assert.equal( getContent(editor), - '

1234

', + '

1234

', 'Inline element not merged in exact mode' ); }); @@ -698,7 +698,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { rng.setEnd(editor.getBody(), 1); editor.selection.setRng(rng); editor.formatter.apply('format'); - assert.equal(getContent(editor), '

1234

'); + assert.equal(getContent(editor), '

1234

'); }); it('Deep left branch', () => { @@ -775,7 +775,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { color: '#ff0000', title: 'title' }); - assert.equal(getContent(editor), '

1234

', 'Inline element on selected text'); + assert.equal(getContent(editor), '

1234

', 'Inline element on selected text'); }); it('Remove redundant children', () => { @@ -821,7 +821,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { color: '#ff', title: 'title' }); - assert.equal(getContent(editor), '

1234

', 'Inline element on selected text with function values'); + assert.equal(getContent(editor), '

1234

', 'Inline element on selected text with function values'); }); it('Block element on selected text', () => { @@ -1018,7 +1018,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.formatter.apply('format'); assert.equal( getContent(editor), - '

1234

', + '

1234

', 'Apply format on single element that matches a selector' ); }); @@ -1043,7 +1043,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.formatter.apply('format'); assert.equal( getContent(editor), - '

1234

test

1234

', + '

1234

test

1234

', 'Apply format on single element parent that matches a selector' ); }); @@ -1068,7 +1068,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.formatter.apply('format'); assert.equal( getContent(editor), - '

1234

test

1234

', + '

1234

test

1234

', 'Apply format on multiple elements that matches a selector' ); }); @@ -1093,7 +1093,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.formatter.apply('format'); assert.equal( getContent(editor), - '

1234

', + '

1234

', 'Apply format on top of existing selector element' ); }); @@ -1119,7 +1119,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.formatter.apply('format'); assert.equal( getContent(editor), - '
text
', + '
text
', 'Apply format on single element that matches a selector' ); }); @@ -1145,7 +1145,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.formatter.apply('format'); assert.equal( getContent(editor), - '
text
', + '
text
', 'Apply format on single element that matches a selector' ); }); @@ -1177,7 +1177,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.formatter.register('format', { inline: 'span', styles: { - color: '#FF0000' + color: '#ff0000' }, links: true }); @@ -1185,7 +1185,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { assert.equal( editor.getContent(), - '

123abc456

', + '

123abc456

', `Link should have it's own color.` ); }); @@ -1201,7 +1201,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.formatter.register('format', { inline: 'span', styles: { - color: '#FF0000' + color: '#ff0000' }, links: true }); @@ -1209,7 +1209,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { assert.equal( editor.getContent(), - '

123abc456

', + '

123abc456

', `Link should have it's own color.` ); }); @@ -1344,7 +1344,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.formatter.apply('format'); assert.equal( editor.getContent(), - `

test

`, + `

test

`, 'Coloring an underlined text should result in a colored underline' ); }); @@ -1358,12 +1358,12 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { textDecoration: 'underline' } }); - editor.setContent(`

test

`); + editor.setContent(`

test

`); editor.execCommand('SelectAll'); editor.formatter.apply('format'); assert.equal( editor.getContent(), - '

test

`, 'Underlining colored text should result in a colored underline' ); @@ -1380,14 +1380,14 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { }); editor.setContent( `

This is some ` + - 'example text

' + 'example text

' ); editor.execCommand('SelectAll'); editor.formatter.apply('format'); assert.equal( editor.getContent(), `

` + - 'This is some example' + + 'This is some example' + ' text

', 'Underlining colored and underlined text should result in a colored underline' ); }); @@ -1410,7 +1410,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.selection.setRng(rng); editor.formatter.apply('format'); assert.equal(getContent(editor), '

yellowredyellow

', + ' text-decoration: underline;">yellowredyellow

', 'Coloring an colored underdlined text should result in newly colored underline' ); }); @@ -1426,10 +1426,10 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { }); editor.setContent( `

This is some example text

This is some example` + + `#ff0000;">example text

This is some example` + ` text

This is` + - ` some example text

` + ` some example text

` ); const rng = editor.dom.createRng(); rng.setStart(editor.dom.select('strong')[0].firstChild as Text, 0); @@ -1439,12 +1439,12 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { assert.equal( editor.getContent(), `

This is some exampleThis is some example text

This is some This is some example text

This is some example text

`, + ` #ff0000; text-decoration: underline;">example text

`, `Colored elements should be underlined when selection is across multiple paragraphs` ); }); @@ -1492,7 +1492,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.formatter.remove('format'); assert.equal( editor.getContent(), - '

This is ' + + '

This is ' + 'some text.

', 'Children nodes that are underlined should be removed if their parent nodes are underlined' ); @@ -1961,7 +1961,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.getBody().innerHTML = '

a bc

'; LegacyUnit.setSelection(editor, 'span span', 0, 'span span', 1); editor.formatter.apply('fontname', { value: 'verdana' }); - assert.equal(getContent(editor), '

a bc

'); + assert.equal(getContent(editor), '

a bc

'); }); it('FontName should not toggle', () => { @@ -1994,7 +1994,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.formatter.apply('hilitecolor', { value: '#ff0000' }); assert.equal( getContent(editor), - '

a b c

' + '

a b c

' ); editor.formatter.remove('hilitecolor', { value: '#ff0000' }); @@ -2070,7 +2070,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.getBody().innerHTML = '

abc

'; LegacyUnit.setSelection(editor, 'span', 0, 'span', 3); editor.formatter.apply('hilitecolor', { value: '#ff0000' }); - assert.equal(getContent(editor), '

abc

'); + assert.equal(getContent(editor), '

abc

'); }); it('Background color over range of font sizes', () => { @@ -2080,7 +2080,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.formatter.apply('hilitecolor', { value: '#ff0000' }); assert.equal( getContent(editor), - '

abc

' + '

abc

' ); }); @@ -2095,7 +2095,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { assert.equal( getContent(editor), '

a b c

' + 'style="font-size: 36pt; background-color: #ff0000;">b c

' ); }); @@ -2104,7 +2104,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.getBody().innerHTML = '

text

'; LegacyUnit.setSelection(editor, 'span', 0, 'span', 4); editor.formatter.apply('forecolor', { value: '#ff0000' }); - assert.equal(getContent(editor), '

text

'); + assert.equal(getContent(editor), '

text

'); }); it('GH-3519: Font family selection does not work after changing font size', () => { @@ -2263,7 +2263,7 @@ describe('browser.tinymce.core.FormatterApplyTest', () => { editor.formatter.apply('hilitecolor', { value: '#00ff00' }); assert.equal(getContent(editor), '

' + - 'abcdef' + + 'abcdef' + '

'); }); diff --git a/modules/tinymce/src/core/test/ts/browser/FormatterRemoveTest.ts b/modules/tinymce/src/core/test/ts/browser/FormatterRemoveTest.ts index cde98376d11..a2e384a5c90 100644 --- a/modules/tinymce/src/core/test/ts/browser/FormatterRemoveTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/FormatterRemoveTest.ts @@ -70,7 +70,7 @@ describe('browser.tinymce.core.FormatterRemoveTest', () => { editor.selection.setRng(rng); editor.formatter.remove('format'); assert.equal(getContent(editor), '

' + - '123' + + '123' + '4' + '

', 'Inline element style where element is format root'); }); @@ -109,7 +109,7 @@ describe('browser.tinymce.core.FormatterRemoveTest', () => { editor.selection.setRng(rng); editor.formatter.remove('format'); assert.equal(getContent(editor), '

12' + - '34

', 'Partially selected inline element text with complex children'); + '
34

', 'Partially selected inline element text with complex children'); }); it('Inline elements with exact flag', () => { diff --git a/modules/tinymce/src/core/test/ts/browser/FormattingCommandsTest.ts b/modules/tinymce/src/core/test/ts/browser/FormattingCommandsTest.ts index b6bf0bcf1c5..d299299f131 100644 --- a/modules/tinymce/src/core/test/ts/browser/FormattingCommandsTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/FormattingCommandsTest.ts @@ -75,17 +75,17 @@ describe('browser.tinymce.core.FormattingCommandsTest', () => { editor.setContent('test 123'); editor.execCommand('SelectAll'); editor.execCommand('ForeColor', false, '#FF0000'); - TinyAssertions.assertContent(editor, '

test 123

'); + TinyAssertions.assertContent(editor, '

test 123

'); editor.setContent('test 123'); editor.execCommand('SelectAll'); editor.execCommand('HiliteColor', false, '#FF0000'); - TinyAssertions.assertContent(editor, '

test 123

'); + TinyAssertions.assertContent(editor, '

test 123

'); editor.setContent('test 123'); editor.execCommand('SelectAll'); editor.execCommand('BackColor', false, '#FF0000'); - TinyAssertions.assertContent(editor, '

test 123

'); + TinyAssertions.assertContent(editor, '

test 123

'); editor.setContent('

test 123

'); TinyAssertions.assertContent(editor, '

test 123

'); diff --git a/modules/tinymce/src/core/test/ts/browser/fmt/FormatNoneditableTest.ts b/modules/tinymce/src/core/test/ts/browser/fmt/FormatNoneditableTest.ts index 644313e500d..546c8a472d3 100644 --- a/modules/tinymce/src/core/test/ts/browser/fmt/FormatNoneditableTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/fmt/FormatNoneditableTest.ts @@ -45,6 +45,8 @@ describe('browser.tinymce.core.fmt.FormatNoneditableTest', () => { await TinyUiActions.pWaitForUi(editor, `button[aria-label="${selector}"][aria-pressed="${active}"]`); }; + // const hexToLower = (str: string) => str.replace(/#([A-F]|\d){6}/g, (s) => s.toLowerCase()); + const pTestFormat = (format: (editor: Editor) => void) => async (editor: Editor, actions: Action[]) => { for (const action of actions) { const { select, expectedHtml, pAssertBefore, pAssertAfter, selectionAfter } = action; @@ -55,6 +57,8 @@ describe('browser.tinymce.core.fmt.FormatNoneditableTest', () => { format(editor); + // editor.setContent(hexToLower(editor.getContent())); + TinyAssertions.assertContent(editor, expectedHtml); if (Type.isNonNullable(pAssertAfter)) { pAssertAfter(editor); @@ -90,7 +94,7 @@ describe('browser.tinymce.core.fmt.FormatNoneditableTest', () => { const forecolorFormat: FormatInfo = { label: 'Text color', tag: 'span', - html: 'span style="color: rgb(255, 0, 0);"', + html: 'span style="color: #ff0000;"', toggle: toggleCustomFormat('forecolor', { value: '#ff0000' }), useToolbar: false }; diff --git a/modules/tinymce/src/core/test/ts/browser/html/StylesTest.ts b/modules/tinymce/src/core/test/ts/browser/html/StylesTest.ts index 6bd2b01aa39..2ad9bd976dd 100644 --- a/modules/tinymce/src/core/test/ts/browser/html/StylesTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/html/StylesTest.ts @@ -33,18 +33,25 @@ describe('browser.tinymce.core.html.StylesTest', () => { it('Colors force hex and lowercase', () => { const styles = Styles(); - assertStyles(styles, 'color: rgb(1,2,3)', 'color: rgb(1,2,3);'); - assertStyles(styles, 'color: RGB(1,2,3)', 'color: rgb(1,2,3);'); + assertStyles(styles, 'color: rgb(1,2,3)', 'color: #010203;'); + assertStyles(styles, 'color: RGB(1,2,3)', 'color: #010203;'); assertStyles(styles, 'color: #FF0000', 'color: #ff0000;'); - assertStyles(styles, ' color: RGB ( 1 , 2 , 3 ) ', 'color: rgb ( 1 , 2 , 3 );'); + assertStyles(styles, ' color: RGB ( 1 , 2 , 3 ) ', 'color: #010203;'); assertStyles(styles, ' FONT-SIZE : 10px ; COLOR : RGB ( 1 , 2 , 3 ) ', - 'font-size: 10px; color: rgb ( 1 , 2 , 3 );' + 'font-size: 10px; color: #010203;' ); assertStyles(styles, ' FONT-SIZE : 10px ; COLOR : RED ', 'font-size: 10px; color: red;' ); + assertStyles( + styles, + 'border: 1px solid rgb(255, 0, 0);', + 'border: 1px solid rgb(255, 0, 0);' + // TODO: color in border style should be in HEX format once https://ephocks.atlassian.net/browse/TINY-8917 is fixed. + // 'border: 1px solid #ff0000;' // Should expect this + ); }); it('Urls convert urls and force format', () => { @@ -152,13 +159,13 @@ describe('browser.tinymce.core.html.StylesTest', () => { assertStyles( styles, 'border-width: 1px; border-color: rgb(1, 2, 3)', - 'border-width: 1px; border-color: rgb(1, 2, 3);' + 'border-width: 1px; border-color: #010203;' ); assertStyles( styles, 'border-width: 1px; border-color: rgb(1, 2, 3); border-style: dashed', - 'border: 1px dashed rgb(1, 2, 3);' + 'border: 1px dashed #010203;' ); }); @@ -235,35 +242,26 @@ describe('browser.tinymce.core.html.StylesTest', () => { assertStyles(styles, 'background:url(vbscript:alert(1)', `background: url('vbscript:alert(1');`); }); - it('TINY-9819: force_hex_color set to "off" (the default)', () => { + it('TINY-10436: colors are handled the way they did in v5', () => { const styles = Styles(); - for (const color of [ - '#aabbcc', - 'rgb(1, 2, 3)', - 'rgba(1, 2, 3, 0.5)', - `rgba(200, 150, 100, 0.95)` - ]) { - // All colors are unchanged: - assertStyles(styles, `color: ${color};`, `color: ${color};`); - } - }); - - it('TINY-9819: force_hex_color set to "always"', () => { - const styles = Styles({ force_hex_color: 'always' }); - assertStyles(styles, 'color: #aabbcc;', 'color: #aabbcc;'); - assertStyles(styles, 'color: rgb(1, 2, 3);', 'color: #010203;'); - assertStyles(styles, 'color: rgba(1, 2, 3, 1);', 'color: #010203;'); - assertStyles(styles, 'color: rgba(1, 2, 3, 0);', 'color: #010203;'); - assertStyles(styles, 'color: rgba(1, 2, 3, 0.5);', 'color: #010203;'); - }); - - it('TINY-9819: force_hex_color set to "rgb_only"', () => { - const styles = Styles({ force_hex_color: 'rgb_only' }); assertStyles(styles, 'color: #aabbcc;', 'color: #aabbcc;'); + assertStyles(styles, 'color: #aabbcc88', 'color: #aabbcc88;'); + assertStyles(styles, 'color: #aabbccff', 'color: #aabbccff;'); assertStyles(styles, 'color: rgb(1, 2, 3);', 'color: #010203;'); - assertStyles(styles, 'color: rgba(1, 2, 3, 1);', 'color: #010203;'); + assertStyles(styles, 'color: rgba(1, 2, 3, 1);', 'color: rgba(1, 2, 3, 1);'); assertStyles(styles, 'color: rgba(1, 2, 3, 0);', 'color: rgba(1, 2, 3, 0);'); assertStyles(styles, 'color: rgba(1, 2, 3, 0.5);', 'color: rgba(1, 2, 3, 0.5);'); + assertStyles( + styles, + 'color: rgba ( 1 , 2 , 3 , 1 );', + 'color: rgba ( 1 , 2 , 3 , 1 );' + ); + assertStyles( + styles, + 'color: rgba ( 1 , 2 , 3);', + 'color: rgba ( 1 , 2 , 3);' + ); + assertStyles(styles, 'color: rgba(1, 2, 3);', 'color: rgba(1, 2, 3);'); + assertStyles(styles, 'color: rgb(1, 2, 3, 0.5);', 'color: rgb(1, 2, 3, 0.5);'); }); - }); diff --git a/modules/tinymce/src/core/test/ts/browser/paste/PasteStylesTest.ts b/modules/tinymce/src/core/test/ts/browser/paste/PasteStylesTest.ts index 7637052e946..05266193e72 100644 --- a/modules/tinymce/src/core/test/ts/browser/paste/PasteStylesTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/paste/PasteStylesTest.ts @@ -64,8 +64,8 @@ describe('browser.tinymce.core.paste.PasteStylesTest', () => { editor.options.set('paste_webkit_styles', 'color'); editor.setContent('

test

'); TinySelections.setSelection(editor, [ 0, 0 ], 0, [ 0, 0 ], 4); - Clipboard.pasteItems(TinyDom.body(editor), { 'text/html': 'b' }); - TinyAssertions.assertContent(editor, `

b

`); + Clipboard.pasteItems(TinyDom.body(editor), { 'text/html': 'b' }); + TinyAssertions.assertContent(editor, `

b

`); }); it('TINY-8525: paste span without any color styles, paste_webkit_styles: color,font-family', () => { diff --git a/modules/tinymce/src/core/test/ts/browser/paste/PasteTest.ts b/modules/tinymce/src/core/test/ts/browser/paste/PasteTest.ts index a5c2a1eb83e..6892350fe2f 100644 --- a/modules/tinymce/src/core/test/ts/browser/paste/PasteTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/paste/PasteTest.ts @@ -455,7 +455,7 @@ describe('browser.tinymce.core.paste.PasteTest', () => { editor.execCommand('mceInsertClipboardContent', false, { html: ( 'a' + - 'b' + 'b' ) }); @@ -471,7 +471,7 @@ describe('browser.tinymce.core.paste.PasteTest', () => { html: ( 'a' + 'b' + - 'c' + 'c' ) }); @@ -480,18 +480,18 @@ describe('browser.tinymce.core.paste.PasteTest', () => { it('TBA: paste webkit remove runtime styles (color) in the same (color) (rgb)', () => { const editor = hook.editor(); - editor.setContent('

Test'); + editor.setContent('

Test'); TinySelections.setSelection(editor, [ 0, 0 ], 0, [ 0, 0 ], 4); editor.execCommand('mceInsertClipboardContent', false, { html: ( 'a' + 'b' + - 'c' + 'c' ) }); - TinyAssertions.assertContent(editor, '

abc

'); + TinyAssertions.assertContent(editor, '

abc

'); }); it('TINY-9997: Paste command does not dispatch input events', async () => { diff --git a/modules/tinymce/src/plugins/table/test/ts/browser/ui/TableCellBackgroundColorTest.ts b/modules/tinymce/src/plugins/table/test/ts/browser/ui/TableCellBackgroundColorTest.ts index f31a8be1193..c704d05ca7f 100644 --- a/modules/tinymce/src/plugins/table/test/ts/browser/ui/TableCellBackgroundColorTest.ts +++ b/modules/tinymce/src/plugins/table/test/ts/browser/ui/TableCellBackgroundColorTest.ts @@ -31,7 +31,7 @@ describe('browser.tinymce.plugins.table.ui.TableCellBackgroundColorTest', () => subMenuRemoveTitle: 'Remove color', rows: 1, columns: 1, - customStyle: 'background-color: rgb(81, 169, 81)' + customStyle: 'background-color: #51a951' }); }); @@ -42,7 +42,7 @@ describe('browser.tinymce.plugins.table.ui.TableCellBackgroundColorTest', () => subMenuRemoveTitle: 'Remove color', rows: 2, columns: 2, - customStyle: 'background-color: rgb(81, 169, 81)' + customStyle: 'background-color: #51a951' }); }); }); diff --git a/modules/tinymce/src/plugins/table/test/ts/browser/ui/TableCellBorderColorTest.ts b/modules/tinymce/src/plugins/table/test/ts/browser/ui/TableCellBorderColorTest.ts index 021e5fae05f..66408f9407f 100644 --- a/modules/tinymce/src/plugins/table/test/ts/browser/ui/TableCellBorderColorTest.ts +++ b/modules/tinymce/src/plugins/table/test/ts/browser/ui/TableCellBorderColorTest.ts @@ -31,8 +31,7 @@ describe('browser.tinymce.plugins.table.ui.TableCellBorderColorTest', () => { subMenuRemoveTitle: 'Remove color', rows: 1, columns: 1, - customStyle: 'border-color: rgb(21, 154, 21)' - + customStyle: 'border-color: #159a15' }); }); @@ -43,7 +42,7 @@ describe('browser.tinymce.plugins.table.ui.TableCellBorderColorTest', () => { subMenuRemoveTitle: 'Remove color', rows: 2, columns: 2, - customStyle: 'border-color: rgb(21, 154, 21)' + customStyle: 'border-color: #159a15' }); }); diff --git a/modules/tinymce/src/plugins/table/test/ts/browser/ui/TableDialogTest.ts b/modules/tinymce/src/plugins/table/test/ts/browser/ui/TableDialogTest.ts index f232ef6b4e6..a0aa01a1231 100644 --- a/modules/tinymce/src/plugins/table/test/ts/browser/ui/TableDialogTest.ts +++ b/modules/tinymce/src/plugins/table/test/ts/browser/ui/TableDialogTest.ts @@ -1,5 +1,6 @@ import { ApproxStructure, UiFinder } from '@ephox/agar'; import { after, before, context, describe, it } from '@ephox/bedrock-client'; +import { PlatformDetection } from '@ephox/sand'; import { SugarBody } from '@ephox/sugar'; import { TinyAssertions, TinyHooks, TinySelections, TinyState } from '@ephox/wrap-mcagar'; @@ -9,6 +10,12 @@ import Plugin from 'tinymce/plugins/table/Plugin'; import * as TableTestUtils from '../../module/test/TableTestUtils'; describe('browser.tinymce.plugins.table.TableDialogTest', () => { + // TODO: border color should be in HEX format once https://ephocks.atlassian.net/browse/TINY-8917 is fixed. + // Various tests here expect RGB, but should be expecting HEX. + // In Safari 15, the colors are also swapped in various border color styles, so also remove this once done. + const platform = PlatformDetection.detect(); + const isSafari15 = platform.browser.isSafari() && platform.browser.version.major === 15; + const hook = TinyHooks.bddSetup({ plugins: 'table', toolbar: 'tableprops', @@ -159,8 +166,8 @@ describe('browser.tinymce.plugins.table.TableDialogTest', () => { 'margin-right': str.is('auto'), 'border-width': str.is('1px'), 'border-spacing': str.is('5px'), - 'background-color': str.startsWith(''), // need to check presence but it can be #ff0000 or rgb(255, 0, 0) - 'border-color': str.startsWith('') // need to check presence but it can be #ff0000 or rgb(255, 0, 0) + 'background-color': str.startsWith(''), // need to check presence but it can be #ff0000 or #ff0000 + 'border-color': str.startsWith('') // need to check presence but it can be #ff0000 or #ff0000 }, children: [ s.element('caption', { }), @@ -236,8 +243,8 @@ describe('browser.tinymce.plugins.table.TableDialogTest', () => { it('TBA: Open dialog via execCommand', async () => { const baseHtml = '' + '' + '' + @@ -286,11 +293,11 @@ describe('browser.tinymce.plugins.table.TableDialogTest', () => { const newHtml = '

X
' + '' + '' + - '' + + '' + '' + '
Caption
X
X
'; @@ -427,7 +434,7 @@ describe('browser.tinymce.plugins.table.TableDialogTest', () => { align: '' }); - const inputHtml = '
 
'; + const inputHtml = '
 
'; const editor = hook.editor(); editor.setContent(inputHtml); @@ -551,15 +558,15 @@ describe('browser.tinymce.plugins.table.TableDialogTest', () => { it('TINY-9837: Should apply bordercolor to cells if it has been modified', () => testApplyDataToCells({ bordercolor: '#FF0000' }, [ - '', + `
`, '', '', '', - '', + '', '', '', - '', - '', + '', + '', '', '', '
   
    
' @@ -583,15 +590,15 @@ describe('browser.tinymce.plugins.table.TableDialogTest', () => { it('TINY-9837: Should apply border and bordercolor to cells if they have been modified', () => testApplyDataToCells({ border: '3px', bordercolor: '#FF0000' }, [ - '', + `
`, '', '', '', - '', + '', '', '', - '', - '', + '', + '', '', '', '
   
    
' @@ -599,15 +606,15 @@ describe('browser.tinymce.plugins.table.TableDialogTest', () => { it('TINY-9837: Should apply cellpadding and bordercolor to cells if they have been modified', () => testApplyDataToCells({ cellpadding: '3px', bordercolor: '#FF0000' }, [ - '', + `
`, '', '', '', - '', + '', '', '', - '', - '', + '', + '', '', '', '
   
    
' @@ -615,15 +622,15 @@ describe('browser.tinymce.plugins.table.TableDialogTest', () => { it('TINY-9837: Should apply border, cellpadding and bordercolor to cells if they have been modified', () => testApplyDataToCells({ border: '3px', cellpadding: '3px', bordercolor: '#FF0000' }, [ - '', + `
`, '', '', '', - '', + '', '', '', - '', - '', + '', + '', '', '', '
   
    
' diff --git a/modules/tinymce/src/plugins/table/test/ts/browser/ui/TableRowDialogTest.ts b/modules/tinymce/src/plugins/table/test/ts/browser/ui/TableRowDialogTest.ts index 654718b66c8..512e8da2ef9 100644 --- a/modules/tinymce/src/plugins/table/test/ts/browser/ui/TableRowDialogTest.ts +++ b/modules/tinymce/src/plugins/table/test/ts/browser/ui/TableRowDialogTest.ts @@ -158,7 +158,7 @@ describe('browser.tinymce.plugins.table.TableRowDialogTest', () => { TinyAssertions.assertContent(editor, '' + '' + - '' + + '' + '' + '' + @@ -449,7 +449,7 @@ describe('browser.tinymce.plugins.table.TableRowDialogTest', () => { TinyAssertions.assertContent(editor, '
a
' + '' + - '' + + '' + '' + '' + '' + diff --git a/modules/tinymce/src/themes/silver/test/ts/browser/editor/ForceHexColorTest.ts b/modules/tinymce/src/themes/silver/test/ts/browser/editor/ForceHexColorTest.ts deleted file mode 100644 index b0920817ba6..00000000000 --- a/modules/tinymce/src/themes/silver/test/ts/browser/editor/ForceHexColorTest.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { Transformations } from '@ephox/acid'; -import { context, describe, it } from '@ephox/bedrock-client'; -import { TinyAssertions, TinyHooks, TinySelections, TinyUiActions } from '@ephox/wrap-mcagar'; -import { assert } from 'chai'; - -import Editor from 'tinymce/core/api/Editor'; - -describe('browser.tinymce.themes.silver.editor.ForceHexColorTest', () => { - const applyAndAssertForeColor = (editor: Editor, appliedColor: string, expectedColor: string) => { - // Reset content - editor.setContent('

colour me

'); - - return { - /** Apply color using 'mceApplyTextcolor' command. */ - usingCommand: () => { - TinySelections.setSelection(editor, [ 0, 0 ], 0, [ 0, 0 ], 'color me'.length + 1); - editor.execCommand('mceApplyTextcolor', 'forecolor' as any, appliedColor); - TinyAssertions.assertContentPresence(editor, { [`span[data-mce-style="color: ${expectedColor};"]`]: 1 }); - TinyAssertions.assertContent(editor, `

colour me

`); - }, - /** Apply color using the 'forecolor' part of the toolbar. */ - usingToolbar: async () => { - TinySelections.setSelection(editor, [ 0, 0 ], 0, [ 0, 0 ], 'color me'.length + 1); - TinyUiActions.clickOnToolbar(editor, '[aria-label^="Text color"] > .tox-tbtn + .tox-split-button__chevron'); - await TinyUiActions.pWaitForUi(editor, '.tox-swatches'); - TinyUiActions.clickOnUi(editor, `div[data-mce-color="${appliedColor}"]`); - TinyAssertions.assertContentPresence(editor, { [`span[data-mce-style="color: ${expectedColor};"]`]: 1 }); - TinyAssertions.assertContent(editor, `

colour me

`); - }, - }; - }; - - context('force_hex_color option set to default ("off")', () => { - const hook = TinyHooks.bddSetupLight({ - base_url: '/project/tinymce/js/tinymce', - }, []); - - it('TINY-9819: data-mce-style colors are left as RGB', () => { - const editor = hook.editor(); - assert.equal(editor.options.get('force_hex_color'), 'off', 'force_hex_color must be set to "off"'); - applyAndAssertForeColor(editor, '#E03E2D', 'rgb(224, 62, 45)').usingCommand(); - applyAndAssertForeColor(editor, '#FF0000', 'rgb(255, 0, 0)').usingCommand(); - applyAndAssertForeColor(editor, '#00FF00', 'rgb(0, 255, 0)').usingCommand(); - applyAndAssertForeColor(editor, 'rgb(40, 120, 200)', 'rgb(40, 120, 200)').usingCommand(); - }); - - it('TINY-9819: alpha channel is unaffected', () => { - const editor = hook.editor(); - applyAndAssertForeColor(editor, 'rgba(224, 62, 45, 0.5)', 'rgba(224, 62, 45, 0.5)').usingCommand(); - applyAndAssertForeColor(editor, 'rgba(3, 2, 1, 0.01)', 'rgba(3, 2, 1, 0.01)').usingCommand(); - }); - }); - - context('force_hex_color option set to "rgb_only"', () => { - const color_map = [ '#E03E2D', 'Red', 'rgb(10, 200, 10)', 'Green' ]; - const hook = TinyHooks.bddSetupLight({ - base_url: '/project/tinymce/js/tinymce', - force_hex_color: 'rgb_only', - toolbar: 'forecolor', - color_map, - }, []); - - it('TINY-9819: will leave RGBA colors unaffected', () => { - const editor = hook.editor(); - assert.equal(editor.options.get('force_hex_color'), 'rgb_only', 'force_hex_color must be set to "rgb_only"'); - applyAndAssertForeColor(editor, 'rgba(50, 60, 70, 0.4)', 'rgba(50, 60, 70, 0.4)').usingCommand(); - }); - - it('TINY-9819: will convert RGB to HEX', () => { - applyAndAssertForeColor(hook.editor(), 'rgb(50, 60, 70)', '#323C46').usingCommand(); - applyAndAssertForeColor(hook.editor(), 'rgb(105, 72, 72)', '#694848').usingCommand(); - }); - - it('TINY-9819: will convert RGB to HEX with toolbar & color_map', async () => { - const editor = hook.editor(); - await applyAndAssertForeColor(editor, color_map[0], color_map[0]).usingToolbar(); - const hex = Transformations.rgbaToHexString(color_map[2]); - await applyAndAssertForeColor(editor, hex, hex).usingToolbar(); - }); - }); - - context('force_hex_color option set to "always"', () => { - const color_map = [ '#E03E2D', 'Red', 'rgb(10, 200, 10)', 'Green', 'rgba(10, 10, 200, 0.9)', 'Blue' ]; - const hook = TinyHooks.bddSetupLight({ - base_url: '/project/tinymce/js/tinymce', - force_hex_color: 'always', - toolbar: 'forecolor', - color_map, - }, []); - - it('TINY-9819: will convert RGB & RGBA to HEX', () => { - const editor = hook.editor(); - assert.equal(editor.options.get('force_hex_color'), 'always', 'force_hex_color must be set to "always"'); - applyAndAssertForeColor(editor, 'rgb(50, 60, 70)', '#323C46').usingCommand(); - applyAndAssertForeColor(editor, 'rgba(50, 60, 70, 0.4)', '#323C46').usingCommand(); - }); - - it('TINY-9819: will convert RGB & RGBA to HEX with toolbar & color_map', async () => { - const editor = hook.editor(); - await applyAndAssertForeColor(editor, color_map[0], color_map[0]).usingToolbar(); - let hex = Transformations.rgbaToHexString(color_map[2]); - await applyAndAssertForeColor(editor, hex, hex).usingToolbar(); - hex = Transformations.rgbaToHexString(color_map[4]); - await applyAndAssertForeColor(editor, hex, hex).usingToolbar(); - }); - }); - - context('force_hex_color option set to "always" and without color_map', () => { - const hook = TinyHooks.bddSetupLight({ - base_url: '/project/tinymce/js/tinymce', - force_hex_color: 'always', - toolbar: 'forecolor', - }, []); - - it('TINY-9819: will convert RGB & RGBA to HEX', () => { - const editor = hook.editor(); - assert.isFalse(editor.options.isSet('color_map')); - - applyAndAssertForeColor(editor, '#00FF00', '#00FF00').usingCommand(); - applyAndAssertForeColor(editor, 'rgb(10, 200, 10)', '#0AC80A').usingCommand(); - applyAndAssertForeColor(editor, 'rgba(10, 10, 200, 0.9)', '#0A0AC8').usingCommand(); - }); - - it('TINY-9819: will convert RGB & RGBA to HEX with toolbar & without color_map', async () => { - const editor = hook.editor(); - await applyAndAssertForeColor(editor, '#BA372A', '#BA372A').usingToolbar(); - await applyAndAssertForeColor(editor, '#3598DB', '#3598DB').usingToolbar(); - await applyAndAssertForeColor(editor, '#B96AD9', '#B96AD9').usingToolbar(); - }); - }); -}); From 3a12b0c5d8b0e554cf3aa9ee0ea60a4acb31ec4c Mon Sep 17 00:00:00 2001 From: Mitchell Crompton Date: Fri, 1 Mar 2024 14:36:11 +1000 Subject: [PATCH 04/15] TINY-10713: Change Advanced List plugin name to List Styles (#9454) * TINY-10713: Change Advanced List to List Styles * TINY-10713: Fix order --------- Co-authored-by: MitchCTiny <89239746+MitchCTiny@users.noreply.github.com> --- modules/tinymce/src/core/main/ts/api/ui/Registry.ts | 2 +- modules/tinymce/src/plugins/advlist/main/ts/Plugin.ts | 2 +- modules/tinymce/src/plugins/help/main/ts/data/PluginUrls.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/tinymce/src/core/main/ts/api/ui/Registry.ts b/modules/tinymce/src/core/main/ts/api/ui/Registry.ts index 285908c1981..de543a307e5 100644 --- a/modules/tinymce/src/core/main/ts/api/ui/Registry.ts +++ b/modules/tinymce/src/core/main/ts/api/ui/Registry.ts @@ -163,7 +163,7 @@ const registry = (): Registry.Registry => { addSidebar: bridge.addSidebar, /** - * Registers a new split button for the toolbar. The advanced list plugin uses + * Registers a new split button for the toolbar. The list styles plugin uses * a split button to simplify its functionality. *
* For information on creating a split toolbar button, see: diff --git a/modules/tinymce/src/plugins/advlist/main/ts/Plugin.ts b/modules/tinymce/src/plugins/advlist/main/ts/Plugin.ts index fa9913ee16b..d5ee2efc424 100644 --- a/modules/tinymce/src/plugins/advlist/main/ts/Plugin.ts +++ b/modules/tinymce/src/plugins/advlist/main/ts/Plugin.ts @@ -12,7 +12,7 @@ export default (): void => { Commands.register(editor); } else { // eslint-disable-next-line no-console - console.error('Please use the Lists plugin together with the Advanced List plugin.'); + console.error('Please use the Lists plugin together with the List Styles plugin.'); } }); }; diff --git a/modules/tinymce/src/plugins/help/main/ts/data/PluginUrls.ts b/modules/tinymce/src/plugins/help/main/ts/data/PluginUrls.ts index 64abd1efd6e..719a4990b9d 100644 --- a/modules/tinymce/src/plugins/help/main/ts/data/PluginUrls.ts +++ b/modules/tinymce/src/plugins/help/main/ts/data/PluginUrls.ts @@ -20,7 +20,6 @@ export interface PluginUrl extends PartialPluginUrl { // These lists are automatically sorted when generating the dialog. const urls = Arr.map([ { key: 'accordion', name: 'Accordion' }, - { key: 'advlist', name: 'Advanced List' }, { key: 'anchor', name: 'Anchor' }, { key: 'autolink', name: 'Autolink' }, { key: 'autoresize', name: 'Autoresize' }, @@ -38,6 +37,7 @@ const urls = Arr.map([ { key: 'insertdatetime', name: 'Insert Date/Time' }, { key: 'link', name: 'Link' }, { key: 'lists', name: 'Lists' }, + { key: 'advlist', name: 'List Styles' }, { key: 'media', name: 'Media' }, { key: 'nonbreaking', name: 'Nonbreaking' }, { key: 'pagebreak', name: 'Page Break' }, From 273d499f35c6a0a70ac915dc0170d558da97cb7b Mon Sep 17 00:00:00 2001 From: jscasca Date: Mon, 4 Mar 2024 17:02:34 +1000 Subject: [PATCH 05/15] TINY-10691: Test name changes (#9461) --- Jenkinsfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index c4e7d8fbbeb..2a979ab279c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -153,7 +153,7 @@ def props def cacheName = "cache_${BUILD_TAG}" -def testname = "tinymce_${cleanBuildName(env.BRANCH_NAME)}_test${env.BUILD_NUMBER}" +def testPrefix = "tinymce_${cleanBuildName(env.BRANCH_NAME)}-build${env.BUILD_NUMBER}" timestamps { bedrockRemoteTools.nodeProducerPod( @@ -227,7 +227,8 @@ timestamps { if (platform.provider) { // use remote def name = "${os}-${platform.browser}${browserVersion}-${platform.provider}${suffix}" - processes[name] = runTestPod(cacheName, name, testname, platform.browser, platform.provider, platform.os, platform.version, s_bucket, s_buckets, runAllTests) + def testName = "${env.BUILD_NUMBER}-${os}-${platform.browser}" + processes[name] = runTestPod(cacheName, name, "${testPrefix}_${testName}", platform.browser, platform.provider, platform.os, platform.version, s_bucket, s_buckets, runAllTests) } else { // use local def name = "${os}-${platform.browser}" From 43769debb0bea065aa702e71b8c1043bc7492b83 Mon Sep 17 00:00:00 2001 From: Andrew Herron Date: Fri, 1 Mar 2024 17:28:25 +1100 Subject: [PATCH 06/15] TINY-10602: Reverted requirement for `build` to run `lint`. --- modules/tinymce/project.json | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/tinymce/project.json b/modules/tinymce/project.json index 6e491dac421..2bd79987dfb 100644 --- a/modules/tinymce/project.json +++ b/modules/tinymce/project.json @@ -8,7 +8,6 @@ "^tiny-product" ], "dependsOn": [ - "lint", "^build" ], "outputs": [ From df7b989ed9f486ea16d8ed316863f75f19889b44 Mon Sep 17 00:00:00 2001 From: shanmen-tiny Date: Wed, 6 Mar 2024 10:28:02 +1100 Subject: [PATCH 07/15] TINY-10732: Fallback `FooterToggleButton` in dialog to use `spec.text` to set the `aria-label` attribute (#9470) --- modules/tinymce/src/themes/silver/main/ts/ui/general/Button.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/tinymce/src/themes/silver/main/ts/ui/general/Button.ts b/modules/tinymce/src/themes/silver/main/ts/ui/general/Button.ts index 6538adcc2f1..629d85b9c82 100644 --- a/modules/tinymce/src/themes/silver/main/ts/ui/general/Button.ts +++ b/modules/tinymce/src/themes/silver/main/ts/ui/general/Button.ts @@ -227,7 +227,7 @@ const renderToggleButton = (spec: FooterToggleButtonSpec, providers: UiFactoryBa borderless: false }; - const tooltipAttributes = buttonSpec.tooltip.map<{}>((tooltip) => ({ + const tooltipAttributes = buttonSpec.tooltip.or(spec.text).map((tooltip) => ({ 'aria-label': providers.translate(tooltip), })).getOr({}); From 809fd2415bb28ce2c2f1f9afc8775372b4e3a7e5 Mon Sep 17 00:00:00 2001 From: spocke Date: Wed, 6 Mar 2024 08:16:46 +0100 Subject: [PATCH 08/15] TINY-10717: Fixed Esc and arrow keys and IME not starting (#9463) --- modules/tinymce/src/core/main/ts/keyboard/Autocompleter.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/tinymce/src/core/main/ts/keyboard/Autocompleter.ts b/modules/tinymce/src/core/main/ts/keyboard/Autocompleter.ts index 682f5d2a2a2..31fd94d9950 100644 --- a/modules/tinymce/src/core/main/ts/keyboard/Autocompleter.ts +++ b/modules/tinymce/src/core/main/ts/keyboard/Autocompleter.ts @@ -32,13 +32,14 @@ const setupEditorInput = (editor: Editor, api: AutocompleterApi) => { update.throttle(); // Pressing closes the autocompleter } else if (keyCode === 27) { + update.cancel(); // We need to cancel here since Esc cancels the IME composition and triggers an input event api.cancelIfNecessary(); } else if (keyCode === 38 || keyCode === 40) { // Arrow up and down keys needs to cancel the update since while composing arrow up or down will end the compose and issue a input event // that causes the list to update and then the focus moves up to the first item in the auto completer list. update.cancel(); } - }); + }, true); // Need to add this to the top so that it exectued before the silver keyboard event editor.on('remove', update.cancel); }; @@ -58,8 +59,7 @@ export const setup = (editor: Editor): void => { }; const commenceIfNecessary = (context: AutocompleteContext) => { - /* Autocompleter works by moving the content into a newly generated element. When combined with composing this creates issues where unexpected data input and visual issues */ - if (!isActive() && !editor.composing) { + if (!isActive()) { // store the element/context activeAutocompleter.set({ trigger: context.trigger, From 0decc9d90cc491f08b7fbd766c7029a7e18b0803 Mon Sep 17 00:00:00 2001 From: tiny-ben-tran Date: Thu, 7 Mar 2024 09:05:38 +1030 Subject: [PATCH 09/15] TINY-10650: Add a link referencing custom view doc page to the addView API doc (#9456) --- .../src/core/main/ts/api/ui/Registry.ts | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/modules/tinymce/src/core/main/ts/api/ui/Registry.ts b/modules/tinymce/src/core/main/ts/api/ui/Registry.ts index de543a307e5..ac9db271dd0 100644 --- a/modules/tinymce/src/core/main/ts/api/ui/Registry.ts +++ b/modules/tinymce/src/core/main/ts/api/ui/Registry.ts @@ -16,7 +16,7 @@ const registry = (): Registry.Registry => { * Emoticons and Charmap use an autocompleter. *
* For information on creating an autocompleter, see: - * + * * UI Components - Autocompleter. * * @method addAutocompleter @@ -30,7 +30,7 @@ const registry = (): Registry.Registry => { * via keyboard navigation controls. *
* For information on creating a basic toolbar button, see: - * + * * UI Components - Types of toolbar buttons: Basic button. * * @method addButton @@ -48,7 +48,7 @@ const registry = (): Registry.Registry => { * contextual input form appears allowing for quick changes to the url field. *
* For information on creating context forms, see: - * + * * UI Components - Context forms. * * @method addContextForm @@ -62,7 +62,7 @@ const registry = (): Registry.Registry => { * for example, the cursor is inside a table. *
* For information on creating context menus, see: - * + * * UI Components - Context Menu. * * @method addContextMenu @@ -105,7 +105,7 @@ const registry = (): Registry.Registry => { * addNestedMenuItem or addToggleMenuItem. *
* For information on creating a toolbar menu button, see: - * + * * UI Components - Types of toolbar buttons: Menu button. * * @method addMenuButton @@ -119,7 +119,7 @@ const registry = (): Registry.Registry => { * via keyboard navigation controls. *
* For information on creating a basic menu item, see: - * + * * UI Components - Custom menu items: Basic menu items. * * @method addMenuItem @@ -134,7 +134,7 @@ const registry = (): Registry.Registry => { * created by addMenuItem, addNestedMenuItem or addToggleMenuItem. *
* For information on creating a nested menu item, see: - * + * * UI Components - Custom menu items: Nested menu items. * * @method addNestedMenuItem @@ -153,7 +153,7 @@ const registry = (): Registry.Registry => { * sidebar for its Ui components. *
* For information on creating a custom sidebar, see: - * + * * UI Components - Custom sidebar. * * @method addSidebar @@ -167,7 +167,7 @@ const registry = (): Registry.Registry => { * a split button to simplify its functionality. *
* For information on creating a split toolbar button, see: - * + * * UI Components - Types of toolbar buttons: Split button. * * @method addSplitButton @@ -181,7 +181,7 @@ const registry = (): Registry.Registry => { * be set in the configuration. *
* For information on creating a toggle toolbar button, see: - * + * * UI Components - Types of toolbar buttons: Toggle button. * * @method addToggleButton @@ -197,7 +197,7 @@ const registry = (): Registry.Registry => { * Note: Group toolbar buttons can only be used when using the floating toolbar mode. *
* For information on creating a group toolbar button, see: - * + * * UI Components - Types of toolbar buttons: Group toolbar button. * * @method addGroupToolbarButton @@ -211,7 +211,7 @@ const registry = (): Registry.Registry => { * showing a tick in the menu item to represent state. *
* For information on creating a toggle menu item, see: - * + * * UI Components - Custom menu items: Toggle menu items. * * @method addToggleMenuItem @@ -229,6 +229,10 @@ const registry = (): Registry.Registry => { * There is also a ToggleView command. * The ToggleView command can toggle the view visibility. * The ToggleView command can be queried for its current state. + *
+ * For information on creating a custom view, see: + * + * UI Components - Custom view. * * @method addView * @param {String} name Unique name identifying the new view. From 48d8d0eff62e7414e8505eac3e2891d79eba806b Mon Sep 17 00:00:00 2001 From: tiny-ben-tran Date: Thu, 7 Mar 2024 09:21:51 +1030 Subject: [PATCH 10/15] TINY-10734: Fix the bottom part of the revision history diff iframe hidden behind its container (#9471) --- .../theme/components/revisionhistory/revisionhistory.less | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/oxide/src/less/theme/components/revisionhistory/revisionhistory.less b/modules/oxide/src/less/theme/components/revisionhistory/revisionhistory.less index 8119642d610..e927f954317 100644 --- a/modules/oxide/src/less/theme/components/revisionhistory/revisionhistory.less +++ b/modules/oxide/src/less/theme/components/revisionhistory/revisionhistory.less @@ -17,9 +17,13 @@ .tox { .tox-revisionhistory__pane { + padding: 0 !important; /* Override the default padding of tox-view__pane */ + } + + .tox-revisionhistory__container { display: flex; flex-direction: column; - padding: 0 !important; /* Override the default padding of tox-view__pane */ + height: 100%; } .tox-revisionhistory { From dd3822f68fe0dd7390487b3a45b315005c4d6f55 Mon Sep 17 00:00:00 2001 From: tiny-ben-tran Date: Thu, 7 Mar 2024 09:56:53 +1030 Subject: [PATCH 11/15] TINY-10710: Add focus style for the revisions list (#9469) --- .../revisionhistory/revisionhistory.less | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/modules/oxide/src/less/theme/components/revisionhistory/revisionhistory.less b/modules/oxide/src/less/theme/components/revisionhistory/revisionhistory.less index e927f954317..81e8ca16231 100644 --- a/modules/oxide/src/less/theme/components/revisionhistory/revisionhistory.less +++ b/modules/oxide/src/less/theme/components/revisionhistory/revisionhistory.less @@ -71,6 +71,22 @@ overflow-y: auto; padding: @revisionhistory-card-padding; + &:focus { + height: 100%; + position: relative; // Override static which prevents z-index to have any effect + z-index: 1; // Ensure focus outline is on top of other buttons + + &::after { + .keyboard-focus-outline-mixin(); + + border-radius: @control-border-radius; + bottom: 1px; + left: 1px; + right: 1px; + top: 1px; + } + } + .tox-revisionhistory__card { border: @revisionhistory-border; border-radius: @control-border-radius; From e13c27a9ebc0ee63fca259c1743ceecacbb23de2 Mon Sep 17 00:00:00 2001 From: Mitchell Crompton Date: Mon, 11 Mar 2024 09:26:05 +1000 Subject: [PATCH 12/15] TINY-10639: Update Jenkins to Safari 17 and fix test failures (#9473) * TINY-10639: Safari 17 browser check * TINY-10639: Fixed a couple tests * TINY-10639: Update more tests * TINY-10639: Replace Sand API * TINY-10639: Update safari version in jenkins file and remove safari < 17 checks * TINY-10639: Undo test changes * TINY-10639: Fix failing webdriver tests * TINY-10639: Fix dragster test * TINY-10639: Fix safari webdriver tests * TINY-10639: Testing new content to resolve some safari failures * TINY-10639: Fix "e" character not working in safari webdriver tests * TINY-10639: Testing with focus * TINY-10639: Test new selector * TINY-10639: Skip failing safari nonbreaking tests * TINY-10639: Link Jira * TINY-10639: Fix dragster test in Chrome * TINY-10639: Fix Dragster test * TINY-10639: Fix Firefox failure with inline blocks * Revert "TINY-10639: Fix Firefox failure with inline blocks" This reverts commit ad56f4b101883f2197b4a3bc220a43626f2623c1. * TINY-10639: Update Safari to use latest version * TINY-10639: Skip failing tests in firefox for TINY-10742 * TINY-10639: Fix clearData new behaviour on chrome * TINY-10639: Skip clearData test for TINY-10743 * TINY-10639: Fix skipping tests * TINY-10639: Skipping failing tests to be addressed in TINY-10737 --------- Co-authored-by: MitchCTiny <89239746+MitchCTiny@users.noreply.github.com> --- Jenkinsfile | 3 +- .../browser/datatransfer/DataTransferTest.ts | 11 ++--- .../src/test/ts/browser/SelectionRangeTest.ts | 43 ++++++------------- .../test/ts/browser/FormatterRemoveTest.ts | 12 +++++- .../browser/annotate/AnnotationStylingTest.ts | 2 +- .../ts/browser/content/EditorContentTest.ts | 18 +------- .../content/EditorGetContentRawTest.ts | 8 +--- .../ts/browser/content/InsertContentTest.ts | 9 +--- .../core/test/ts/browser/dom/SelectionTest.ts | 7 ++- .../core/test/ts/browser/dom/TrimBodyTest.ts | 6 +-- .../test/ts/browser/html/DomParserTest.ts | 4 +- .../test/ts/browser/html/SanitizationTest.ts | 7 +-- .../ts/webdriver/keyboard/SpaceKeyTest.ts | 12 ++++-- .../webdriver/AccordionBackspaceDeleteTest.ts | 30 ++++++------- .../ts/webdriver/NonbreakingTypingTest.ts | 17 +++++--- .../ts/webdriver/NonbreakingWrapTypingTest.ts | 24 ++++++----- 16 files changed, 89 insertions(+), 124 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 2a979ab279c..f00c28d097c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -208,8 +208,7 @@ timestamps { [ browser: 'edge', provider: 'lambdatest', buckets: 1 ], [ browser: 'chrome', provider: 'lambdatest', os: 'macOS Sonoma', buckets: 1 ], [ browser: 'firefox', provider: 'lambdatest', os: 'macOS Sonoma', buckets: 1 ], - // [ browser: 'safari', provider: 'lambdatest', os: 'macOS Sonoma', buckets: 1, version: '17' ], // TINY-10639: Investigate Safari 17 issues - [ browser: 'safari', provider: 'lambdatest', os: 'macOS Monterey', buckets: 1, version: '15' ], + [ browser: 'safari', provider: 'lambdatest', os: 'macOS Sonoma', buckets: 1 ] ]; def processes = [:] diff --git a/modules/dragster/src/test/ts/browser/datatransfer/DataTransferTest.ts b/modules/dragster/src/test/ts/browser/datatransfer/DataTransferTest.ts index 3595177d642..0950ef7010d 100644 --- a/modules/dragster/src/test/ts/browser/datatransfer/DataTransferTest.ts +++ b/modules/dragster/src/test/ts/browser/datatransfer/DataTransferTest.ts @@ -190,13 +190,7 @@ describe('browser.dragster.datatransfer.DataTransferTest', () => { it('TINY-9601: Files list cannot be modified', () => { const transfer = createDataTransfer(); addAndAssertFile(transfer, testFile1, 1); - if (isSafari) { - // Safari doesn't throw a TypeError on native DataTransfer.files so verify using different method - transfer.files[0] = testFile2; - assert.deepEqual(transfer.files.item(0), testFile1, 'Should still be file 1'); - } else { - assertFilesCannotBeModified(transfer); - } + assertFilesCannotBeModified(transfer); }); it('TINY-9601: Files list cannot be modified when in protected mode', () => { @@ -209,7 +203,8 @@ describe('browser.dragster.datatransfer.DataTransferTest', () => { }); context('clearData', () => { - it('TINY-9601: clearData should clear data as expected', () => { + // TINY-10743: Skipping until clearData behaviour is resolved + it.skip('TINY-9601: clearData should clear data as expected', () => { const transfer = createDataTransfer(); transfer.setData('text/plain', 'Hello'); diff --git a/modules/sugar/src/test/ts/browser/SelectionRangeTest.ts b/modules/sugar/src/test/ts/browser/SelectionRangeTest.ts index 8f460d0d837..20ce67c5e42 100644 --- a/modules/sugar/src/test/ts/browser/SelectionRangeTest.ts +++ b/modules/sugar/src/test/ts/browser/SelectionRangeTest.ts @@ -122,6 +122,12 @@ UnitTest.test('WindowSelectionTest', () => { finish: [ 0, 1, 0 ], foffset: 'w'.length }, + safari: { + start: [ 0 ], + soffset: 2, + finish: [ 0, 1, 0 ], + foffset: 'w'.length + }, fallback: { start: [ 0, 1, 0 ], soffset: 'world'.length, @@ -142,12 +148,6 @@ UnitTest.test('WindowSelectionTest', () => { soffset: 0, finish: [ 0 ], foffset: 7 - }, - safari: { - start: [ 0, 0 ], - soffset: ''.length, - finish: [ 0 ], - foffset: 7 } }, Situ.on(find( [ 0 ]), 0), @@ -169,12 +169,6 @@ UnitTest.test('WindowSelectionTest', () => { soffset: 7, finish: [ 0 ], foffset: 0 - }, - safari: { - start: [ 0 ], - soffset: 7, - finish: [ 0, 0 ], - foffset: ''.length } }, Situ.on(find( [ 0 ]), 7), @@ -184,13 +178,6 @@ UnitTest.test('WindowSelectionTest', () => { checkSelection( 'LTR selection (t I)', { - // '

This world is not wha[t I

]wanted


And even more

'; - safari: { - start: [ 0, 3, 2 ], - soffset: ''.length, - finish: [ 0 ], - foffset: 6 - }, fallback: { start: [ 0, 3, 1 ], soffset: 1, @@ -224,6 +211,12 @@ UnitTest.test('WindowSelectionTest', () => { start: [ 0 ], soffset: 6 }, + safari: { + finish: [ 0, 3, 1 ], + foffset: 1, + start: [ 0 ], + soffset: 6 + }, spartan: { finish: [ 0, 3, 1 ], foffset: 1, @@ -263,12 +256,6 @@ UnitTest.test('WindowSelectionTest', () => { soffset: 0, finish: [ 0 ], foffset: 0 - }, - safari: { - start: [ 0, 0 ], - soffset: 0, - finish: [ 0, 0 ], - foffset: 0 } }, Situ.on(find( [ 0 ]), 0 ), @@ -283,12 +270,6 @@ UnitTest.test('WindowSelectionTest', () => { soffset: 0, finish: [ 0 ], foffset: 0 - }, - safari: { - start: [ 0, 0 ], - soffset: 0, - finish: [ 0, 0 ], - foffset: 0 } }, Situ.on(find( [ 0 ]), 0 ), diff --git a/modules/tinymce/src/core/test/ts/browser/FormatterRemoveTest.ts b/modules/tinymce/src/core/test/ts/browser/FormatterRemoveTest.ts index a2e384a5c90..44de177d1a5 100644 --- a/modules/tinymce/src/core/test/ts/browser/FormatterRemoveTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/FormatterRemoveTest.ts @@ -1,4 +1,5 @@ import { describe, it } from '@ephox/bedrock-client'; +import { PlatformDetection } from '@ephox/sand'; import { LegacyUnit, TinyApis, TinyAssertions, TinyHooks, TinySelections } from '@ephox/wrap-mcagar'; import { assert } from 'chai'; @@ -8,6 +9,8 @@ import { ZWSP } from 'tinymce/core/text/Zwsp'; import * as KeyUtils from '../module/test/KeyUtils'; describe('browser.tinymce.core.FormatterRemoveTest', () => { + const browser = PlatformDetection.detect().browser; + const hook = TinyHooks.bddSetupLight({ indent: false, extended_valid_elements: 'b[style],i,span[style|contenteditable|class]', @@ -372,7 +375,14 @@ describe('browser.tinymce.core.FormatterRemoveTest', () => { editor.setContent(initialContent); LegacyUnit.setSelection(editor, 'p:nth-child(2) b', 0, 'p:last-of-type b', 3); editor.formatter.remove('format'); - TinyAssertions.assertContent(editor, initialContent); + if (browser.isSafari()) { + // Safari 17 will not select the non-editable content + // Selection only covers editable "def" and removes format correctly + const expectedContent = '

abc

def

ghj

'; + TinyAssertions.assertContent(editor, expectedContent); + } else { + TinyAssertions.assertContent(editor, initialContent); + } }); it('contentEditable: true inside contentEditable: false', () => { diff --git a/modules/tinymce/src/core/test/ts/browser/annotate/AnnotationStylingTest.ts b/modules/tinymce/src/core/test/ts/browser/annotate/AnnotationStylingTest.ts index aeaa3e34c1a..df8eadb90b8 100644 --- a/modules/tinymce/src/core/test/ts/browser/annotate/AnnotationStylingTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/annotate/AnnotationStylingTest.ts @@ -301,7 +301,7 @@ describe('browser.tinymce.core.annotate.AnnotationStylingTest', () => { it('TINY-8698: should have blue outline for nested editable region when selected noneditable ancestor has a comment', async () => { const editor = hook.editor(); editor.setContent(figureImageHtml); - TinySelections.select(editor, 'img', []); + TinySelections.select(editor, 'figure.image', []); editor.annotator.annotate('test-comment', {}); TinySelections.setCursor(editor, [ 0, 1, 0 ], 1, true); await pAssertStyling(editor, 'figure.image', noBackgroundColor, selectedOutline, false); diff --git a/modules/tinymce/src/core/test/ts/browser/content/EditorContentTest.ts b/modules/tinymce/src/core/test/ts/browser/content/EditorContentTest.ts index 1d41610b56f..f82f317a7b2 100644 --- a/modules/tinymce/src/core/test/ts/browser/content/EditorContentTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/content/EditorContentTest.ts @@ -1,6 +1,5 @@ import { beforeEach, context, describe, it } from '@ephox/bedrock-client'; import { Arr, Type } from '@ephox/katamari'; -import { PlatformDetection } from '@ephox/sand'; import { TinyApis, TinyAssertions, TinyHooks } from '@ephox/wrap-mcagar'; import { assert } from 'chai'; @@ -18,11 +17,6 @@ const defaultExpectedEvents = [ ]; describe('browser.tinymce.core.content.EditorContentTest', () => { - // TINY-10669: Remove this - const platform = PlatformDetection.detect(); - const isSafari = platform.browser.isSafari(); - const isSafariLessThan17 = isSafari && platform.browser.version.major < 17; - const toHtml = (node: AstNode): string => HtmlSerializer({}).serialize(node); const assertContentTreeEqualToHtml = (editor: Editor, html: string, msg: string) => { @@ -578,11 +572,7 @@ describe('browser.tinymce.core.content.EditorContentTest', () => { const editor = hook.editor(); editor.setContent('

'); const content = editor.getContent(); - // TINY-10669: Remove this check - const expected = isSafariLessThan17 - ? '

' - : '

'; - assert.equal(content, expected, 'getContent should not error when there is iframes with child nodes in content'); + assert.equal(content, '

', 'getContent should not error when there is iframes with child nodes in content'); }); it('getContent text with unsanitized content should get text from unsanitized content', () => { @@ -619,11 +609,7 @@ describe('browser.tinymce.core.content.EditorContentTest', () => { it('TINY-10305: setContent html should sanitize content that can cause mXSS via ZWNBSP trimming', () => { const editor = hook.editor(); editor.setContent('

test

'); - // TINY-10669: Remove this check - const expected = isSafariLessThan17 - ? '

test

' - : '

test

'; - TinyAssertions.assertRawContent(editor, expected); + TinyAssertions.assertRawContent(editor, '

test

'); }); it('TINY-10305: setContent tree should sanitize content that can cause mXSS via ZWNBSP trimming', () => { diff --git a/modules/tinymce/src/core/test/ts/browser/content/EditorGetContentRawTest.ts b/modules/tinymce/src/core/test/ts/browser/content/EditorGetContentRawTest.ts index 53064c1228e..22587e2b90a 100644 --- a/modules/tinymce/src/core/test/ts/browser/content/EditorGetContentRawTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/content/EditorGetContentRawTest.ts @@ -1,16 +1,11 @@ import { context, describe, it } from '@ephox/bedrock-client'; import { Arr } from '@ephox/katamari'; -import { PlatformDetection } from '@ephox/sand'; import { TinyApis, TinyAssertions, TinyHooks } from '@ephox/wrap-mcagar'; import { assert } from 'chai'; import Editor from 'tinymce/core/api/Editor'; describe('browser.tinymce.core.content.EditorGetContentRawTest', () => { - // TINY-10669: Remove this - const platform = PlatformDetection.detect(); - const isSafariLessThan17 = platform.browser.isSafari() && platform.browser.version.major < 17; - const hook = TinyHooks.bddSetupLight({ base_url: '/project/tinymce/js/tinymce' }, []); @@ -51,8 +46,7 @@ describe('browser.tinymce.core.content.EditorGetContentRawTest', () => { TinyApis(editor).setRawContent(initial); assert.strictEqual(editor.getContent({ format: 'raw' }), '

test0

</plaintext>', 'Should be expected html'); // TINY-10305: Modern browsers add a closing plaintext tag to end of body. Safari escapes text nodes within <plaintext>. - TinyAssertions.assertRawContent(editor, - isSafariLessThan17 ? '<p>test0</p><plaintext>te\uFEFFst1 test2&lt;p&gt;te\uFEFFst3&lt;/p&gt;</plaintext>' : `${initial}</plaintext>`); + TinyAssertions.assertRawContent(editor, `${initial}</plaintext>`); }); context('Content XSS', () => { diff --git a/modules/tinymce/src/core/test/ts/browser/content/InsertContentTest.ts b/modules/tinymce/src/core/test/ts/browser/content/InsertContentTest.ts index 71cb909d5e4..4f2d7bba201 100644 --- a/modules/tinymce/src/core/test/ts/browser/content/InsertContentTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/content/InsertContentTest.ts @@ -1,5 +1,4 @@ import { context, describe, it } from '@ephox/bedrock-client'; -import { PlatformDetection } from '@ephox/sand'; import { TinyAssertions, TinyHooks, TinySelections, TinyState } from '@ephox/wrap-mcagar'; import { assert } from 'chai'; @@ -9,10 +8,6 @@ import { EditorEvent } from 'tinymce/core/api/util/EventDispatcher'; import * as InsertContent from 'tinymce/core/content/InsertContent'; describe('browser.tinymce.core.content.InsertContentTest', () => { - // TINY-10669: Remove this - const platform = PlatformDetection.detect(); - const isSafariLessThan17 = platform.browser.isSafari() && platform.browser.version.major < 17; - const hook = TinyHooks.bddSetupLight<Editor>({ add_unload_trigger: false, disable_nodechange: true, @@ -845,9 +840,7 @@ describe('browser.tinymce.core.content.InsertContentTest', () => { TinySelections.setCursor(editor, [ 0 ], 0); editor.insertContent('<!--\ufeff><iframe onload=alert(document.domain)>-></body>-->'); // TINY-10305: Safari escapes text nodes within <iframe>. - TinyAssertions.assertRawContent(editor, isSafariLessThan17 - ? '<p><!----><iframe sandbox="">-&gt;&lt;/body&gt;--&gt;&lt;span id="mce_marker" data-mce-type="bookmark"&gt;&amp;#xFEFF;&lt;/span&gt;&lt;/body&gt;</iframe>initial</p>' - : '<p><!---->initial</p>'); + TinyAssertions.assertRawContent(editor, '<p><!---->initial</p>'); }); }); diff --git a/modules/tinymce/src/core/test/ts/browser/dom/SelectionTest.ts b/modules/tinymce/src/core/test/ts/browser/dom/SelectionTest.ts index 0b288ff757e..298f103747f 100644 --- a/modules/tinymce/src/core/test/ts/browser/dom/SelectionTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/dom/SelectionTest.ts @@ -1,4 +1,5 @@ import { context, describe, it } from '@ephox/bedrock-client'; +import { PlatformDetection } from '@ephox/sand'; import { LegacyUnit, TinyAssertions, TinyHooks, TinySelections } from '@ephox/wrap-mcagar'; import { assert } from 'chai'; @@ -10,6 +11,9 @@ import * as CaretContainer from 'tinymce/core/caret/CaretContainer'; import * as Zwsp from 'tinymce/core/text/Zwsp'; describe('browser.tinymce.core.dom.SelectionTest', () => { + const platform = PlatformDetection.detect(); + const isSafari = platform.browser.isSafari(); + const hook = TinyHooks.bddSetupLight<Editor>({ add_unload_trigger: false, entities: 'raw', @@ -1365,7 +1369,8 @@ describe('browser.tinymce.core.dom.SelectionTest', () => { soffset: 1, fpath: [ 1, 0 ], foffset: 1, - expected: false + // TINY-10639: Safari does not allow selection over non-editable content + expected: isSafari })); it('TINY-9477: isEditable on selected noneditable table cells should be true since parent is editable', testIsEditableSelection({ diff --git a/modules/tinymce/src/core/test/ts/browser/dom/TrimBodyTest.ts b/modules/tinymce/src/core/test/ts/browser/dom/TrimBodyTest.ts index e4a152729a5..1d412d53a72 100644 --- a/modules/tinymce/src/core/test/ts/browser/dom/TrimBodyTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/dom/TrimBodyTest.ts @@ -1,13 +1,10 @@ import { context, describe, it } from '@ephox/bedrock-client'; import { Arr } from '@ephox/katamari'; -import { PlatformDetection } from '@ephox/sand'; import { assert } from 'chai'; import * as TrimBody from 'tinymce/core/dom/TrimBody'; describe('browser.tinymce.core.dom.TrimBodyTest', () => { - const isSafari = PlatformDetection.detect().browser.isSafari(); - context('trim', () => { it('trim should trim body containing trimmmable nodes', () => { const tempAttrs = [ 'data-mce-selected' ]; @@ -180,8 +177,7 @@ describe('browser.tinymce.core.dom.TrimBodyTest', () => { unescapedText.innerHTML = `<p>Test</p><${plaintext}>Test<p>Test</p>`; TrimBody.emptyUnescapedZwspTexts(unescapedText); // TINY-10305: Safari escapes text nodes within <plaintext>. - assert.strictEqual(unescapedText.innerHTML, - isSafari ? `<p>Test</p><${plaintext}>Test&lt;p&gt;Test&lt;/p&gt;</${plaintext}>` : `<p>Test</p><${plaintext}>Test<p>Test</p></${plaintext}>`); + assert.strictEqual(unescapedText.innerHTML, `<p>Test</p><${plaintext}>Test<p>Test</p></${plaintext}>`); }); }); }); diff --git a/modules/tinymce/src/core/test/ts/browser/html/DomParserTest.ts b/modules/tinymce/src/core/test/ts/browser/html/DomParserTest.ts index 12ecc85e148..e294169e36d 100644 --- a/modules/tinymce/src/core/test/ts/browser/html/DomParserTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/html/DomParserTest.ts @@ -1,6 +1,5 @@ import { context, describe, it } from '@ephox/bedrock-client'; import { Arr, Fun, Obj } from '@ephox/katamari'; -import { PlatformDetection } from '@ephox/sand'; import { assert } from 'chai'; import Env from 'tinymce/core/api/Env'; @@ -17,7 +16,6 @@ interface ParseTestResult { } describe('browser.tinymce.core.html.DomParserTest', () => { - const browser = PlatformDetection.detect().browser; const schema = Schema({ valid_elements: '*[class|title]' }); const serializer = HtmlSerializer({}, schema); @@ -772,7 +770,7 @@ describe('browser.tinymce.core.html.DomParserTest', () => { assert.equal( serializer.serialize(DomParser(scenario.settings).parse('<iframe><textarea></iframe><img src="a" onerror="alert(document.domain)" />')), - browser.isSafari() || !scenario.isSanitizeEnabled ? '<iframe><textarea></iframe><img src="a">' : '<img src="a">' + scenario.isSanitizeEnabled ? '<img src="a">' : '<iframe><textarea></iframe><img src="a">' ); }); diff --git a/modules/tinymce/src/core/test/ts/browser/html/SanitizationTest.ts b/modules/tinymce/src/core/test/ts/browser/html/SanitizationTest.ts index 4930d13d339..9b3cb635bf0 100644 --- a/modules/tinymce/src/core/test/ts/browser/html/SanitizationTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/html/SanitizationTest.ts @@ -1,5 +1,4 @@ import { context, describe, it } from '@ephox/bedrock-client'; -import { PlatformDetection } from '@ephox/sand'; import { assert } from 'chai'; import Schema from 'tinymce/core/api/html/Schema'; @@ -7,8 +6,6 @@ import { getSanitizer, MimeType } from 'tinymce/core/html/Sanitization'; describe('browser.tinymce.core.html.SanitizationTest', () => { context('Sanitize html', () => { - const isSafari = PlatformDetection.detect().browser.isSafari(); - const testHtmlSanitizer = (testCase: { input: string; expected: string; mimeType: MimeType; sanitize?: boolean }) => { const sanitizer = getSanitizer({ sanitize: testCase.sanitize ?? true }, Schema()); @@ -22,14 +19,14 @@ describe('browser.tinymce.core.html.SanitizationTest', () => { it('Sanitize iframe HTML', () => testHtmlSanitizer({ input: '<iframe src="x"><script>alert(1)</script></iframe><iframe src="javascript:alert(1)"></iframe>', // Safari seems to encode the contents of iframes - expected: isSafari ? '<iframe src="x">&lt;script&gt;alert(1)&lt;/script&gt;</iframe><iframe></iframe>' : '<iframe></iframe>', + expected: '<iframe></iframe>', mimeType: 'text/html' })); it('Disabled sanitization of iframe HTML', () => testHtmlSanitizer({ input: '<iframe src="x"><script>alert(1)</script></iframe><iframe src="javascript:alert(1)"></iframe>', // Safari seems to encode the contents of iframes - expected: isSafari ? '<iframe src="x">&lt;script&gt;alert(1)&lt;/script&gt;</iframe><iframe></iframe>' : '<iframe src="x"><script>alert(1)</script></iframe><iframe></iframe>', + expected: '<iframe src="x"><script>alert(1)</script></iframe><iframe></iframe>', mimeType: 'text/html', sanitize: false })); diff --git a/modules/tinymce/src/core/test/ts/webdriver/keyboard/SpaceKeyTest.ts b/modules/tinymce/src/core/test/ts/webdriver/keyboard/SpaceKeyTest.ts index 5f533c61e6c..9ea113c946a 100644 --- a/modules/tinymce/src/core/test/ts/webdriver/keyboard/SpaceKeyTest.ts +++ b/modules/tinymce/src/core/test/ts/webdriver/keyboard/SpaceKeyTest.ts @@ -22,7 +22,8 @@ describe('webdriver.tinymce.core.keyboard.SpaceKeyTest', () => { }); context('Space key around inline boundary elements', () => { - it('TINY-8588: Add one space just before a block', async () => { + // TINY-10742: Skipping until unexpected <br> tag being added in Firefox is addressed. + it.skip('TINY-8588: Add one space just before a block', async () => { const editor = hook.editor(); editor.setContent('<p>s<span style="display: block;" contenteditable="false">a</span></p>'); TinySelections.setCursor(editor, [ 0, 0 ], 1); @@ -30,7 +31,8 @@ describe('webdriver.tinymce.core.keyboard.SpaceKeyTest', () => { TinyAssertions.assertContent(editor, '<p>s&nbsp;<span style="display: block;" contenteditable="false">a</span></p>'); }); - it('TINY-8588: Add two spaces just before a block', async () => { + // TINY-10742: Skipping until unexpected <br> tag being added in Firefox is addressed. + it.skip('TINY-8588: Add two spaces just before a block', async () => { const editor = hook.editor(); editor.setContent('<p>s<span style="display: block;" contenteditable="false">a</span></p>'); TinySelections.setCursor(editor, [ 0, 0 ], 1); @@ -45,7 +47,8 @@ describe('webdriver.tinymce.core.keyboard.SpaceKeyTest', () => { } }); - it('TINY-8588: Add one space before a block while in a span', async () => { + // TINY-10742: Skipping until unexpected <br> tag being added in Firefox is addressed. + it.skip('TINY-8588: Add one space before a block while in a span', async () => { const editor = hook.editor(); editor.setContent('<p><span class="filler">s</span><span style="display: block;" contenteditable="false">a</span></p>'); TinySelections.setCursor(editor, [ 0, 0, 0 ], 1); @@ -53,7 +56,8 @@ describe('webdriver.tinymce.core.keyboard.SpaceKeyTest', () => { TinyAssertions.assertContent(editor, '<p><span class="filler">s&nbsp;</span><span style="display: block;" contenteditable="false">a</span></p>'); }); - it('TINY-8588: Add one space before a block inside a strong', async () => { + // TINY-10742: Skipping until unexpected <br> tag being added in Firefox is addressed. + it.skip('TINY-8588: Add one space before a block inside a strong', async () => { const editor = hook.editor(); editor.setContent('<p>s<strong><span contenteditable="false" style="display: block;">a</span></strong></p>'); TinySelections.setCursor(editor, [ 0, 0 ], 1); diff --git a/modules/tinymce/src/plugins/accordion/test/ts/webdriver/AccordionBackspaceDeleteTest.ts b/modules/tinymce/src/plugins/accordion/test/ts/webdriver/AccordionBackspaceDeleteTest.ts index eff45eb2397..4434a38234d 100644 --- a/modules/tinymce/src/plugins/accordion/test/ts/webdriver/AccordionBackspaceDeleteTest.ts +++ b/modules/tinymce/src/plugins/accordion/test/ts/webdriver/AccordionBackspaceDeleteTest.ts @@ -31,11 +31,10 @@ describe('webdriver.tinymce.plugins.accordion.AccordionBackspaceDeleteTest', () const hook = TinyHooks.bddSetup<Editor>(settings, [ AccordionPlugin ], true); const platform = PlatformDetection.detect(); - const os = platform.os; - const isSafari = platform.browser.isSafari(); const isFirefox = platform.browser.isFirefox(); - const isMacOS = os.isMacOS(); - const isWindows = os.isWindows(); + const isSafari = platform.browser.isSafari(); + const isMacOS = platform.os.isMacOS(); + const isWindows = platform.os.isWindows(); const pDoBackspaceDelete = async (key: DeletionKey, modifier?: BackspaceDeleteModifier): Promise<void> => { await RealKeys.pSendKeysOn('iframe => body', [ Type.isUndefined(modifier) ? RealKeys.text(key) : RealKeys.combo(modifier, key) ]); @@ -246,8 +245,8 @@ describe('webdriver.tinymce.plugins.accordion.AccordionBackspaceDeleteTest', () TinySelections.setCursor(editor, [ 0, 1, 0 ], 0); await pDoDelete(); assertAccordionContent(editor, { summary: 'summary', body: '<p>ody</p>' }); - // TODO: Investigate why the path is different here on Firefox and Safari - TinyAssertions.assertCursor(editor, isFirefox || isSafari ? [ 0, 1, 0 ] : [ 0, 1, 0, 0 ], 0); + // TODO: Investigate why the path is different here on Firefox + TinyAssertions.assertCursor(editor, isFirefox ? [ 0, 1, 0 ] : [ 0, 1, 0, 0 ], 0); }); it('TINY-9951: Deleting content in body by pressing DELETE should work as expected if caret in middle of body content', async () => { @@ -410,19 +409,20 @@ describe('webdriver.tinymce.plugins.accordion.AccordionBackspaceDeleteTest', () } assertAccordionContent(editor, getSummarySpec(expectedContent)); - // TINY-9302: Extra format caret added when using keyboard shortcut ranged deletion, except on Safari - // due to TINY-9951 workaround - let expectedPath: number[]; - let expectedOffset: number; if (isSafari) { - expectedPath = isSummary ? [ 0, 0, 0 ] : [ 0, 1, 0, 0 ]; - expectedOffset = isBackspace ? 'word1 '.length : 'wo'.length; + // Safari positions selection around format caret + const expectedPath = isSummary ? [ 0, 0, 0 ] : [ 0, 1, 0, 0 ]; + const expectedOffset = isBackspace ? 6 : 2; + + TinyAssertions.assertCursor(editor, expectedPath, expectedOffset); } else { - expectedPath = isSummary ? [ 0, 0, 1, 0 ] : [ 0, 1, 0, 1, 0 ]; // 0 offset as selection positioned within format caret - expectedOffset = 0; + const expectedPath = isSummary ? [ 0, 0, 1, 0 ] : [ 0, 1, 0, 1, 0 ]; + const expectedOffset = 0; + + TinyAssertions.assertCursor(editor, expectedPath, expectedOffset); } - TinyAssertions.assertCursor(editor, expectedPath, expectedOffset); + }; const testCtrlDeletionInSummary = (deletionKey: DeletionKey) => testCtrlDeletion(deletionKey, 'summary'); diff --git a/modules/tinymce/src/plugins/nonbreaking/test/ts/webdriver/NonbreakingTypingTest.ts b/modules/tinymce/src/plugins/nonbreaking/test/ts/webdriver/NonbreakingTypingTest.ts index b33e864a7ba..6df80cd1535 100644 --- a/modules/tinymce/src/plugins/nonbreaking/test/ts/webdriver/NonbreakingTypingTest.ts +++ b/modules/tinymce/src/plugins/nonbreaking/test/ts/webdriver/NonbreakingTypingTest.ts @@ -25,10 +25,11 @@ describe('webdriver.tinymce.plugins.nonbreaking.NonbreakingTypingTest', () => { editor.setContent(''); }); - it('TBA: Click on the nbsp button then type some text, and assert content is correct', async () => { + // TINY-10737: Investigate these failures on Safari + it.skip('TBA: Click on the nbsp button then type some text, and assert content is correct', async () => { const editor = hook.editor(); clickNbspToolbarButton(editor); - await RealKeys.pSendKeysOn('iframe => body => p', [ RealKeys.text('test') ]); + await RealKeys.pSendKeysOn('iframe => body', [ RealKeys.text('test') ]); TinyAssertions.assertContentStructure(editor, ApproxStructure.build((s, str) => { return s.element('body', { children: [ @@ -60,12 +61,13 @@ describe('webdriver.tinymce.plugins.nonbreaking.NonbreakingTypingTest', () => { })); }); - it('TBA: Add content to editor, click on the nbsp button then type some text, and assert content is correct', async () => { + // TINY-10737: Investigate these failures on Safari + it.skip('TBA: Add content to editor, click on the nbsp button then type some text, and assert content is correct', async () => { const editor = hook.editor(); editor.setContent('test'); TinySelections.setCursor(editor, [ 0, 0 ], 4); clickNbspToolbarButton(editor); - await RealKeys.pSendKeysOn('iframe => body => p', [ RealKeys.text('test') ]); + await RealKeys.pSendKeysOn('iframe => body', [ RealKeys.text('test') ]); TinyAssertions.assertContentStructure(editor, ApproxStructure.build((s, str) => { return s.element('body', { children: [ @@ -82,7 +84,7 @@ describe('webdriver.tinymce.plugins.nonbreaking.NonbreakingTypingTest', () => { it('TBA: Click on the nbsp button then type a space, and assert content is correct', async () => { const editor = hook.editor(); clickNbspToolbarButton(editor); - await RealKeys.pSendKeysOn('iframe => body => p', [ RealKeys.text(' ') ]); + await RealKeys.pSendKeysOn('iframe => body', [ RealKeys.text(' ') ]); TinyAssertions.assertContentStructure(editor, ApproxStructure.build((s, str) => { return s.element('body', { children: [ @@ -96,12 +98,13 @@ describe('webdriver.tinymce.plugins.nonbreaking.NonbreakingTypingTest', () => { })); }); - it('TBA: Add text to editor, click on the nbsp button and add content plus a space, and assert content is correct', async () => { + // TINY-10737: Investigate these failures on Safari + it.skip('TBA: Add text to editor, click on the nbsp button and add content plus a space, and assert content is correct', async () => { const editor = hook.editor(); editor.setContent('test'); TinySelections.setCursor(editor, [ 0, 0 ], 4); clickNbspToolbarButton(editor); - await RealKeys.pSendKeysOn('iframe => body => p', [ RealKeys.text('test ') ]); + await RealKeys.pSendKeysOn('iframe => body', [ RealKeys.text('test ') ]); TinyAssertions.assertContentStructure(editor, ApproxStructure.build((s, str) => { return s.element('body', { children: [ diff --git a/modules/tinymce/src/plugins/nonbreaking/test/ts/webdriver/NonbreakingWrapTypingTest.ts b/modules/tinymce/src/plugins/nonbreaking/test/ts/webdriver/NonbreakingWrapTypingTest.ts index 4737a435b06..2d0285d47ac 100644 --- a/modules/tinymce/src/plugins/nonbreaking/test/ts/webdriver/NonbreakingWrapTypingTest.ts +++ b/modules/tinymce/src/plugins/nonbreaking/test/ts/webdriver/NonbreakingWrapTypingTest.ts @@ -25,10 +25,11 @@ describe('webdriver.tinymce.plugins.nonbreaking.NonbreakingWrapTypingTest', () = editor.setContent(''); }); - it('TINY-3647: Click on the nbsp button then type some text, and assert content is correct', async () => { + // TINY-10737: Investigate these failures on Safari + it.skip('TINY-3647: Click on the nbsp button then type some text, and assert content is correct', async () => { const editor = hook.editor(); clickNbspToolbarButton(editor); - await RealKeys.pSendKeysOn('iframe => body => p', [ RealKeys.text('test') ]); + await RealKeys.pSendKeysOn('iframe => body', [ RealKeys.text('test') ]); TinyAssertions.assertContentStructure(editor, ApproxStructure.build((s, str, arr) => s.element('body', { children: [ s.element('p', { @@ -69,12 +70,13 @@ describe('webdriver.tinymce.plugins.nonbreaking.NonbreakingWrapTypingTest', () = }))); }); - it('TINY-3647: Add content to editor, click on the nbsp button then type some text, and assert content is correct', async () => { + // TINY-10737: Investigate these failures on Safari + it.skip('TINY-3647: Add content to editor, click on the nbsp button then type some text, and assert content is correct', async () => { const editor = hook.editor(); editor.setContent('test'); TinySelections.setCursor(editor, [ 0, 0 ], 4); clickNbspToolbarButton(editor); - await RealKeys.pSendKeysOn('iframe => body => p', [ RealKeys.text('test') ]); + await RealKeys.pSendKeysOn('iframe => body', [ RealKeys.text('test') ]); TinyAssertions.assertContentStructure(editor, ApproxStructure.build((s, str, arr) => s.element('body', { children: [ s.element('p', { @@ -96,7 +98,7 @@ describe('webdriver.tinymce.plugins.nonbreaking.NonbreakingWrapTypingTest', () = it('TINY-3647: Click on the nbsp button then type a space, and assert content is correct', async () => { const editor = hook.editor(); clickNbspToolbarButton(editor); - await RealKeys.pSendKeysOn('iframe => body => p', [ RealKeys.text(' ') ]); + await RealKeys.pSendKeysOn('iframe => body', [ RealKeys.text(' ') ]); TinyAssertions.assertContentStructure(editor, ApproxStructure.build((s, str, arr) => s.element('body', { children: [ s.element('p', { @@ -114,7 +116,8 @@ describe('webdriver.tinymce.plugins.nonbreaking.NonbreakingWrapTypingTest', () = }))); }); - it('TINY-3647: Add text to editor, click on the nbsp button and add content plus a space, and assert content is correct', async () => { + // TINY-10737: Investigate these failures on Safari + it.skip('TINY-3647: Add text to editor, click on the nbsp button and add content plus a space, and assert content is correct', async () => { const editor = hook.editor(); editor.setContent('test'); TinySelections.setCursor(editor, [ 0, 0 ], 4); @@ -136,7 +139,7 @@ describe('webdriver.tinymce.plugins.nonbreaking.NonbreakingWrapTypingTest', () = ] }))); - await RealKeys.pSendKeysOn('iframe => body => p', [ RealKeys.text('test ') ]); + await RealKeys.pSendKeysOn('iframe => body', [ RealKeys.text('test ') ]); TinyAssertions.assertContentStructure(editor, ApproxStructure.build((s, str, arr) => s.element('body', { children: [ s.element('p', { @@ -155,7 +158,8 @@ describe('webdriver.tinymce.plugins.nonbreaking.NonbreakingWrapTypingTest', () = }))); }); - it('TINY-3647: Add text to editor, click on the nbsp button and add content plus a space, repeat, and assert content is correct', async () => { + // TINY-10737: Investigate these failures on Safari + it.skip('TINY-3647: Add text to editor, click on the nbsp button and add content plus a space, repeat, and assert content is correct', async () => { const editor = hook.editor(); editor.setContent('test'); TinySelections.setCursor(editor, [ 0, 0 ], 4); @@ -177,7 +181,7 @@ describe('webdriver.tinymce.plugins.nonbreaking.NonbreakingWrapTypingTest', () = ] }))); - await RealKeys.pSendKeysOn('iframe => body => p', [ RealKeys.text('test ') ]); + await RealKeys.pSendKeysOn('iframe => body', [ RealKeys.text('test ') ]); TinyAssertions.assertContentStructure(editor, ApproxStructure.build((s, str, arr) => s.element('body', { children: [ s.element('p', { @@ -195,7 +199,7 @@ describe('webdriver.tinymce.plugins.nonbreaking.NonbreakingWrapTypingTest', () = ] }))); - await RealKeys.pSendKeysOn('iframe => body => p', [ RealKeys.text('test ') ]); + await RealKeys.pSendKeysOn('iframe => body', [ RealKeys.text('test ') ]); TinyAssertions.assertContentStructure(editor, ApproxStructure.build((s, str, arr) => s.element('body', { children: [ s.element('p', { From 2123e275ac28089e6816918e09fa5a430fd59e83 Mon Sep 17 00:00:00 2001 From: spocke <spocke@moxiecode.com> Date: Tue, 12 Mar 2024 00:22:10 +0100 Subject: [PATCH 13/15] TINY-10754: Updated the license message (#9477) --- modules/tinymce/src/core/main/ts/init/LicenseKeyValidation.ts | 2 +- .../src/core/test/ts/browser/init/LicenseKeyValidationTest.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/tinymce/src/core/main/ts/init/LicenseKeyValidation.ts b/modules/tinymce/src/core/main/ts/init/LicenseKeyValidation.ts index 7c994592e0b..267bc0d72c7 100644 --- a/modules/tinymce/src/core/main/ts/init/LicenseKeyValidation.ts +++ b/modules/tinymce/src/core/main/ts/init/LicenseKeyValidation.ts @@ -16,6 +16,6 @@ export const validateEditorLicenseKey = (editor: Editor): void => { const hasApiKey = Type.isString(Options.getApiKey(editor)); if (!hasApiKey && (Type.isUndefined(licenseKey) || validateLicenseKey(licenseKey) === 'INVALID')) { // eslint-disable-next-line no-console - console.warn('You are running TinyMCE in evaluation mode. Provide a valid license key or specify the license to \'GPL\' to agree to the open source license terms. https://www.tiny.cloud/'); + console.warn(`TinyMCE is running in evaluation mode. Provide a valid license key or add license_key: 'gpl' to the init config to agree to the open source license terms. Read more at https://www.tiny.cloud/license-key/`); } }; diff --git a/modules/tinymce/src/core/test/ts/browser/init/LicenseKeyValidationTest.ts b/modules/tinymce/src/core/test/ts/browser/init/LicenseKeyValidationTest.ts index af1f690ed79..9ec68638c90 100644 --- a/modules/tinymce/src/core/test/ts/browser/init/LicenseKeyValidationTest.ts +++ b/modules/tinymce/src/core/test/ts/browser/init/LicenseKeyValidationTest.ts @@ -10,7 +10,7 @@ import * as LicenseKeyValidation from 'tinymce/core/init/LicenseKeyValidation'; describe('browser.tinymce.core.init.LicenseKeyValidationTest', () => { let oldWarn: typeof console.warn; let messages: string[] = []; - const expectedLogMessage = 'You are running TinyMCE in evaluation mode. Provide a valid license key or specify the license to \'GPL\' to agree to the open source license terms. https://www.tiny.cloud/'; + const expectedLogMessage = `TinyMCE is running in evaluation mode. Provide a valid license key or add license_key: 'gpl' to the init config to agree to the open source license terms. Read more at https://www.tiny.cloud/license-key/`; const invalidGeneratedKeyToShort = Arr.range(63, Fun.constant('x')).join(''); const invalidGeneratedKeyToLong = Arr.range(512, Fun.constant('x')).join(''); const validGeneratedKey = Arr.range(67, Fun.constant('x')).join(''); From dde5967541629e390c36095bcdbe1779cd072a8f Mon Sep 17 00:00:00 2001 From: Andrew Herron <thespyder@programmer.net> Date: Tue, 12 Mar 2024 10:24:26 +1100 Subject: [PATCH 14/15] TINY-10712: Update 7.0 changelog --- .changes/tinymce/7.0.0.md | 1 + .changes/unreleased/tinymce-TINY-10436-2024-02-27.yaml | 7 ------- 2 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 .changes/unreleased/tinymce-TINY-10436-2024-02-27.yaml diff --git a/.changes/tinymce/7.0.0.md b/.changes/tinymce/7.0.0.md index d95f5c963d1..443298704b8 100644 --- a/.changes/tinymce/7.0.0.md +++ b/.changes/tinymce/7.0.0.md @@ -39,6 +39,7 @@ - Updated deprecation/removed console message. #TINY-10694 ### Removed +- Removed `force_hex_color` option, with the default now being all colors are forced to HEX format and as lower case #TINY-10436 - Removed the deprecated `remove_trailing_brs` option from DomParser. #TINY-10454 - Removed `title` attribute for buttons with visible label. #TINY-10453 - Removed `InsertOrderedList` and `InsertUnorderedList` commands from core. #TINY-10644 diff --git a/.changes/unreleased/tinymce-TINY-10436-2024-02-27.yaml b/.changes/unreleased/tinymce-TINY-10436-2024-02-27.yaml deleted file mode 100644 index 5aa0baf2041..00000000000 --- a/.changes/unreleased/tinymce-TINY-10436-2024-02-27.yaml +++ /dev/null @@ -1,7 +0,0 @@ -project: tinymce -kind: Removed -body: Removed `force_hex_color` option, with the default now being all colors are forced - to HEX format and as lower case -time: 2024-02-27T16:23:33.051971748+11:00 -custom: - Issue: TINY-10436 From 07d1157533efdd406f019b3a74ab7f7377760903 Mon Sep 17 00:00:00 2001 From: Andrew Herron <thespyder@programmer.net> Date: Tue, 12 Mar 2024 10:24:42 +1100 Subject: [PATCH 15/15] TINY-10712: Temporary rollback of package.json --- modules/tinymce/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/tinymce/package.json b/modules/tinymce/package.json index 6d762e34d18..fcc0c639f6e 100644 --- a/modules/tinymce/package.json +++ b/modules/tinymce/package.json @@ -1,6 +1,6 @@ { "name": "tinymce", - "version": "7.1.0", + "version": "7.0.0", "private": true, "repository": { "type": "git",
a