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

Introduced schema#setAttributeProperties() and schema#getAttributeProperties() methods #1711

Merged
merged 8 commits into from
Mar 29, 2019

Conversation

mlewand
Copy link
Contributor

@mlewand mlewand commented Mar 28, 2019

Suggested merge commit message (convention)

Feature: Introduced schema#setAttributeProperties() and schema#getAttributeProperties() methods. Closes ckeditor/ckeditor5#1659.


Followups

  • - implement it in our formatting plugins (Moving node to the same position is handled by differ as a change ckeditor5#4478)
    • - bold, italic, underline, strikethrough, code, subscript, superscript
    • - fontSize, fontFamily
    • - alignment
    • - highlight I'll actually start a discussion whether highlight should be considered formatting markup or not.
  • - integrate it with remove formatting plugin
  • - integrate it in CKE5 inspector

@mlewand mlewand requested a review from oleq March 28, 2019 14:47
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.

🔂 😛

* A map containing attribute's properties.
*
* @private
* @member {Map.<String,String>}
Copy link
Member

Choose a reason for hiding this comment

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

This is a plain object, not a map. So Object.<String,String>

*
* @returns {Object.<String,module:engine/model/schema~SchemaCompiledItemDefinition>}
*/
getDefinitions() {
Copy link
Member

Choose a reason for hiding this comment

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

Why this change? This method was here on purpose (next to getDefinition()).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As funny as it might sound I have grabbed one method too much where moving setAttributeProperties and getAttributeProperties. Thanks for catching that.

Restored to the original position.

@@ -475,6 +470,70 @@ export default class Schema {
}, { priority: 'high' } );
}

/**
* Registers custom properties to a given attribute.
Copy link
Member

Choose a reason for hiding this comment

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

Sets? Registering means saying "I exist!". We register nodes (Schema#register()). You can call register( foo ) only once too (cause you report your existence once).

Copy link
Member

Choose a reason for hiding this comment

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

Or rather:

Defines properties of the given attribute.

This method allows assigning additional information to model attributes. Currently, it is only used to mark formatting attributes (like bold, italic) which allows differentiating them from semantic attributes (such as src, listType, etc.). This knowledge is then used by features like "Remove format".

And that's it. Good documentation should back all big words by giving real-life examples.

Copy link
Member

Choose a reason for hiding this comment

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

I see you used "metadata" below. That's a nice word too. You may try to use it here too. It may be better than "information" or "properties".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The introduction was modified to shortly mention cases and link AttributeProperties#isFormatting example for further reading.

Unfortunately I could not link to isFormatting property directly due to ckeditor/ckeditor5-dev#504.

PTAL

* } );
*
* console.log( schema.getAttributeProperties( 'blockQuote' ) );
* // Logs: {one: 1, two: 2}
Copy link
Member

Choose a reason for hiding this comment

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

{ one: 1, two: 2 }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That was actually the output copied straight from the browser. I'll reformat this.

* isFormatting: false
* } );
*
* You can also use custom attributes:
Copy link
Member

Choose a reason for hiding this comment

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

custom properties

* You can also use custom attributes:
*
* schema.setAttributeProperties( 'blockQuote', {
* customAttribute: 'value'
Copy link
Member

Choose a reason for hiding this comment

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

customProperty

*
* It can be used to mark the attributes relation and handle them in a common way.
*
* // Mark blockQuote as a formatting attribute.
Copy link
Member

Choose a reason for hiding this comment

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

blockQuote is not an attribute – it's an element

Let's use something realistic – bold, italic, fontFamily, etc.

}

/**
* Returns properties assigned to a given attribute.
Copy link
Member

Choose a reason for hiding this comment

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

Returns properties of the given attribute.

* See {@link module:engine/model/schema~Schema#setAttributeProperties `Schema#setAttributeProperties()`} for usage examples.
*
* @typedef {Object} module:engine/model/schema~AttributeProperties
* @property {Boolean} [isFormatting] Indicates that the attribute should be considered as a visual formatting.
Copy link
Member

Choose a reason for hiding this comment

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

Missing examples of what it means. Show what common attrs are considered "formatting" and which not.

Copy link
Member

@oleq oleq left a comment

Choose a reason for hiding this comment

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

Mostly changes in docs.

I also find the custom AttributeProperties data type confusing and it should be somehow resolved.

@@ -39,6 +39,14 @@ export default class Schema {
constructor() {
this._sourceDefinitions = {};

/**
* A map containing attribute's properties.
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
* A map containing attribute's properties.
* A map containing attribute properties.

* A map containing attribute's properties.
*
* @private
* @member {Map.<String,String>}
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
* @member {Map.<String,String>}
* @member {Object.<String,String>}

@@ -475,6 +470,70 @@ export default class Schema {
}, { priority: 'high' } );
}

/**
* Registers custom properties to a given attribute.
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
* Registers custom properties to a given attribute.
* Adds custom properties to an attribute.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was addressed by fix for one issues raised in previous review.

/**
* Registers custom properties to a given attribute.
*
* It can be used to mark the attributes relation and handle them in a common way.
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
* It can be used to mark the attributes relation and handle them in a common way.
* Properties allow categorization of model attributes. Thanks to that, certain groups of attributes can be recognized and handled in the same way by some of the editor features.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was addressed by fix for one issues raised in previous review.

* isFormatting: false
* } );
*
* You can also use custom attributes:
Copy link
Member

Choose a reason for hiding this comment

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

This is very confusing. We're talking about properties and all of the sudden there's this line about custom attributes of... attributes? This needs rewording. I guess the intention was that one can use any property name they want.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes it was a typo, should be custom properties.

* console.log( schema.getAttributeProperties( 'blockQuote' ) );
* // Logs: {one: 1, two: 2}
*
* @param {String} attributeName Name of the attribute to receive properties.
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
* @param {String} attributeName Name of the attribute to receive properties.
* @param {String} attributeName A name of the attribute to gain the properties.

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'm not sure about receive -> gain change. I semantically both words are very similar, while receive is used more commonly.

I'll keep receive - but ofc feel free to follow this up.

* // Logs: {one: 1, two: 2}
*
* @param {String} attributeName Name of the attribute to receive properties.
* @param {module:engine/model/schema~AttributeProperties} properties A dictionary of properties.
Copy link
Member

Choose a reason for hiding this comment

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

This is confusing. First, it is stated that

You can also use custom attributes:

Then we enforce a type, which clearly declares which properties are allowed.

* @param {module:engine/model/schema~AttributeProperties} properties A dictionary of properties.
*/
setAttributeProperties( attributeName, properties ) {
this._attributeProperties[ attributeName ] = Object.assign( this._attributeProperties[ attributeName ] || {}, properties );
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
this._attributeProperties[ attributeName ] = Object.assign( this._attributeProperties[ attributeName ] || {}, properties );
this._attributeProperties[ attributeName ] = Object.assign( this.getAttributeProperties( attributeName ) || {}, properties );

}

