It seems if i define an extra element like:
infoTab.add( {
id: 'myCheckbox',
type: 'checkbox',
label: 'myCheckbox',
onLoad: function() {
Drupal.dndck4.registeredOptions.push({id: this.id, type: 'image', mode: 'atom', name: 'scald_image'});
},
setup: function(widget) {
var options = JSON.parse(widget.data.options);
this.setValue(options.my_checkbox);
},
commit: function(widget) {
// Copy the current options into a new object,
var options = JSON.parse(widget.data.options);
var value = this.getValue();
if (value != '') {
options.my_checkbox = value;
}
else {
delete options.my_checkbox;
}
widget.setData('options', JSON.stringify(options));
}
});
Then the onLoad function is not called (neither the onShow). However if all i do is change the type to text, then onLoad works fine.
I suspect it is a ckeditor bug. However this prevents me for making this work properly.
ckeditor version 4.4.6
Comments
Comment #1
nagy.balint commentedThe workaround i found is to make the showHideOptions function available globally by the patch attached.
And then to add in the setup:
Then it works fine. (Though in certain cases then the showHideOptions will be called twice.
@gifad : can you check if you see the same thing? If we can do this workaround, or rather should do something else?
Comment #2
gifad commented@nagy.balint :
1 - Your code would not work, because the argument of
showHideOptions()must be the context field...2 - the registration code is not required to be located inside the element description; you can issue
- if you are injecting the element dynamically : in the script where you do the
on('dialogDefinition',...- if you are building a custom dialog : in the
onLoadof a regular control, or in theonLoadof the dialog itself.BTW, the ckeditor "bug" is still present in ckeditor-dev 4.4.8 and 4.5.0; so it could be a feature ?
[Edit] : This works, because the
registeredOptionsarray stores only the string representation of the element id, not requiring that the element is actually created.Comment #3
gifad commentedAs a proof of concept, and/or for sample code, I tested this on scald_image module.
Comment #4
gifad commentedCorrection : the initialisation of registeredOptions in atomProperties.js must be made compliant...
Comment #5
nagy.balint commented@gifad thats not going to work on pages where you have more than one wysiwyg.
The dialog add runs when you click on the edit atom properties (and thats when all the other js runs that adds new items).
So clicking edit atom properties in the first field will add correctly the 2 items (scald_image, and my custom), and then if you do the same in the second wysiwyg, it will add them too, and you end up having 4 items in the Drupal.dndck4.registeredOptions
Comment #6
nagy.balint commentedSo in fact the current version of the code works fine, cause even though it always replaces the array with an empty one and fills it up again in each wysiwyg, but since we dont have the capability to add something different for a specific wysiwyg it wont cause a problem.
Comment #7
nagy.balint commentedComment #8
gifad commentedI was never satisfied with the public use of registeredOptions array;
So I made a registerOptions function(id, type, mode, name), which is cleaner, and solves problems.
Sample usage (in scald_image.js)
Drupal.dndck4.registerOptions('txtLink', 'image', 'atom', 'scald_image');I don't think there are so many uses of this for now, so API change it not a hard inconvenience...
[Edit]
Sorry, issue was fixed while I was building the patch
Leaving status as is, as this is better (at least less bad) code...
Comment #9
nagy.balint commenteda) I think that at this point:
+ if (found = (this.id == id && this.type == type && this.mode == mode && this.name == name)) {Checking the id would be enough, as likely you would not give the same id to two different items.
b)
$.merge(Drupal.dndck4.registeredOptions, [item]);I dont see why we need merge as we will never add more than one item at the same time, so the previous push is enough.
Comment #10
gifad commented@nagy.balint :
a) Of course I "would not give the same id to two different items", but I have two custom image providers, and some of them implement the same item (including the "txtLink")
b) You're right...
Comment #11
nagy.balint commenteda) Hmm well since here we only add to the list to have a list to consider when doing a cycle.
So if the field is the same on another provider, then that provider does not need to add the option, as it will be added by the other provider for the image already.
Or even if the other provider adds it to the list, comparing the id would be enough, as then one of the providers will add the item to the list.
If both provider is supposed to display its field on the atom properties, then they should not have the same id anyways, so that case would be fine as well.
So can you provide a use case where comparing only with the id would be bad?
Comment #12
gifad commentedUse case : two image providers implementing he same "txtLink" option;
If we added in the list only the first referencing "txtLink", the atoms provided by the second provider would not have the option available !
This is because the test is :
which is necessary for the case of the second provider not implementing the option.
[Edit] such as scald_flickr module...
Comment #13
nagy.balint commentedOkey.
Another question. In showHideOptions it seems unnecessary to do $.each 3 times. Seems to me that what the function does could be done with a single $.each, as you are not accessing any other items in an iteration.
Also lets delete the commented console logs at the end.
Comment #14
gifad commentedWell, I'm used to optimizing compilers, and I'm a javascript beginner, so this code was written with debugging in mind...
This is a "minified" version...
Comment #16
nagy.balint commentedThanks!
Committed.