Feature request
A work in progress preview is available. I made a codepen demo where the default dialog value feature can be tested.
I know that you can already freely customize dialog fields using API, by hooking to a proper event - but this requires some basic programming skills.
This feature requests aims to simplify default dialog fields customization, by allowing that through configuration object.
Let's talk about the formats, currently there are two proposals that come to my mind:
config.dialog_defaultValues = {
// '<dialogName>.<tabId>.<fieldId>': '<value>'
'link.info.protocol': 'https://',
'table.info.txtWidth': '100%'
};
config.dialog_defaultValues = {
link: {
info: {
protocol: 'https://'
}
},
table: {
info: {
txtWidth: '100%'
}
}
}
I can see that both formats could be further extended if there will be need for that.
For instance, assume that the default value should be different for a editor in RTL language, or that the value should differ in case there is a xyz plugin.
To satisfy this requirement the values could be provided as functions, like that:
config.dialog_defaultValues = {
'link.info.protocol': function( editor ) {
return editor.lang.dir == 'ltr' ? 'foo' : 'bar';
}
};
I'm just wondering wouldn't it be useful also to allow more customization, like mark the field as required or hide a given view, like so:
config.dialog_defaultValues = {
'link.info.protocol': 'https://', // Simple format.
'table.info.txtWidth': { // Advanced format.
placeholder: 'width',
required: true,
type: 'number'
}
};
In which case the config property should get more generic name, that does not imply that it's about dialog values.
Lastly: I can even see this property being utilized in some sort of "umbrella" plugins, say we have plugin like html5links and it would do the following:
config.dialog_defaultValues = CKEDITOR.tools.object.merge( config.dialog_defaultValues, {
'link.info.protocol': 'https://',
'link.advanced.advName': {
hide: true
}
} );
I can already see some problems lurking around the corner. In case of mentioned link protocol, there is a special case for RTL languages, which for instance gets https://\u200E instead of https://. So if we treat values literally it would not work in case of RTL langs.
As you might recall we have a Developer Tools plugin - it's an old plugin, but it could be helpful for people to quickly identify how a particular dialog field could be addressed.
You can check it in our old samples.
First I wanted to start the discussion regarding this feature. What is exactly what we need, what is the bare minimum we want to go with.
Based on the above I actually prefer "Flat Object" approach, as it is more user friendly, for devs configuring it.
IMO flat object is much more user-friendly in this case, also it's not so unfamiliar thus libraries like lodash. It would be great if a user could reuse our validation functions CKEDITOR.dialog.validate.
Agree, flat object will be simpler. Let's split the implementation into two steps (two pull requests):
javascript
config.dialog_defaultValues = {
// '<dialogName>.<tabId>.<fieldId>': '<value>'
'link.info.protocol': 'https://',
'table.info.txtWidth': '100%'
};
javascript
config.dialog_defaultValues = {
// '<dialogName>.<tabId>.<fieldId>': '<value>'
'link.info.protocol': 'https://',
'table.info.txtWidth': {
required: true,
default: '100%'
}
};
I stumbled upon interesting case with image2 caption checkbox on StackOverflow that should also be improved by this enhancement. So we need to make sure this enhancement works also with checkboxes.
I have added a link to early preview in the issue description.
During the review of PR I came with the following question: should the default values be used when opening the dialog to edit the element?
The issue is that in CKE4 we have no good way to tell whether you're editing something or not. It is kind of present in case of widgets, as widgets do pass widget instance in a systematical way, where you can check whether it exists in the DOM.
But for regular dialogs like link, liststyle and worst yet, any third-party, there's no such thing.
In order to reduce the changes as much as possible, the best option I see here is to introduce dialog interface, that if implemented (this grants backward compatibility) can be used to determine whether dialog is editing something or not.
Keep in mind that in CKE4 architecture dialogs are singletons, but this is not a big issue as we can pass the editor instance to the called method.
Interface would feature only a single method:
getModel( editor ) : [Object] Returns null if there's no related model (about, help dialogs). For the most plugins like table / link it would simply return a CKEDITOR.dom.element if there's a related element to it.If the dialog does not implement getModel() it is assumed to be always in editing mode.
Good thing is that it allows you to implement this interface, even in a reusable way to 3rd party plugins, but it requires JS code. You could listen to dialogDefinition event, and add getModel() method.
To make the adoption easier, it would be nice to add a short article that briefly mentions reasons for that and guides how to implement the new API.
I set link default values like these:
CKEDITOR.on('dialogDefinition', (ev) => {
if (ev.data.name == 'link') {
ev.data.definition.getContents('target').get('linkTargetType')['default']='_blank';
ev.data.definition.getContents('info').get('protocol')['default']='https://';
}
});
Most helpful comment
I stumbled upon interesting case with image2 caption checkbox on StackOverflow that should also be improved by this enhancement. So we need to make sure this enhancement works also with checkboxes.