Index: openacs-4/packages/xowiki/tcl/form-field-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/form-field-procs.tcl,v diff -u -r1.287 -r1.288 --- openacs-4/packages/xowiki/tcl/form-field-procs.tcl 11 Sep 2024 06:15:56 -0000 1.287 +++ openacs-4/packages/xowiki/tcl/form-field-procs.tcl 18 Sep 2024 14:10:09 -0000 1.288 @@ -4270,47 +4270,23 @@ -event load \ -script { function richtext_tinymce_editor_init_repeat(id, containerId, editorConfig) { - const repeatSelector = `[id^='${containerId}']`; - const compoundRepeatSelector = `[data-repeat-template-id='${id}']` + // Via this pattern we recognize fields that are + // appended to the DOM that are relevant to our repeated + // formfield. + const namePattern = id.replace(/^F\.[^\.]+\./g, '').replaceAll(/\.[0-9]+/g, '.[1-9][0-9]*'); const targetNode = document.getElementById(containerId); const config = { childList: true, subtree: true }; const callback = (mutationList, observer) => { for (const mutation of mutationList) { - for (const repeatedField of mutation.addedNodes) { - const inputField = repeatedField.querySelector?.(compoundRepeatSelector) || - repeatedField.querySelector?.(repeatSelector); - if (!inputField) { continue; } - const fieldId = inputField.id; - const repeatInfo = JSON.parse(repeatedField.getAttribute('data-repeat')); - const fieldName = repeatInfo ? repeatInfo.name : null; - editorConfig.selector = `[id='${fieldId}']`; - tinyMCE.init(editorConfig).then((editors) => { - let replacedField; - let fieldNum = 1; - for (const hiddenField of targetNode. - querySelectorAll('input[type=hidden]')) { - if (hiddenField.name === fieldId) { - /* Special behavior for inline editors: we - need to adjust the name of the hidden - formfield generated by TinyMCE */ - replacedField = hiddenField; - if (replacedField.name.endsWith(`.${fieldNum}`)) { - /* Simple repeat */ - replacedField.name = `${fieldName}.${fieldNum}`; - } else { - /* Nested repeat */ - const nameTokens = replacedField.name.split('.'); - const nestedName = nameTokens[nameTokens.length - 1]; - replacedField.name = `${fieldName}.${fieldNum}.${nestedName}`; - } - break; - } - fieldNum++; - } - replacedField?.form.addEventListener('submit', (evt) => { - replacedField.value = editors[0].getContent(); - }); - }); + for (const node of mutation.addedNodes) { + // Skip text nodes + if (!node.querySelectorAll) { continue; } + for (const inputField of node.querySelectorAll('[name]')) { + // Skip things that are not instances of our field. + if (!inputField.getAttribute('name').match(`^${namePattern}\$`)) { continue; } + editorConfig.selector = `[id='${inputField.id}']`; + tinyMCE.init(editorConfig); + } } } }; @@ -4320,11 +4296,6 @@ } # - # Hook to locate our richtext template when repeated. - # - set :data-repeat-template-id ${:id} - - # # The repeat container is the topmost ancestor of this # formfield. This is true both for regular and compound repeated # fields.