Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Introduced Title plugin #130

Merged
merged 34 commits into from
Sep 5, 2019
Merged

Introduced Title plugin #130

merged 34 commits into from
Sep 5, 2019

Conversation

oskarwrobel
Copy link
Contributor

@oskarwrobel oskarwrobel commented Aug 28, 2019

Suggested merge commit message (convention)

Feature: Introduced Title plugin. Closes ckeditor/ckeditor5#2003. Closes ckeditor/ckeditor5#2005.


Additional information

For example – encountered issues, assumptions you had to make, other affected tickets, etc.

@oskarwrobel
Copy link
Contributor Author

oskarwrobel commented Aug 28, 2019

I'm wondering if we should disable heading command when selection is in the title element?

The document title is always represented as a <title /> element in the model. It's not possible to change it into the other block element (post-fixer will always fix such a change).

Is it possible to set some shema rules for that? Tell schema that title element cannot be renamed?

ckeditor/ckeditor5#2005

@pjasiun
Copy link

pjasiun commented Aug 29, 2019

Make sure that title integrates well with the placeholder support (https://ckeditor5.github.io/docs/nightly/ckeditor5/latest/features/editor-placeholder.html) I think that placeholder if defined should be the placeholder for the body element. If not defined you should use "Body" as a default option.

@jodator jodator self-assigned this Sep 2, 2019
@Mgsy
Copy link
Member

Mgsy commented Sep 2, 2019

I'm wondering if we should disable heading command when selection is in the title element?

I think it should be disabled. During testing, I noticed that heading dropdown is active and I tried to convert the title into a heading/paragraph, so for me it indicates that if it's active, I can do something with it.

@oskarwrobel
Copy link
Contributor Author

I think it should be disabled. During testing, I noticed that heading dropdown is active and I tried to convert the title into a heading/paragraph, so for me it indicates that if it's active, I can do something with it.

Yep, I'm working on it.

@oskarwrobel
Copy link
Contributor Author

Known issue ckeditor/ckeditor5#2010

@Mgsy
Copy link
Member

Mgsy commented Sep 2, 2019

Steps to reproduce

  1. Copy two block elements.
  2. Paste them at the beginning of the title.
  3. Undo.

Current result

The editor crashes.

Error

ckeditorerror.js:66 Uncaught CKEditorError: model-createPositionAt-offset-required: Model#createPositionAt() requires the offset when the first parameter is a model item. Read more: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/error-codes.html#error-model-createPositionAt-offset-required

    at Function._createAt (http://localhost:8125/ckeditor5-core/tests/manual/article.js:59326:11)
    at new Range (http://localhost:8125/ckeditor5-core/tests/manual/article.js:59526:66)
    at LiveRange._getTransformedByMove (http://localhost:8125/ckeditor5-core/tests/manual/article.js:60259:17)
    at LiveRange._getTransformedByMoveOperation (http://localhost:8125/ckeditor5-core/tests/manual/article.js:60041:15)
    at LiveRange.getTransformedByOperation (http://localhost:8125/ckeditor5-core/tests/manual/article.js:59935:17)
    at LiveRange.transform (http://localhost:8125/ckeditor5-core/tests/manual/article.js:51404:22)
    at Model.listenTo.priority (http://localhost:8125/ckeditor5-core/tests/manual/article.js:51392:14)
    at Model.fire (http://localhost:8125/ckeditor5-core/tests/manual/article.js:114391:29)
    at Model.<computed> [as applyOperation] (http://localhost:8125/ckeditor5-core/tests/manual/article.js:116520:16)
    at UndoCommand._undo (http://localhost:8125/ckeditor5-core/tests/manual/article.js:109329:11)

GIF

bug_cke5

@jodator
Copy link
Contributor

jodator commented Sep 2, 2019

@oskarwrobel - from my manual tests

  • should The Alignment feature be enabled in the title? (I do not have preference in that matter - looks like it's OK to have it).
  • the mention plugin gets invoked inside title (might be bug of a mention plugin)
    Peek 2019-09-02 18-24

Copy link
Contributor

@jodator jodator left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found some things to iron out - to not block you I'll R- now and will check the tests later.

src/title.js Outdated
} from '@ckeditor/ckeditor5-engine/src/view/placeholder';

// List of model elements that are allowed to be renamed to title element.
const allowedToBeTitle = new Set( [ 'heading1', 'heading2', 'heading3', 'paragraph' ] );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing heading4...6.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


## Keyboard navigation

Title plugin lets you navigate between title and body elements using <kbd>Tab</kbd> key and back, using <kbd>Shift</kbd> + <kbd>Tab</kbd>, providing form-like experience. You can also use <kbd>Enter</kbd> and <kbd>Backspace</kbd> keys to move caret between title and body.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't work like that if the body has content and selection is not at the start:
Peek 2019-09-02 18-37

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs should be more precise. Shift+Tab works only when selection is at the beginning of the "body" section.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add this explanation to the docs.

docs/features/title.md Show resolved Hide resolved
src/title.js Outdated

model.schema.addChildCheck( ( context, childDefinition ) => {
// Allow `title` element only directly inside a root.
if ( childDefinition.name === 'title' && !context.endsWith( '$root' ) ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be handled by: allowIn: '$root' in schema.register()?It bloats this check - it wis for two different items and the if below is already "big".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was afraid it won't disallow title element inside a blockQuote (because of inheritAllFrom: '$block'). Works fine after the change 👌

src/title.js Outdated
// Allow only `title-content` inside `title`.
if (
context.endsWith( 'title' ) && childDefinition.name !== 'title-content' ||
childDefinition.name === 'title-content' && !context.endsWith( 'title' )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this second check covered by schema definition allowIn?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've checked the tests with:

model.schema.addChildCheck( ( context, childDefinition ) => {
	// Allow only `title-content` inside `title`.
	if ( context.endsWith( 'title' ) && childDefinition.name !== 'title-content' ) {
		return false;
	}
} );

and only schema rules test fails so either we can simplify this or add more tests.

ps.: I didn't read the tests yet ;)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh.. I was wrong because of inheritAllFrom there. So Now I'm not sure if we shouldn't make this more specific in the first place? Either by inheriting only those required options or by manually defining the title and title-content with full schema.

It looks like more straight-forward then allowing all there and then adding callback to check only those allowed scenarios.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. I'll define title and title-content manually.

src/title.js Outdated
const view = editor.editing.view;
const viewRoot = view.document.getRoot();

const bodyPlaceholder = editor.config.get( 'placeholder' ) || 'Body';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll check this but I feel that we should make those strings ('Title' & 'Body') translate-able.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No doubts. I'll change it.

src/title.js Outdated
_getTitleElement() {
const root = this.editor.model.document.getRoot();

return Array.from( root.getChildren() ).find( element => element.is( 'title' ) );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will return undefined not null if element is not found in the array.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

src/title.js Outdated
* @returns {String} Title of the document.
*/
getTitle() {
const title = this.editor.model.document.getRoot().getChild( 0 ).getChild( 0 );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that we have a post-fixer but I would feel safer with using getTitleElement(), WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or OTOH - maybe add a comment about that post-fixer takes care of this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm..... I was thinking about using getTitleElement() but finally decided to do it as it is. getTitleElement() it's an additional call of Array.from and Array.find. As you wrote, post-fixer takes care of this structure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this.

const titleChildren = Array.from( title.getChildren() );
let hasChanged = false;

titleChildren.shift();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a comment about preserving of the first child? (I wonted to write firstborn 😆)

@@ -0,0 +1,28 @@
## Title feature

- you should see `Title` and `Body` placeholders when there is no text in any of sections.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- you should see `Title` and `Body` placeholders when there is no text in any of sections.
- you should see `Title` and `Body` placeholders when there is no text in any of the sections.

@oskarwrobel
Copy link
Contributor Author

oskarwrobel commented Sep 2, 2019

  • the mention plugin gets invoked inside title (might be bug of a mention plugin)

I think mention balloon should be not displayed in the text where mention attribute is disallowed.

@oskarwrobel
Copy link
Contributor Author

  • should The Alignment feature be enabled in the title? (I do not have preference in that matter - looks like it's OK to have it).

It's enabled now.

@oskarwrobel
Copy link
Contributor Author

oskarwrobel commented Sep 3, 2019

Steps to reproduce

  1. Copy two block elements.
  2. Paste them at the beginning of the title.
  3. Undo.

Current result

The editor crashes.

I fixed this scenario however this error is still reproducible.

  1. Copy 2 blocks (paragraph and list item).
  2. Paste them at the beginning of the title.
  3. Undo.

I hope I'm wrong but it can be a bug in OT.

[Edit]

I was debugging this for a while and I found the way to prevent this exception but this is something for the exorcist @scofalik ckeditor/ckeditor5#2022.

Copy link
Contributor

@jodator jodator left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've found that one case wasn't tested (defined). Als I would take a different approach in the post fixer as it si a quite big.

src/title.js Outdated Show resolved Hide resolved

## Keyboard navigation

Title plugin lets you navigate between title and body elements using <kbd>Tab</kbd> key and back, using <kbd>Shift</kbd> + <kbd>Tab</kbd>, providing form-like experience. You can also use <kbd>Enter</kbd> and <kbd>Backspace</kbd> keys to move caret between title and body.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add this explanation to the docs.

src/title.js Show resolved Hide resolved
src/title.js Outdated Show resolved Hide resolved
src/title.js Outdated Show resolved Hide resolved
src/title.js Outdated Show resolved Hide resolved
src/title.js Outdated Show resolved Hide resolved
src/title.js Outdated
const selection = model.document.selection;
const selectedElements = Array.from( selection.getSelectedBlocks() );

if ( selectedElements.length === 1 && selectedElements[ 0 ].name === 'title-content' ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

selectedElements[ 0 ].is( 'title-content' )

src/title.js Outdated Show resolved Hide resolved
src/title.js Show resolved Hide resolved
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Heading plugin should be disabled when selection in the title Title plugin
4 participants