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

StylesProcessor is no longer singleton #1826

Merged
merged 37 commits into from
Mar 3, 2020
Merged

StylesProcessor is no longer singleton #1826

merged 37 commits into from
Mar 3, 2020

Conversation

pomek
Copy link
Member

@pomek pomek commented Feb 20, 2020

Suggested merge commit message (convention)

Other: StylesProcessor rules will not be stored in a singleton, which made them shared between editor instances. In order to allow binding a styles processor instance to a specific view document, we had to replace a dynamic #document property in view nodes with a static one, set upon node creation. Closes ckeditor/ckeditor5#6091.

MAJOR BREAKING CHANGES: EditingController requires an instance of StylesProcessor in its constructor.

MAJOR BREAKING CHANGES: DataController requires an instance of StylesProcessor in its constructor.

MAJOR BREAKING CHANGES: DomConverter, HtmlDataProcessor and XmlDataProcessor require an instance of the view document in their constructors.

MAJOR BREAKING CHANGES: The View class requires an instance of StylesProcessor as its first argument.

MAJOR BREAKING CHANGES: The createViewElementFromHighlightDescriptor() function that is exported by src/conversion/downcasthelpers.js file requires an instance of the view document as its first argument.

MAJOR BREAKING CHANGES: Method view.Document#addStyleProcessorRules() has been moved to DataController class.

MINOR BREAKING CHANGES: DataController does not accept the data processor instance any more.

MAJOR BREAKING CHANGES: The #document getter was removed from model nodes. Only the root element holds the reference to the model document. For attached nodes, use node.root.document to access it.

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 think we're good to merge it now 👍

@coveralls
Copy link

coveralls commented Feb 26, 2020

Coverage Status

Coverage decreased (-15.7%) to 84.292% when pulling fb8e77a on i/6091 into 5fdb765 on master.

@Reinmar
Copy link
Member

Reinmar commented Feb 26, 2020

I think we're good to merge it now 👍

What happened to the CI? :D It's bloody red.

@jodator
Copy link
Contributor

jodator commented Feb 27, 2020

@Reinmar
Copy link
Member

Reinmar commented Feb 27, 2020

@Reinmar #monorepo: https://travis-ci.org/ckeditor/ckeditor5/builds/654456582?utm_source=github_status&utm_medium=notification

Why have I asked? :D

@Reinmar
Copy link
Member

Reinmar commented Feb 27, 2020

OK, some more changes are needed, unfortunately. This time much smaller, though. I missed the fact that we should keep the model and view APIs as similar as possible. The following changes will ensure that:

  • model Node:

    • Let's remove the #document getter. From what I can see, it's only used in the correct way on the root elements (e.g. position.root.document). On all other elements, since it can be null when the node is not attached, it's used for a single purpose – to check whether the node is attached. In other words – it's used in a non-idiomatic way.

      Note: to have it symmetrical with the view, where the #document is always available, we'd have to do huge changes in the model too, so that's why it's just easier to remove it for now (as it has no usefull applications here anyway).

    • Let's introduce an isAttached() method for checking whether node is in a tree rooted in an element of the root type. It'll be a shorthand to this.root.is( 'rootElement' ).

      Note: Make sure to document that a model node which was moved to the graveyard is still attached. Make sure to test it too.

  • model RootElement

    • Let's keep the #document here. As I mentioned above, it's used in many places and it makes sense there.
  • view Node:

    • Let's add isAttached() and make it work the same way it works in the model – check whether it's in a root which is a root: this.root.is( 'rootEditableElement' ).

    Note: nodes attached to a document fragment are not "attached". So "attached" means – attached to a document via one of its roots.

  • Finally, we need to review those places where #document was used before for some checks (one of these places is what @jodator found) and replace those with isAttached() (if that makes sense).

@pomek
Copy link
Member Author

pomek commented Feb 28, 2020

Done. Ready for review once again. New CI => https://travis-ci.org/ckeditor/ckeditor5/builds/656226522.

@@ -189,20 +189,12 @@ export default class Node {
}

/**
* {@link module:engine/model/document~Document Document} that owns this node or `null` if the node has no parent or is inside
* a {@link module:engine/model/documentfragment~DocumentFragment DocumentFragment}.
* Returns true if a node is in a tree rooted in an element of the root type.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* Returns true if a node is in a tree rooted in an element of the root type.
* Returns true if the node is in a tree rooted in the document
* (is a descendant of one of its roots).

src/view/node.js Outdated
@@ -109,19 +118,12 @@ export default class Node {
}

/**
* {@link module:engine/view/document~Document View document} that owns this node, or `null` if the node is inside
* {@link module:engine/view/documentfragment~DocumentFragment document fragment}.
* Returns true if a node is in a tree rooted in an element of the root type.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* Returns true if a node is in a tree rooted in an element of the root type.
* Returns true if the node is in a tree rooted in the document
* (is a descendant of one of its roots).


// The element was removed from document.
if ( !doc ) {
export function needsPlaceholder( elementOrDocumentFragment ) {
Copy link
Member

@Reinmar Reinmar Mar 2, 2020

Choose a reason for hiding this comment

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

Why these changes?

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 that we should use here isAttached() and that we don't need the type change.

* @param {module:engine/model/model~Model} model Data model.
* @param {module:engine/dataprocessor/dataprocessor~DataProcessor} [dataProcessor] Data processor that should be used
* by the controller.
*/
constructor( model, dataProcessor ) {
constructor( stylesProcessor, model, dataProcessor ) {
Copy link
Member

Choose a reason for hiding this comment

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

Why is this the first param? It should be the last one. It is the last one in the EditingController already.

Copy link
Member Author

Choose a reason for hiding this comment

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

Because dataProcessor is not required. Following the docs:

@param {module:engine/dataprocessor/dataprocessor~DataProcessor} [dataProcessor]

Copy link
Member Author

Choose a reason for hiding this comment

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

There is also a test that says the same.

Copy link
Member

Choose a reason for hiding this comment

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

Still, the model is required. So if anything, this should be the 2nd arg.

/**
* Adds a style processor normalization rules.
*
* The available style processors:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* The available style processors:
* You can implement your own rules as well as use one of the available processor rules:

/**
* Adds a style processor normalization rules.
*
* The available style processors:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* The available style processors:
* You can implement your own rules as well as use one of the available processor rules:

@@ -829,7 +829,9 @@ function isUnvisitedBlock( element, visited ) {

visited.add( element );

return element.document.model.schema.isBlock( element ) && element.parent;
const document = element.is( 'rootElement' ) ? element.document : element.root.document;
Copy link
Member

Choose a reason for hiding this comment

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

That's not necessary. element.root.document will always work, even if element is a root.

@@ -1807,7 +1810,7 @@ function breakTextNode( position ) {
position.parent._data = position.parent.data.slice( 0, position.offset );

// Insert new text node after position's parent text node.
position.parent.parent._insertChild( position.parent.index + 1, new Text( textToMove ) );
position.parent.parent._insertChild( position.parent.index + 1, new Text( position.parent.document, textToMove ) );
Copy link
Member

Choose a reason for hiding this comment

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

position.parent is slow. position.root will be much better here.

@Reinmar
Copy link
Member

Reinmar commented Mar 3, 2020

OK, I'm done reviewing this PR :) Now, need to check the other ones :O

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
4 participants