/**
* Returns properties assigned to a given attribute.
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 properties assigned to a given attribute.
* Returns properties associated with a given model attribute. See {@link #setAttributeProperties `setAttributeProperties()`}.

@@ -1285,6 +1344,15 @@ export class SchemaContext {
* @typedef {Object} module:engine/model/schema~SchemaContextItem
*/

/**
* A structure containing additional metadata describing the attribute.
Copy link
Member

Choose a reason for hiding this comment

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

As I wrote earlier, setAttributeProperties() allows any property names while this type clearly narrows possible options to isFormatting only. We should figure that out.

@coveralls
Copy link

coveralls commented Mar 28, 2019

Coverage Status

Coverage remained the same at 100.0% when pulling 4688a17 on t/ckeditor5/1659 into bd875c7 on master.

I accidentally moved it too while reordering Schema#setAttributeProperties() method.
…ributes than specified in the AttributeProperties typedef.
@mlewand
Copy link
Contributor Author

mlewand commented Mar 29, 2019

All the requested changes were addressed. There's one thing that requires some comments:

This is confusing. First, it is stated that

You can also use custom attributes:

Then we enforce a type, which clearly declares which properties are allowed.

This is interesting point @oleq and I can see how it can be an issue.

I can see two ways to resolve it:

  • Stick to a dedicated typedef and be explicit about the fact that it could be extended/patched (as basically everything in js world).
    • Pros:
      • Reduced DRY factor.
      • Allows for a more detailed property documentation.
    • Cons:
  • Describe the structure using inline object notation. (pushed an example to the t/ckeditor5/1659b branch)
    • Pros:
      • The method description is closer to (g/s)etAttributeProperties.
    • Cons:
      • I'm not even sure if our docs properly handle @returns tag with inline object. As it renders pretty 💩y.
      • Method API docs length increases, containing details that are not necessary to understand this method.

Taking above into consideration I'm strongly for going with a dedicated typedef, but explicitly say that it can be extended.

@mlewand mlewand requested a review from Reinmar March 29, 2019 08:15
@Reinmar
Copy link
Member

Reinmar commented Mar 29, 2019

Perfect! ❤️

@Reinmar Reinmar merged commit 1c6f83a into master Mar 29, 2019
@Reinmar Reinmar deleted the t/ckeditor5/1659 branch March 29, 2019 08:50
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.

Implement attribute properties
4 participants