-
Notifications
You must be signed in to change notification settings - Fork 15
Feature: Introduced PendingActions plugin. #127
Conversation
src/pendingactions.js
Outdated
*/ | ||
add( message ) { | ||
if ( typeof message !== 'string' ) { | ||
throw new CKEditorError( 'pendingactions-add-invalid-message: Message has to be a string.' ); |
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.
Missing docs for the pendingactions-add-invalid-message
error.
See
ckeditor5-core/src/plugincollection.js
Lines 186 to 197 in 7e7b950
/** | |
* Cannot load a plugin because one of its dependencies is listed in the `removePlugins` option. | |
* | |
* @error plugincollection-required | |
* @param {Function} plugin The required plugin. | |
* @param {Function} requiredBy The parent plugin. | |
*/ | |
throw new CKEditorError( | |
'plugincollection-required: Cannot load a plugin because one of its dependencies is listed in' + | |
'the `removePlugins` option.', | |
{ plugin: RequiredPluginConstructor, requiredBy: PluginConstructor } | |
); |
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.
AFAIK there is no need to add docs to the error when an additional explanation is not necessary.
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.
If you miss the @error
JSDoc tag, the error will not appear on the error codes page:
After adding:
+/**
+ * Some docs for the error.
+ *
+ * @error pendingactions-add-invalid-message
+ */
throw new CKEditorError( 'pendingactions-add-invalid-message: Message has to be a string.' );
the error appears:
One more thing. When I built the docs, I noticed that:
No errors found during the validation.
WARNING: The @type tag does not permit a description; the description will be ignored. File: pendingactions.js, line: 55
Should it be @member
instead of @type
?
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.
Ok, we have more errors without docs and probably we should fix them too. I'll add docs to this error. And I'll change @type
to @member
:) Thx.
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.
we have more errors without docs
Would be good to verify this and report as a new ticket.
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.
OTOH I still think that additional explanation for this error is not necessary because the error message is clear and we don't need to explain it in the docs. @pjasiun WDYT? Should we always add docs to error or only when error needs an additional explanation?
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.
You don't need to introduce any additional description. See here – https://github.com/ckeditor/ckeditor5-engine/blob/a721f95601511a6fcbb7d43becb957af64f2d157/src/view/attributeelement.js#L109-L117
We need the proper documentation for the error in docs, so
/**
* Message has to be a string.
*
* @error pendingactions-add-invalid-message
*/
is enough.
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.
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.
Ok, I checked and each new type of error needs docs. When the error is repeated then docs is not necessary.
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.
Done.
src/pendingactions.js
Outdated
throw new CKEditorError( 'pendingactions-add-invalid-message: Message has to be a string.' ); | ||
} | ||
|
||
const observable = Object.create( ObservableMixin ); |
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 variable should be called action
, instead of observable
.
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.
Done.
src/pendingactions.js
Outdated
/* istanbul ignore next */ | ||
this._domEmitter.listenTo( window, 'beforeunload', ( evtInfo, domEvt ) => { | ||
if ( this.isPending ) { | ||
domEvt.returnValue = this._actions.get( 0 ).message; |
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.
Since getting the first action looks like a common case, maybe we should have: this.get
, which will do this._actions.get
or the property first
?
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.
More I think about it, more I feel that the plugin should have Collection
API. Not everybody feels comfortable with iterators (even you used _actions.get( 0 )
, it is more convenient). So as much as I love iterator, I think that get
and length
should be also provided.
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 f2f talk we decided to add getter first
for getting first pending action from the list.
tests/manual/pendingactions.js
Outdated
.then( () => wait( 500 ) ) | ||
.then( () => ( action.message = 'Dynamic pending action 80%.' ) ) | ||
.then( () => wait( 500 ) ) | ||
.then( () => ( action.message = 'Dynamic pending action 1000%.' ) ) |
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.
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.
Done.
tests/manual/pendingactions.js
Outdated
const action = pendingActions.add( 'Static pending action.' ); | ||
|
||
wait( 5000 ).then( () => pendingActions.remove( action ) ); | ||
} ); |
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 we need these "static pending actions"? Can't we have only one type of actions in this manual tests (dynamic)? More buttons in manual tests mean more things to click, to test, more code to maintain. If "dynamic" pending actions cover all cases lets make it simple.
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.
Done.
src/pendingactions.js
Outdated
/** | ||
* Adds action to the list of pending actions. | ||
* | ||
* Methods returns an object with observable message property. Message can be changed. |
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 method returns an action object with observable message property. The action object can be later used in the remove method. It also allows you to change the message.
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, it would be useful to put an example here.
src/pendingactions.js
Outdated
/** | ||
* List of editor pending actions. | ||
* | ||
* Any asynchronous action that should be finished before the editor destroy (like file upload) should be registered |
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.
should be finished before the editor destroy
This plugin has nothing to do with editing destroy. It is to handle long-lasting actions. To synchronise plugins which execute such action (i.e. file upload) and the editor integration. It gives a developer, who integrates the editor, an easy way to check if there are any pending action whenever such information is needed. All plugins, which register pending action provides also a message what action is ongoing which can be displayed to a user and let him decide if he wants to interrupt the action or wait. This plugin is not able to interrupt actions or manage that in any other way.
src/pendingactions.js
Outdated
if ( this.isPending ) { | ||
domEvt.returnValue = this.first.message; | ||
} | ||
} ); |
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.
We talked with @Reinmar and agreed that this logic is not needed with no autosave plugin so we should move it there. If one does not use autosave plugins, he also does not care about closing browser with pending action. Content is not saved anyway.
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.
Done.
src/pendingactions.js
Outdated
* All plugins, which register pending action provides also a message what action is ongoing | ||
* which can be displayed to a user and let him decide if he wants to interrupt the action or wait. | ||
* | ||
* This plugin listens to `window#beforeunload` event and displays browser prompt when a pending action is in progress. |
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 anymore.
src/pendingactions.js
Outdated
* const pendingActions = editor.plugins.get( 'PendingActions' ); | ||
* const action = pendingActions.add( 'Upload in progress 0%' ); | ||
* | ||
* action.message = 'Upload in progress 10%'; |
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.
There is no example how to remove action.
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, I would move the whole sample to the plugin description.
src/pendingactions.js
Outdated
* action.message = 'Upload in progress 10%'; | ||
* | ||
* @param {String} message | ||
* @returns {Object} Observable object that represents a pending action. |
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 great to describe properties.
src/pendingactions.js
Outdated
* pendingActions.add( 'Action 2' ); | ||
* | ||
* pendingActions.first // Returns 'Action 1' | ||
* Array.from( pendingActions ) // Returns [ 'Action 1', 'Action 2' ] |
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.
Since this sample shows usage of not only this method by also iterator interface I would move it to the class description.
|
||
1. Click `Add pending actions` | ||
2. Check if action message is changing (action should disappear when progress reaches 100%) | ||
3. Try to reload page or close the browser tab when pending action is displayed, you should see a prompt |
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 does not make sense now. We could have some "finish" button to check if it works.
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.
Or you can add onbeforeunload
integration to the sample.
Suggested merge commit message (convention)
Feature: Introduced PendingActions plugin. Closes ckeditor/ckeditor5#2934.
This is a very basic implementation that covers all current needs.
It is possible to add pending action with a custom message and change this message. Message is observable.
Besides plugin listens to
window#beforeunload
event and displays prompt in a case of pending action.