Fix subform multiple tinymce elements#39449
Conversation
|
|
|
Sorry, the fix is not a fix. And should not be acepted. Editor-XTD buttons broken because they hardly linked to Editor ID. |
True, they only get the editor name as their input, probably we could pass the id as well:
So basically a store that each editor needs to subscribe and update the state each time it takes focus but I don't really follow you on the API part for the buttons, how would that work? Just ask the latest in focus and then apply the command on that editor? |
Yeap, kind of that. The idea like this: |
|
Basically (pseudo): // Only define editors if not defined
window.Joomla.editors = window.Joomla.editors || {};
// Dumb last focused editor state
window.Joomla.editors._active = null;
window.Joomla.editors.setActive = (val) => window.Joomla.editors._active = val;
window.Joomla.editors.getActive = () => window.Joomla.editors._active;
// An object to hold each editor instance on page, only define if not defined.
window.Joomla.editors.instances = window.Joomla.editors.instances || { }; |
|
Yeap kind of that. Then Joomla.editors.instances['jform_articletext'].replaceSelection('Joomla! rocks')will become Joomla.editors.getActive().replaceSelection('Joomla! rocks')Also in setActive() can store only instance key, and then use this key in getActive(): getActive = () => Joomla.editors.instances[Joomla.editors._active];But that a details, can be anything. |
Can we use proxy for the state (eg https://github.com/windmaomao/proxy-state) and make it promise based? Or am I complicating it too much? |
|
I do not have much expiriance with Proxy. Sounds complicated to me :) |
It's not ultra weird, this example from MDN is probably closer to what we need: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#validation |
|
Hmhm, I would do without, and look how it will go. |
|
We already have similar (synchronous) code: joomla-cms/build/media_source/system/js/core.es6.js Lines 104 to 133 in 8bbc625 |
FFS that code is wrong 😂 setCurrent: (element) => {
window.Joomla.Modal.current = element;
},
getCurrent: () => window.Joomla.Modal.current, |
|
If it work, then nothing wrong hehe |
That modal will not have the problem, it just an modal, it does nothing with editor. The media/user fields, also should work in theory. But I still would change them to use "events" instead of callbacks. But that another topic. |
I realised that the problem in in the url of the iframe the
I think we should just create a simple API that collects the data for the button (text, icon, etc) pass them to joomlaOptions and have the editor create them and bound them per instance. Should be less problematic going forward |
Yeah. As long as the Input id is correct, this should continue to work.
That could work. But that should be compatible with any editor, not only tinymce. |
We will implement it for tinyMCE, Codemirror and None, so plenty examples for anyone to pickup the code for their own implementation. I think we should evaluate which option will be also easier for maintenance but also for 3rd PD. I don't have all the answers, I'm just shouting ideas here |
|
Yeah, need to make some concept first. Probably some simple button can have a callback, and more complex a script, or callback that run code from script :)
Me either :) |
Yes glad you got there in the end. But the reason for that is that the buttons currently reference the last part of the name so Also it's not just modals for example readmore which doesn't have a modal but instead has a click event uses I mean I put in some code that although it is a b/c break works ;) Admittedly I've broken the initial load of tinymce even more - but pretty sure i can fix that in another 10 minutes - it's just the fact the default field misses xtdButtons altogether. But if you guys have a counter proposal happy to figure that out. But right now I'm not sure you do?
Also going to need some extra explanations here.... |
|
Also needs fixing that all tiny xtd buttons for a subform field editor have the same id due to https://github.com/joomla/joomla-cms/blob/4.2-dev/plugins/editors/tinymce/src/PluginTraits/XTDButtons.php#L61 |
Theoretically speaking #39351 should be orders of magnitude easier to patch for subforms. A possible way out of this rabbit hole might be a twisted code of the xtd-buttons:
But all these are hacks around an API that was never designed to support multiple instances of any editor per page... |
|
I mean the specific code dates back to this #14520 But I don't understand why we've done this per part of field name and not just used the full name or id? I assume I'm missing something obvious? |
Depends who you want responsible for what :D PHP these days just assembles all the form field params together. The JS is doing all the rendering these days as you know. So honestly I'm not totally sure where the "root problem" is other than it's how the options are being passed through. I agree about templating and thought about bodging it. But even that involves tiny being aware it's being used in a subfield which isn't how it should be in theory. It should somehow be hooking into https://github.com/joomla/joomla-cms/blob/4.2-dev/build/media_source/system/js/fields/joomla-field-subform.w-c.es6.js#L253 to do the id replacement (a new event??) although |
Ok, some insight in the way this whole think works maybe will show why I'm leaning into a client side rendering solution. So when php sends the html (assuming that the subform is null at this point) the tinymce js gets all the |
Look: you have ID
It looks like works, but it is not. |
|
@Fedik @wilsonge will this code fixes (the modal, for now, for the inline code we need to do a similar search replace) the problem? arr.forEach((xtdButton) => {
const tmp = {};
tmp.text = xtdButton.name;
tmp.icon = xtdButton.icon;
tmp.type = 'menuitem';
if (xtdButton.iconSVG) {
icons[tmp.icon] = xtdButton.iconSVG;
}
if (xtdButton.href) {
const modal = element.parentNode.parentNode.querySelector(`#${xtdButton.id}_modal`);
// Update the editor url parameter of the modal
if (modal && modal.dataset.url) {
const url = new URL(modal.dataset.url);
url.searchParams.delete('editor');
url.searchParams.append('editor', element.id);
modal.dataset.url = url.toString();
tmp.onAction = () => {
modal.open();
};
}
} else {
tmp.onAction = () => {
// eslint-disable-next-line no-new-func
new Function(xtdButton.click)();
};
}
buttonValues.push(tmp);
}); |
|
Looks haky, but if it works then I am fine 😄 |
|
Of course it's hacky. We seriously need to re architecture the Editor and buttons to fit the current multi editor status (since the introduction of Custom Fields) and also eliminate all the new Function... |
|
I am closing it in favor of #40202. Please review and test ;) |
Pull Request for Issue #39416 .
There is a minor B/C break here in that the options are injectable by other components and this does change that ID - however there isn't another way to make this work for subform fields. The only other way I can make this work is to code a b/c break that would be more specific to subform fields with tiny (by detecting the property in the url or similar). Either way there's going to be a b/c break. However we don't guarentee b/c breaks in extensions so the impact should be limited and hence I've targeted 4.3 rather than 4.2 even though this is also a bug fix
Summary of Changes
Changes the property used to inject tinymce options from the last element in the name to the id of the element. This is because in subform fields (with a tinymce custom field) the final element is the id of the field (e.g.
field5) and the one before that is the row number which differentiates the fieldsTesting Instructions
Follow the instructions in the linked issue to test the patch before applying the PR. Apply the PR (remember to run
npm run build:jsto compile the javascript if using patchtester. Else use the upgrade package from drone. Then retest and find things work as expectedLink to documentations
Please select:
Documentation link for docs.joomla.org:
No documentation changes for docs.joomla.org needed
Pull Request link for manual.joomla.org:
No documentation changes for manual.joomla.org needed