-
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
Added autocomplete throttle feature #2001
Conversation
Please rebase the branch onto latest upstream branch. |
Rebased into |
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, rebase the branch onto latest autocomplete branch. After dummy rebase, it yields errors in unit tests.
Rebased onto the latest |
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.
Not all occurences of consturctor calls were updated:
plugins/autocomplete/plugin.js
Outdated
|
||
/** | ||
* The editor instance to which autocomplete is attached to. | ||
* |
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.
Looks like a merge artifact 🙂
plugins/autocomplete/plugin.js
Outdated
*/ | ||
|
||
/** | ||
* Indicates throttle threshold mitigating text checks. |
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.
First, docs for this property should clearly express that these are milliseconds given here.
I think that the second part:
Higher levels of throttle (…)
Is not really necessarry, as one should understand this consequence based on information that this is throttling expressed in milliseconds.
plugins/autocomplete/plugin.js
Outdated
* Higher levels of throttle threshold will create visible delay for autocomplete view | ||
* but also save the number of {@link #dataCallback} calls. | ||
* | ||
* @property {Number} [throttle=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.
The default value for throttling should be greater than zero. Let's make it to a small value that is barely noticable. Let's make it 20ms so that gives us 50fps.
plugins/textwatcher/plugin.js
Outdated
@@ -261,6 +271,21 @@ | |||
} | |||
}; | |||
|
|||
function check( selectionRange ) { |
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.
Now that you moved it to a higher scope, this function name collides with other existing function in one scenario:
https://github.com/ckeditor/ckeditor-dev/blob/5a130a9/plugins/textwatcher/plugin.js#L202
Not a good thing, we want to avoid colliding functions. Move it instead to the closest scope where it is needed, so to the constructor where it is used and that will solve this problem.
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 name could be more meaningful. Since it mostly relates to calling a callback, I think that should be somehow reflected in the name.
|
||
## Expected | ||
|
||
1. After `@` character dropdown should contain multiple items and appear immediately. |
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 won't appear immediately if you focus the editor with a tab
key instead of mouse. That's because tab
keyup event will trigger the initial check (that is run synchronously) and your typed @
key will get throttled.
I suggest that the first step tells explicitly to focus the editor using mouse.
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'm aslo wondering whether we should put an information at the beginning asking to read expected section before starting the test, as the timing is crucial. What I mean here is that I can see someone spending 2.5 sec on performing first step, reading expected and performing 3-4. In this case result for typing "a" would appear (almost) instnatly.
|
||
Typed text should be logged: | ||
1. Immediately after first typed character. | ||
1. After 2000ms intervals. |
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.
Technically it should be something like not more often than once every 2000ms. Or something.
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 logging the time (including millisecs) would be very helpful for this test.
plugins/autocomplete/plugin.js
Outdated
* Simple usage: | ||
* | ||
* ```javascript | ||
* var definition = { dataCallback: dataCallback, textTestCallback: textTestCallback, throttle: 200 }; |
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.
Avoid putting objects in a single line. One property per line.
plugins/autocomplete/plugin.js
Outdated
* @param {String} [itemTemplate] Template for list item in dropdown. See {@link CKEDITOR.plugins.autocomplete.view#itemTemplate} for more information. | ||
* @param {String} [outputTemplate] Template for match rendering. See {@link #outputTemplate}. | ||
* @param {CKEDITOR.plugins.autocomplete.configDefinition} config Configuration object keeping information | ||
* how to instantiate autocomplete 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.
instantiate autocomplete plugin
It's not instantiating the plugin, it's more of a component. I'd just simpify it to "Configuration object for this autocomplete instance." or something alike.
plugins/autocomplete/plugin.js
Outdated
/** | ||
* See {@link CKEDITOR.plugins.autocomplete.configDefinition#throttle}. | ||
* | ||
* @property {Number} [throttle=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.
I'd avaoid duplicating the default value here. Keep it only within configDefinition#throttle
instead.
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 mean code:
config.throttle || 0;
Is a good defensive way of coding, and that's fine. My concern is only related to API docs.
@property {Number} [throttle=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.
Pushed some minor adjustments.
I just saw couple of minor issues in the recent code, and we're close to finish this issue.
plugins/autocomplete/plugin.js
Outdated
@@ -91,7 +91,10 @@ | |||
* } | |||
* | |||
* // Finally, instantiate the autocomplete class. | |||
* new CKEDITOR.plugins.autocomplete( editor, textTestCallback, dataCallback ); | |||
* new CKEDITOR.plugins.autocomplete( editor, { | |||
* textTestCallback: textTestCallback, |
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.
Mixed tab and spaces, this and following lines.
var counter = 0, | ||
counterInterval = 100, | ||
|
||
textWatcher = new CKEDITOR.plugins.textWatcher( editor, function( selectionRange ) { |
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.
Formatting is pretty bad here. First, this empty line between counterInterval
and textWatcher
is a little misleading, but a bigger problem is missing indentation after opening the function, and wrong braces indentation (closing the function).
logger.appendChild( matchEl ); | ||
|
||
if ( counter == 0 ) { | ||
setInterval( function() { |
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.
That's a bit overcomplicated solution… use simply performance.now()
and display a difference between last and current call.
However currently performance.now()
has an issue that it might be off by +/- 2 ms, see mdn for more details:
The timestamp is not actually high-resolution. To mitigate security threats such as Spectre, browsers currently round the result to varying degrees. (Firefox started rounding to 2 milliseconds in Firefox 59.) Some browsers may also slightly randomize the timestamp. The precision may improve again in future releases; browser developers are still investigating these timing attacks and how best to mitigate them.
In that case I propose to set throttling in the sample to 2002 ms, and issue description should still say that the calls should be no more often than 2000 ms.
Finally make sure to put a short comment (even simply to this comment) in the code, right above the 2002 threshold value.
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.
After doing that you'll be able to remove this fragment:
Other details Measured time by logger can have slight error +/- 100ms.
|
||
Typed text is logged immediately or in invalid interval times. | ||
|
||
***Other details*** Measured time by logger can have slight error +/- 100ms. |
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 record, use more common way to bold, which is simply double **
character.
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 fixed mentioned review issues, and rebased onto latest upstream branch (resolved one conflict during the rebase).
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?
Implemented throttle feature inside
textwatcher
/autocomplete
plugins. Refactoredautocomplete
constructor to useCKEDITOR.plugins.autocomplete.configDefinition
abstract class.Based on #1993 (PR #1996).
Closes #1997