TINY-6559: Now exit the blockquote when pressing enter twice (#7636)

This commit is contained in:
HAFRMO
2022-03-24 08:53:42 +01:00
committed by GitHub
parent e242dd9b55
commit 8614f8785e
6 changed files with 354 additions and 5 deletions

View File

@ -63,6 +63,9 @@ const bedrockHeadless = (tests, browser, auto) => {
name: 'headless-tests',
browser,
testfiles: testFolders(tests, auto),
// we have a few tests that don't play nicely when combined together in the monorepo
retries: 3
}
}
}

View File

@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
### Changed
- The `end_container_on_empty_block` option can now take a string of blocks to split when pressing Enter twice #TINY-6559
- The default value for `end_container_on_empty_block` option has been changed to `'blockquote'` #TINY-6559
### Fixed
- Dialogs will not exceed the window height on smaller screens #TINY-8146

View File

@ -89,7 +89,7 @@ interface BaseEditorOptions {
element_format?: 'xhtml' | 'html';
elementpath?: boolean;
encoding?: string;
end_container_on_empty_block?: boolean;
end_container_on_empty_block?: boolean | string;
entities?: string;
entity_encoding?: EntityEncoding;
extended_valid_elements?: string;

View File

@ -155,8 +155,16 @@ const register = (editor: Editor) => {
});
registerOption('end_container_on_empty_block', {
processor: 'boolean',
default: false
processor: (value) => {
if (Type.isBoolean(value)) {
return { valid: true, value };
} else if (Type.isString(value)) {
return { valid: true, value };
} else {
return { valid: false, message: 'Must be boolean or a string' };
}
},
default: 'blockquote'
});
registerOption('font_size_style_values', {

View File

@ -1,4 +1,4 @@
import { Arr, Obj, Optional, Optionals } from '@ephox/katamari';
import { Arr, Obj, Optional, Optionals, Type } from '@ephox/katamari';
import { Css, PredicateFilter, SugarElement, SugarNode } from '@ephox/sugar';
import DOMUtils from '../api/dom/DOMUtils';
@ -6,6 +6,7 @@ import DomTreeWalker from '../api/dom/TreeWalker';
import Editor from '../api/Editor';
import * as Options from '../api/Options';
import { EditorEvent } from '../api/util/EventDispatcher';
import Tools from '../api/util/Tools';
import * as Bookmarks from '../bookmark/Bookmarks';
import * as CaretContainer from '../caret/CaretContainer';
import * as NodeType from '../dom/NodeType';
@ -235,6 +236,17 @@ const addBrToBlockIfNeeded = (dom, block) => {
}
};
const shouldEndContainer = (editor: Editor, container: Node | undefined) => {
const optionValue = Options.shouldEndContainerOnEmptyBlock(editor);
if (Type.isNullable(container)) {
return false;
} else if (Type.isString(optionValue)) {
return Arr.contains(Tools.explode(optionValue), container.nodeName.toLowerCase());
} else {
return optionValue;
}
};
const insert = (editor: Editor, evt?: EditorEvent<KeyboardEvent>) => {
let tmpRng, container, offset, parentBlock;
let newBlock, fragment, containerBlock, parentBlockName, isAfterLastNodeInContainer;
@ -361,7 +373,7 @@ const insert = (editor: Editor, evt?: EditorEvent<KeyboardEvent>) => {
}
// Split the current container block element if enter is pressed inside an empty inner block element
if (Options.shouldEndContainerOnEmptyBlock(editor) && canSplitBlock(dom, containerBlock) && dom.isEmpty(parentBlock)) {
if (shouldEndContainer(editor, containerBlock) && canSplitBlock(dom, containerBlock) && dom.isEmpty(parentBlock)) {
// Split container block for example a BLOCKQUOTE at the current blockParent location for example a P
newBlock = dom.split(containerBlock, parentBlock);
} else {

View File

@ -162,4 +162,326 @@ describe('browser.tinymce.core.newline.InsertNewLineTest', () => {
TinyAssertions.assertContent(editor, '<p><a href="#">a</a></p><p><a href="#"><img src="about:blank"></a></p>');
TinyAssertions.assertSelection(editor, [ 1, 0 ], 0, [ 1, 0 ], 0);
});
context('end_container_on_empty_block', () => {
context('With the default value', () => {
it('TINY-6559: Press Enter in blockquote', () => {
const editor = hook.editor();
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>Line 2</p><p>&nbsp;</p></blockquote>');
TinyAssertions.assertSelection(editor, [ 0, 2 ], 0, [ 0, 2 ], 0);
});
it('TINY-6559: Press Shift+Enter in blockquote', () => {
const editor = hook.editor();
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { shiftKey: true });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>Line 2<br><br></p></blockquote>');
TinyAssertions.assertSelection(editor, [ 0, 1 ], 2, [ 0, 1 ], 2);
});
it('TINY-6559: Press Enter twice in blockquote', () => {
const editor = hook.editor();
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>Line 2</p></blockquote><p>&nbsp;</p>');
TinyAssertions.assertSelection(editor, [ 1 ], 0, [ 1 ], 0);
});
it('TINY-6559: Press Enter twice in blockquote while between two lines', () => {
const editor = hook.editor();
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 0 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p></blockquote><p>&nbsp;</p><blockquote><p>Line 2</p></blockquote>');
TinyAssertions.assertSelection(editor, [ 1 ], 0, [ 1 ], 0);
});
it('TINY-6559: Press Enter twice in a div', () => {
const editor = hook.editor();
editor.setContent('<div><p>Line 1</p><p>Line 2</p></div>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<div><p>Line 1</p><p>Line 2</p><p>&nbsp;</p><p>&nbsp;</p></div>');
TinyAssertions.assertSelection(editor, [ 0, 3 ], 0, [ 0, 3 ], 0);
});
it('TINY-6559: Press Enter twice in a section', () => {
const editor = hook.editor();
editor.setContent('<section><p>Line 1</p><p>Line 2</p></section>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<section><p>Line 1</p><p>Line 2</p><p>&nbsp;</p><p>&nbsp;</p></section>');
TinyAssertions.assertSelection(editor, [ 0, 3 ], 0, [ 0, 3 ], 0);
});
});
context('Is set to "div"', () => {
it('TINY-6559: Press Enter in blockquote', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', 'div');
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>Line 2</p><p>&nbsp;</p></blockquote>');
TinyAssertions.assertSelection(editor, [ 0, 2 ], 0, [ 0, 2 ], 0);
});
it('TINY-6559: Press Shift+Enter in blockquote', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', 'div');
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { shiftKey: true });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>Line 2<br><br></p></blockquote>');
TinyAssertions.assertSelection(editor, [ 0, 1 ], 2, [ 0, 1 ], 2);
});
it('TINY-6559: Press Enter twice in blockquote', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', 'div');
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>Line 2</p><p>&nbsp;</p><p>&nbsp;</p></blockquote>');
TinyAssertions.assertSelection(editor, [ 0, 3 ], 0, [ 0, 3 ], 0);
});
it('TINY-6559: Press Enter twice in blockquote while between two lines', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', 'div');
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 0 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>&nbsp;</p><p>&nbsp;</p><p>Line 2</p></blockquote>');
TinyAssertions.assertSelection(editor, [ 0, 2 ], 0, [ 0, 2 ], 0);
});
it('TINY-6559: Press Enter twice in a div', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', 'div');
editor.setContent('<div><p>Line 1</p><p>Line 2</p></div>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<div><p>Line 1</p><p>Line 2</p></div><p>&nbsp;</p>');
TinyAssertions.assertSelection(editor, [ 1 ], 0, [ 1 ], 0);
});
it('TINY-6559: Press Enter twice in a section', () => {
const editor = hook.editor();
editor.setContent('<section><p>Line 1</p><p>Line 2</p></section>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<section><p>Line 1</p><p>Line 2</p><p>&nbsp;</p><p>&nbsp;</p></section>');
TinyAssertions.assertSelection(editor, [ 0, 3 ], 0, [ 0, 3 ], 0);
});
});
context('Is set to "div,blockquote"', () => {
it('TINY-6559: Press Enter in blockquote', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', 'div,blockquote');
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>Line 2</p><p>&nbsp;</p></blockquote>');
TinyAssertions.assertSelection(editor, [ 0, 2 ], 0, [ 0, 2 ], 0);
});
it('TINY-6559: Press Shift+Enter in blockquote', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', 'div,blockquote');
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { shiftKey: true });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>Line 2<br><br></p></blockquote>');
TinyAssertions.assertSelection(editor, [ 0, 1 ], 2, [ 0, 1 ], 2);
});
it('TINY-6559: Press Enter twice in blockquote', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', 'div,blockquote');
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>Line 2</p></blockquote><p>&nbsp;</p>');
TinyAssertions.assertSelection(editor, [ 1 ], 0, [ 1 ], 0);
});
it('TINY-6559: Press Enter twice in blockquote while between two lines', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', 'div,blockquote');
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 0 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p></blockquote><p>&nbsp;</p><blockquote><p>Line 2</p></blockquote>');
TinyAssertions.assertSelection(editor, [ 1 ], 0, [ 1 ], 0);
});
it('TINY-6559: Press Enter twice in a div', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', 'div,blockquote');
editor.setContent('<div><p>Line 1</p><p>Line 2</p></div>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<div><p>Line 1</p><p>Line 2</p></div><p>&nbsp;</p>');
TinyAssertions.assertSelection(editor, [ 1 ], 0, [ 1 ], 0);
});
it('TINY-6559: Press Enter twice in a section', () => {
const editor = hook.editor();
editor.setContent('<section><p>Line 1</p><p>Line 2</p></section>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<section><p>Line 1</p><p>Line 2</p><p>&nbsp;</p><p>&nbsp;</p></section>');
TinyAssertions.assertSelection(editor, [ 0, 3 ], 0, [ 0, 3 ], 0);
});
});
context('Is set to true', () => {
it('TINY-6559: Press Enter in blockquote', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', true);
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>Line 2</p><p>&nbsp;</p></blockquote>');
TinyAssertions.assertSelection(editor, [ 0, 2 ], 0, [ 0, 2 ], 0);
});
it('TINY-6559: Press Shift+Enter in blockquote', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', true);
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { shiftKey: true });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>Line 2<br><br></p></blockquote>');
TinyAssertions.assertSelection(editor, [ 0, 1 ], 2, [ 0, 1 ], 2);
});
it('TINY-6559: Press Enter twice in blockquote', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', true);
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>Line 2</p></blockquote><p>&nbsp;</p>');
TinyAssertions.assertSelection(editor, [ 1 ], 0, [ 1 ], 0);
});
it('TINY-6559: Press Enter twice in blockquote while between two lines', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', true);
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 0 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p></blockquote><p>&nbsp;</p><blockquote><p>Line 2</p></blockquote>');
TinyAssertions.assertSelection(editor, [ 1 ], 0, [ 1 ], 0);
});
it('TINY-6559: Press Enter twice in a div', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', true);
editor.setContent('<div><p>Line 1</p><p>Line 2</p></div>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<div><p>Line 1</p><p>Line 2</p></div><p>&nbsp;</p>');
TinyAssertions.assertSelection(editor, [ 1 ], 0, [ 1 ], 0);
});
it('TINY-6559: Press Enter twice in a section', () => {
const editor = hook.editor();
editor.setContent('<section><p>Line 1</p><p>Line 2</p></section>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<section><p>Line 1</p><p>Line 2</p></section><p>&nbsp;</p>');
TinyAssertions.assertSelection(editor, [ 1 ], 0, [ 1 ], 0);
});
});
context('Is set to false', () => {
it('TINY-6559: Press Enter in blockquote', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', false);
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>Line 2</p><p>&nbsp;</p></blockquote>');
TinyAssertions.assertSelection(editor, [ 0, 2 ], 0, [ 0, 2 ], 0);
});
it('TINY-6559: Press Shift+Enter in blockquote', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', false);
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { shiftKey: true });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>Line 2<br><br></p></blockquote>');
TinyAssertions.assertSelection(editor, [ 0, 1 ], 2, [ 0, 1 ], 2);
});
it('TINY-6559: Press Enter twice in blockquote', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', false);
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>Line 2</p><p>&nbsp;</p><p>&nbsp;</p></blockquote>');
TinyAssertions.assertSelection(editor, [ 0, 3 ], 0, [ 0, 3 ], 0);
});
it('TINY-6559: Press Enter twice in blockquote while between two lines', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', false);
editor.setContent('<blockquote><p>Line 1</p><p>Line 2</p></blockquote>');
TinySelections.setCursor(editor, [ 0, 0 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<blockquote><p>Line 1</p><p>&nbsp;</p><p>&nbsp;</p><p>Line 2</p></blockquote>');
TinyAssertions.assertSelection(editor, [ 0, 2 ], 0, [ 0, 2 ], 0);
});
it('TINY-6559: Press Enter twice in a div', () => {
const editor = hook.editor();
editor.options.set('end_container_on_empty_block', false);
editor.setContent('<div><p>Line 1</p><p>Line 2</p></div>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<div><p>Line 1</p><p>Line 2</p><p>&nbsp;</p><p>&nbsp;</p></div>');
TinyAssertions.assertSelection(editor, [ 0, 3 ], 0, [ 0, 3 ], 0);
});
it('TINY-6559: Press Enter twice in a section', () => {
const editor = hook.editor();
editor.setContent('<section><p>Line 1</p><p>Line 2</p></section>');
TinySelections.setCursor(editor, [ 0, 1 ], 1);
insertNewline(editor, { });
insertNewline(editor, { });
TinyAssertions.assertContent(editor, '<section><p>Line 1</p><p>Line 2</p><p>&nbsp;</p><p>&nbsp;</p></section>');
TinyAssertions.assertSelection(editor, [ 0, 3 ], 0, [ 0, 3 ], 0);
});
});
});
});