-
Notifications
You must be signed in to change notification settings - Fork 16
Create MediaFormView for each dropdown instance separately. #98
Conversation
@@ -53,6 +53,12 @@ describe( 'MediaEmbedUI', () => { | |||
expect( dropdown ).to.be.instanceOf( DropdownView ); | |||
} ); | |||
|
|||
it( 'should allow creating two instances', () => { |
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.
To make this test a bit more bulletproof, it'd be good to ensure that two instances are actually created. What if someone changes the beforeEach to not create this item (I can imagine this line being moved to particular it()s?
So, I'd simply call this .create()
twice in this test.
It'd also be good to verify that it's not the same instance returned twice :D
src/mediaembedui.js
Outdated
// Setup `imageUpload` button. | ||
editor.ui.componentFactory.add( 'mediaEmbed', locale => { | ||
const dropdown = createDropdown( locale ); | ||
|
||
this._setUpDropdown( dropdown, this.form, command, editor ); | ||
this._setUpForm( this.form, dropdown, command ); | ||
// Prepare custom view for dropdown's panel. |
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 that while taken the bug this line may seem in need of being commented, this is actually completely logical code and the test will be enough.
Haha :D My OCD suffers here as well. I think it's fine if it lands in another commit. |
@@ -41,19 +41,15 @@ export default class MediaEmbedUI extends Plugin { | |||
const command = editor.commands.get( 'mediaEmbed' ); | |||
const registry = editor.plugins.get( MediaEmbedEditing ).registry; | |||
|
|||
/** |
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's a breaking change. We need to mention this in the merge commit message (can be "MINOR BREAKING CHANGE"). What I'd also check is why the heck was this exposed on the plugin and whether someone doesn't use it somewhere (you can ping @scofalik to check CF's code for this). In general, it's odd that it was exposed here, so it's worth doublechecking.
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.
- Updated the merge commit message.
- Checked ckeditor5 project for
[\."']form\b
- nothing found, any ideas where else should I check?
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.
Some minor issues as commented.
…ent from each other. As suggested at #98 (review)
All comments addressed, except on unclear thing
|
Probably because people (including me) pointed out in some issues that there's no way to access the form and its descendants from the editor instance object. The form hosts several components and integrators may want to access them and adjust things (labels, placeholders, etc.). As a rule of thumb, there should always be some way to access any piece of UI by a chain of public properties starting with an editor instance (or As for why I didn't document or test that change, well... that's another topic :P Sorry for the confusion. I don't remember why I decided to do that in an unrelated PR. |
If we are about to expose a form as property on That would be more like UX change, and I'm not sure whether it's in the scope of this issue, and if it requires any approval from somebody? (@Reinmar ?) |
We definitely shouldn't change the UX of the feature in this PR. Solutions:
diff --git a/src/mediaembedui.js b/src/mediaembedui.js
index ec46f40..50ca212 100644
--- a/src/mediaembedui.js
+++ b/src/mediaembedui.js
@@ -48,12 +48,20 @@ export default class MediaEmbedUI extends Plugin {
*/
this.form = new MediaFormView( getFormValidators( editor.t, registry ), editor.locale );
+ this.form.urlInputView.bind( 'value' ).to( command, 'value' );
+
+ // Form elements should be read-only when corresponding commands are disabled.
+ this.form.urlInputView.bind( 'isReadOnly' ).to( command, 'isEnabled', value => !value );
+
+ this.form.saveButtonView.bind( 'isEnabled' ).to( command );
+
// Setup `imageUpload` button.
editor.ui.componentFactory.add( 'mediaEmbed', locale => {
const dropdown = createDropdown( locale );
this._setUpDropdown( dropdown, this.form, command, editor );
- this._setUpForm( this.form, dropdown, command );
+
+ this.form.delegate( 'submit', 'cancel' ).to( dropdown );
return dropdown;
} );
@@ -65,7 +73,14 @@ export default class MediaEmbedUI extends Plugin {
const button = dropdown.buttonView;
dropdown.bind( 'isEnabled' ).to( command );
- dropdown.panelView.children.add( form );
+
+ dropdown.on( 'change:isOpen', () => {
+ if ( dropdown.isOpen ) {
+ dropdown.panelView.children.add( form );
+ } else {
+ dropdown.panelView.children.remove( form );
+ }
+ } );
button.set( {
label: t( 'Insert media' ),
@@ -102,15 +117,6 @@ export default class MediaEmbedUI extends Plugin {
dropdown.isOpen = false;
}
}
-
- _setUpForm( form, dropdown, command ) {
- form.delegate( 'submit', 'cancel' ).to( dropdown );
- form.urlInputView.bind( 'value' ).to( command, 'value' );
-
- // Form elements should be read-only when corresponding commands are disabled.
- form.urlInputView.bind( 'isReadOnly' ).to( command, 'isEnabled', value => !value );
- form.saveButtonView.bind( 'isEnabled' ).to( command );
- }
} |
That is a thing I wasn't sure about. I could imagine a theme, a11y mode, or just a UX |
Can't we expose the form property on the button itself? I wouldn't feel safe with the form being reused as this may lead to strange situations. We're talking about corner cases here, but what if someone wants to have one of these forms look a bit different because it's displayed in the block toolbar (so perhaps should be more narrow) and the other form in the normal toolbar? Etc. If the form is shown by the button, then the button should expose it. I guess that this is what we'd do if we weren't biased by seeing this bug first and were writing this for the first time :D We just started exploring more complex areas because of what we already saw. |
That'd be fine for me too. However, while we don't see an application for accessing the form, it often happens that it appears at the moment when we simply have other things to do. And then someone needs to wait at least a month until we release a new version. Of course, there's always a way to fork this particular module or the entire package, so making decisions about such things always troubles me :D A trivial change can save someone a lot of work. But will anyone actually need it? |
I think we should rather expose it on Let me know if I get correctly what you mean by exposing, and making future applications easier. const mediaForm = new MediaFormView( /*...*/ );
dropdown.panelView.children.add( mediaForm );
// DevX sugar to avoid dropdown.panelView.children.get(0).
dropdown.form = mediaForm;
dropdown.panelView.children.get(0) === dropdown.form // true But then how to document it? What is the JSDOC handle for |
👍 Sorry, that's what I meant.
Oh, right. I didn't think about this. Yup, we'd need to subclass DropdownView just to document this propert 🤦 For me that makes all this not worth the effort (the ROI drops). So, as you proposed, let's drop this property completely. After all, it can be accessed via |
Waiting for confirmation from @scofalik that we can safely remove this property. |
Szymon said we're fine. |
We're waiting with the merge for the monorepo migration. |
…ent from each other. As suggested at ckeditor/ckeditor5-media-embed#98 (review)
Closing in favor of ckeditor/ckeditor5#6736 |
Fixes ckeditor/ckeditor5#6333
Suggested merge commit message (convention)
Fix: Create MediaFormView for each dropdown instance separately. Closes ckeditor/ckeditor5#6333
MINOR BREAKING CHANGE:
mediaembedui~MediaEmbedUI#form
was removed from the APIAdditional information
Previously it was trying to attach the same
MediaFormView
instance form for all dropdowns instances, then attach actions multiple times.BTW, I was thinking about refactoring a bit
_setUpDropdown
and_setUpForm
, to have the same order of arguments, but decided to keep the changes to the minimum.