Index: openacs-4/packages/xowiki/xowiki.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/xowiki.info,v diff -u -r1.180.2.123 -r1.180.2.124 --- openacs-4/packages/xowiki/xowiki.info 5 Apr 2024 08:55:04 -0000 1.180.2.123 +++ openacs-4/packages/xowiki/xowiki.info 2 May 2024 14:06:47 -0000 1.180.2.124 @@ -10,7 +10,7 @@ t xowiki - + Gustaf Neumann A xotcl-based enterprise wiki system with multiple object types 2023-07-11 @@ -55,7 +55,7 @@ BSD-Style 2 - + @@ -83,7 +83,7 @@ - + { + 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) { + replacedField = hiddenField; + replacedField.name = `${fieldName}.${fieldNum}`; + break; + } + fieldNum++; + } + replacedField?.form.addEventListener('submit', (evt) => { + replacedField.value = editors[0].getContent(); + }); + }); + } + } + }; + const observer = new MutationObserver(callback); + observer.observe(targetNode, config); + } + } + + # + # 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. + # + set obj [self] + while {[$obj exists parent_field]} { + set parent_field [$obj set parent_field] + set obj $parent_field + } + set repeat_container_id [$parent_field id] + + ::template::add_body_handler -event load -script [subst -nocommands { + richtext_tinymce_editor_init_repeat('${:id}', '${repeat_container_id}', {$config}); + }] + } else { + # + # A regular non-repeated field. + # + ::template::add_body_handler \ + -identifier richtext_tinymce_editor_init \ + -event load \ + -script { + function richtext_tinymce_editor_init(elementId, fieldName, editorConfig) { + editorConfig.selector = `[id='${elementId}']`; + tinyMCE.init(editorConfig).then((editors) => { + const replacedField = document.querySelector(`input[type=hidden][name='${elementId}']`); + replacedField?.form.addEventListener('submit', (evt) => { + replacedField.name = fieldName; + replacedField.value = editors[0].getContent(); + }); + }); + } + } + + ::template::add_body_handler -event load -script [subst -nocommands { + richtext_tinymce_editor_init('${:id}', '${:name}', {$config}); + }] + } + + if {$inline_p} { + # + # In inline mode, the markup we send is a div, that TinyMCE + # replaces with an editor + a hidden input field with our same id, + # but no name attribute. + # + # Before the form is submitted, we get the content from the + # editor and store it as the hidden field value, then set the + # name attibute as XoWiki expects it. This logic is found in + # both the promise handler for TinyMCE.init up in the js + # functions. + # + :render_richtext_as_div + } else { + next + } + } + + ########################################################### + # # ::xowiki::formfield::ShuffleField # ###########################################################