Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#4469: Implemented the view RawElement #7621

Merged
merged 31 commits into from
Jul 22, 2020
Merged

Conversation

oleq
Copy link
Member

@oleq oleq commented Jul 14, 2020

Suggested merge commit message (convention)

Feature (engine): Implemented the view RawElement. Implemented the DowncastWriter#createRawElement() method. Closes #4469.

Fix (media-embed): The editor placeholder should disappear after inserting media into an empty editor. Closes #1684.

Docs (ckeditor5): Used the RawElement instead of UIElement in the "Using a React component in a block widget" guide (see #1684).

Internal (media-embed): Removed the getFillerOffset() hack from the createMediaFigureElement() helper that is no longer needed since the media content is rendered using RawElements (see #1684).

BREAKING CHANGE (engine): The DomConverter#getParentUIElement() method was renamed to DomConverter#getHostViewElement() because now it supports both UIElement and RawElement (see #4469).


Additional information

TBH the conversion (mapping) to a RawElement should be possible but I don't know where to write tests for it because I couldn't find similar tests for other view element types. Any ideas?

@oleq oleq requested a review from Reinmar July 14, 2020 07:53
@@ -887,7 +896,8 @@ export default class DomConverter {
*
* The following places are considered as incorrect for selection boundaries:
* * before or in the middle of the inline filler sequence,
* * inside the DOM element which represents {@link module:engine/view/uielement~UIElement a view ui element}.
* * inside the DOM element which represents {@link module:engine/view/uielement~UIElement a view UI element}.
* * inside the DOM element which represents {@link module:engine/view/rawelement~RawElement a view raw element}.
Copy link
Member

Choose a reason for hiding this comment

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

Something went wrong here.

Copy link
Member

@Reinmar Reinmar Jul 17, 2020

Choose a reason for hiding this comment

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

It renders as:

inside the DOM element which represents a view UI element. inside the DOM element which represents a view raw element

Duplicated "inside...". Should be joined with "and" or something.

* Custom render function can be provided as third parameter:
*
* writer.createRawElement( 'span', null, function( domDocument ) {
* const domElement = this.toDomElement( domDocument );
Copy link
Member

Choose a reason for hiding this comment

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

IMO, in the callback you should get the DOM element as in case of RawElement, unlike like in UIElement, you do not control the host element. It's being controlled by the view.

@@ -272,6 +273,36 @@ export default class DowncastWriter {
return uiElement;
}

/**
* Creates a new {@link module:engine/view/rawelement~RawElement}.
Copy link
Member

Choose a reason for hiding this comment

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

Does it make sense to create raw elements without their "internals" (passing the callback)?

Also, I'd focus on having here a good cross-ref between UIElement and RawElement, explaining also briefly what's the difference, etc. These API methods have a high chance of being visited and it's hard to figure out what it is based on this method.

Copy link
Member

Choose a reason for hiding this comment

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

What about this? I can see that the callback is still optional.

I'll remove the first two examples and leave the rest as is to make it less confusing.

Copy link
Member

Choose a reason for hiding this comment

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

I can see it's a copy-paste from UI element... But it makes more sense there as sometimes UIElements can be used without any content as their purpose is different.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, I remember now that you mentioned that it'd look bad if the last param wasn't optional since attrs are. So, that's fine. I'll just remove those examples.

* @error view-rawelement-cannot-add
*/
throw new CKEditorError(
'view-rawelement-cannot-add: Cannot add child nodes to RawElement instance.',
Copy link
Member

Choose a reason for hiding this comment

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

to a RawElement instance

_insertChild( index, nodes ) {
if ( nodes && ( nodes instanceof Node || Array.from( nodes ).length > 0 ) ) {
/**
* Cannot add children to a {@link module:engine/view/rawelement~RawElement}.
Copy link
Member

Choose a reason for hiding this comment

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

missing "instance" or remove "a" :D


expect( normalizeHtml( domRoot.innerHTML ) ).to.equal( normalizeHtml(
'<p>Foo<span><span id="id2"><b>RAW2</b></span></span> Bar</p>' ) );
} );
Copy link
Member

Choose a reason for hiding this comment

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

I'm missing a test of updating a raw element's attributes via the view.

@Reinmar
Copy link
Member

Reinmar commented Jul 16, 2020

I left a couple of comments. The two biggest things are:

  • The form of the raw element's render callback.
  • A missing test for using toWidget( rawElement ) and then whether e.g. the classes of this element are nicely updated when selection changes – as that's one of the things that wasn't possible before (you had to have a wrapper). Similar test can be written for the data pipeline – for checking that you can indeed implement something like "raw HTML" embedding Custom Html Widget #5566 (comment). These tests could land in the widget package as some integration tests, although the data pipeline test would not, in fact, be in any way related to widgets (as only the editing pipeline uses it).

1 similar comment
@Reinmar
Copy link
Member

Reinmar commented Jul 16, 2020

I left a couple of comments. The two biggest things are:

  • The form of the raw element's render callback.
  • A missing test for using toWidget( rawElement ) and then whether e.g. the classes of this element are nicely updated when selection changes – as that's one of the things that wasn't possible before (you had to have a wrapper). Similar test can be written for the data pipeline – for checking that you can indeed implement something like "raw HTML" embedding Custom Html Widget #5566 (comment). These tests could land in the widget package as some integration tests, although the data pipeline test would not, in fact, be in any way related to widgets (as only the editing pipeline uses it).

Copy link
Member

@Reinmar Reinmar left a comment

Choose a reason for hiding this comment

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

As commented.

@oleq oleq requested a review from Reinmar July 21, 2020 09:24
@Reinmar Reinmar merged commit bff38e3 into master Jul 22, 2020
@Reinmar Reinmar deleted the i/4469-view-raw-element branch July 22, 2020 20:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Introduce RawElement (aka ShadowElement) Placeholder does not disappear after inserting media
3 participants