-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Introduced mentions plugin #1932
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So far just a couple of docs related issues.
Most importantly we need better docs for config.mentions
option. There should be an abstract type like CKEDITOR.plugins.mentions.configDefinition
that would document config option.
Then config.mentions
should be set as a CKEDITOR.plugins.mentions.configDefinition[]
type. Also config
parameter of CKEDITOR.plugin.mentions
type should be marked as CKEDITOR.plugins.mentions.configDefinition
.
plugins/mentions/plugin.js
Outdated
'use strict'; | ||
|
||
( function() { | ||
var MARKER = '@', MIN_CHARS = 2, ENCODED_QUERY = '{encodedQuery}'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not define multiple vars in the same line.
plugins/mentions/plugin.js
Outdated
this.minChars = config.minChars !== null && config.minChars !== undefined ? config.minChars : MIN_CHARS; | ||
|
||
/** | ||
* {@link CKEDITOR.plugins.autocomplete Autocomplete} instance used by mentions feature to implement autocompletion logic. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a private property.
plugins/mentions/plugin.js
Outdated
* @since 4.10.0 | ||
* @constructor Creates the new instance of mentions and attaches it to the editor using {@link CKEDITOR.plugins.autocomplete Autocomplete feature}. | ||
* @param {CKEDITOR.editor} editor The editor to watch. | ||
* @param {Object} config Configuration object keeping information how to instantiate mentions plugin. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This parameter should use abstract type definition, for an example, it could be named CKEDITOR.plugins.mentions.configDefinition
.
plugins/mentions/plugin.js
Outdated
* A character that should trigger autocompletion. | ||
* @property {String} [marker='@'] | ||
*/ | ||
this.marker = config.marker || MARKER; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This property is not meant to be modified. Thus it should be marked as readonly.
plugins/mentions/plugin.js
Outdated
* A number of characters that should follow the marker character in order to trigger mentions feature. | ||
* @property {Number} [minChars=2] | ||
*/ | ||
this.minChars = config.minChars !== null && config.minChars !== undefined ? config.minChars : MIN_CHARS; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as this.marker
(readonly).
plugins/mentions/plugin.js
Outdated
|
||
/** | ||
* A character that should trigger autocompletion. | ||
* @property {String} [marker='@'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, leave consistently one line between property/method description and API doc tags section. This issue appears in other places too.
plugins/mentions/plugin.js
Outdated
this.marker = config.marker || MARKER; | ||
|
||
/** | ||
* A number of characters that should follow the marker character in order to trigger mentions feature. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"marker character" should be linked, so for instance {@link #marker marker character}
.
plugins/mentions/plugin.js
Outdated
* | ||
* @class CKEDITOR.plugins.mentions | ||
* @since 4.10.0 | ||
* @constructor Creates the new instance of mentions and attaches it to the editor using {@link CKEDITOR.plugins.autocomplete Autocomplete feature}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"using Autocomplete feature" is not needed here. It should be simply "to the editor.", period. The fact that it utilizes autocomplete under the hood is not important for docs reader at this level.
plugins/mentions/plugin.js
Outdated
getTextTestCallback( this.marker, this.minChars ), | ||
getDataCallback( feed, this.marker, this.caseSensitive ) ); | ||
|
||
template && this.changeViewTemplate( template ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not use x && y()
form. Use a regular if
s.
plugins/mentions/plugin.js
Outdated
}, | ||
|
||
/** | ||
* Changes the view template. The given template will be used by {@link CKEDITOR.template}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The given template will be used by {@link CKEDITOR.template}.
I don't think this has value. Focus on the purpose of method, rather on how something is done.
During the review I noticed a major requirement that is needed before deploying the feature:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have extracted issue related to caching to a separate issue so that it's easier to track.
There's also an issue with possible race condition. Also I noted multiple things related to docs. I want to stress that the docs are vital for this feature. Also it's about time we start to work on sdk sample and docs in paraler to this feature (ckeditor/ckeditor4-sdk#240).
The proposed solution is prone to response race conditions.
A scenario where server responses does not come in exact order, as they were issued, is pretty possible - wile easy to avoid. We should consider that too.
Imagine that the user opens CKE with "@ann" as a content and wants to type "@annaB" in order to use "Annabelle" suggestion.
- User starts typing, mentions plugin detects "@anna".
Server at this point sends "Anna", "Annabelle" response but client did not get it yet! Let's call it response A. - User presses "b" so there's "@annaB" (this is few ms after the previous step).
Server at this point sends "Annabelle" response but client did not get it yet! Let's call it response B. - User receives response B (note this server response is out of order!).
- User receives response A.
Expected
Mention plugin shows only "Annabelle" option.
Actual
Mention plugin shows both "Anna" and "Annabelle" options.
plugins/mentions/plugin.js
Outdated
/** | ||
* A character that should trigger autocompletion. | ||
* | ||
* @property {String} [marker='@'] marker |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
plugins/mentions/plugin.js
Outdated
} ); | ||
|
||
/** | ||
* Mentions plugin allows you to type custom marker character and get suggested values for the usernames so that you don't have to write it on your own. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for the usernames so that
This functionallity is not limited to user names. It could reference just anything.
plugins/mentions/plugin.js
Outdated
* Mentions plugin allows you to type custom marker character and get suggested values for the usernames so that you don't have to write it on your own. | ||
* | ||
* The recommended way to add mentions feature to an editor is by | ||
* using {@link CKEDITOR.config#mentions} configuration property or by passing it as the configuration option when instantiating an editor. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a better inner text would be config.mentions
also "configuration" word is redundant.
See how it looks currently:
(…) using CKEDITOR.config.mentions configuration property (…)
What I'm proposing is something more like
(…) using
config.mentions
property (…)
plugins/mentions/plugin.js
Outdated
* | ||
* ```javascript | ||
* // Simple usage with CKEDITOR.config.mentions property. | ||
* CKEDITOR.config.mentions = [ { feed: ['Anna', 'Thomas', 'John'], minChars: 0, marker: '#' } ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's skip marker
property customization here. minChars
is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also this is not an optimal way to change this configuration.
This code will most likely not work when the plugin is loaded dynamically.
Imagine you have website code like:
<script src="ckeditor/4.9.2/ckeditor.js"></script>
<script>
CKEDITOR.config.mentions = [ { feed: ['Anna', 'Thomas', 'John'], minChars: 0, marker: '#' } ];
CKEDITOR.replace( 'editable', {
extraPlugins: mentions
} );
</script>
Your config will get overridden. Why is that? Because plugin.js will get loaded asynchronously. Meaning that your default value will kick in after the value above was assigned.
Please update other places accordingly. I think in this case you need to refer to config.mentions = [ (…) ]
. In case of doubts contact our docs manager.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case shouldn't we remove default CKEDITOR.config.mentions = []
initialization so it won't overwrite user configuration?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, that's fine.
plugins/mentions/plugin.js
Outdated
* | ||
* // Passing mentions configuration when creating editor. | ||
* CKEDITOR.replace( 'editor', { | ||
* mentions: [ { feed: ['Anna', 'Thomas', 'John'], minChars: 0, marker: '#' } ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above:
Let's skip
marker
property customization here.minChars
is fine.
plugins/mentions/plugin.js
Outdated
|
||
callback = getDataCallbackWithMarkedItems( marker, callback ); | ||
|
||
// Feed is a simple array e.g. [ 'Anna', 'John', 'Thomas' ]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Blocks:
// Feed is a simple array e.g. [ 'Anna', 'John', 'Thomas' ].
// Feed is a URL to be requested for a JSON of matches e.g.
/user-controller/get-list/{encodedQuery}
.
// Feed is a function which uses callback to pass data through autocomplete plugin e.g.
Should be palced in feed
property API docs rather than here in the code.
plugins/mentions/plugin.js
Outdated
*/ | ||
|
||
/** | ||
* Feed of items to be displayed in mentions plugin. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This property is not properly documented. It's extremely important property, while this its entire doc:
You have placed a lot of it in mentions.configDefinition
type description. I feel that type definition should be very short and simple.
It make sense to add one listingbut that's about it. From there it should reference feed
property for further reading. I think it will be much better path.
plugins/mentions/plugin.js
Outdated
/** | ||
* Template used to render matches in the dropdown. | ||
* | ||
* @property {String} [template=CKEDITOR.plugins.autocomplete.view.itemTemplate] template |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What attributes does it (the template) take? At least code listing would be valuable here.
plugins/mentions/plugin.js
Outdated
var encodedQueryRegex = new RegExp( ENCODED_QUERY, 'g' ), | ||
encodedUrl = feed.replace( encodedQueryRegex, encodeURIComponent( query ) ); | ||
|
||
CKEDITOR.ajax.load( encodedUrl, function( data ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code doesn't handle response race conditions. I'll inlcude the full repro case in review summary.
plugins/mentions/plugin.js
Outdated
|
||
// Feed is a URL to be requested for a JSON of matches e.g. `/user-controller/get-list/{encodedQuery}`. | ||
else if ( typeof feed === 'string' ) { | ||
var encodedQueryRegex = new RegExp( ENCODED_QUERY, 'g' ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please reuse CKEDITOR.template
type for replacement logic.
The issue #1932 (review) has been handled inside |
Rebased into |
Rebased into |
7f26536
to
d143232
Compare
e8c25fa
to
b457315
Compare
I rebased this PR into the latest upstream. I also referenced #2101 issue. |
This reverts commit 2451cf6.
… not take an effect.
Added mentions items limit option
…f it consisted of more than 1 character. Also simplified unit tests a little.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests are running and failing on IE8.
|
||
1. Focus the editor. | ||
1. Type `@anna`. | ||
1. Press enter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to add a point to type a space, because without space, if you start to type @anna@anna
or anything else, text the text will not issue the request anyway.
|
||
## Expected | ||
|
||
History log doesn't contain duplicated URL requests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
URL requests - we should simplify it, as the tester does not see URLs but simply something like:
Request: ""
Request: "a"
Request: "an"
Request: "anna"
Request: "annaJ"
Request: "j"
Request: "joh"
Request: "john"
Let's refer to it just as request.
@@ -0,0 +1,10 @@ | |||
@bender-tags: mentions, feature, 4.10.0, 1703 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This manual test deserves to become a generic manual test (so that it gets tested during each future release).
To do that you need to remove feature feature
/bug
branch.
plugins/mentions/plugin.js
Outdated
* | ||
* ```javascript | ||
* // Simple usage with CKEDITOR.config.mentions property. | ||
* CKEDITOR.config.mentions = [ { feed: ['Anna', 'Thomas', 'John'], minChars: 0 } ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recommended way is to set it up by passing the config directly to the editor
instance, global config, although valid, is not a common method in CKE4. So I'd switch these two.
plugins/mentions/plugin.js
Outdated
return function( query, range, callback ) { | ||
// We are removing marker here to give clean query result for the endpoint callback. | ||
if ( mentions.marker ) { | ||
query = query.substring( 1 ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The length of a marker should be dynamically computed, so mentions.marker.length
instead of magic number 1
I have pushed a commit fixing most of the above issues, except IE8 thing. I don't see more issues than that so please correct it and we're good to go! 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, looks good 👌
What is the purpose of this pull request?
New feature
Does your PR contain necessary tests?
All patches which change the editor code must include tests. You can always read more
on PR testing,
how to set the testing environment and
how to create tests
in the official CKEditor documentation.
This PR contains
What changes did you make?
This PR continues work on #1703 plugin. See #1757 for more details.
Closes #1703, #2101