Details
-
Bug
-
Resolution: Unresolved
-
Major
-
18.6.0-rc-1
-
None
-
Unknown
-
Description
Since XWIKI-24559, async.js sends the xwiki:dom:updated event once the result of an asynchronous rendering is displayed, but the event targets the placeholder that was replaced by the result, not the result itself:
element.replaceWith(xhr.responseText);
$(document).trigger('xwiki:dom:updated', {elements: element.toArray()});
replaceWith leaves element pointing to the removed placeholder. The listeners of the event, which initialize the updated elements, look for what to initialize inside elements that are not in the page anymore, so they find nothing.
Steps to reproduce
Example with the Chart.js application, whose charts are drawn on page load and on xwiki:dom:updated, in the updated elements (seen with the OpenProject Charts macro of the Project Management application, which renders its charts asynchronously):
- Edit a page containing an asynchronously rendered chart with the in-place editor
- Click "Done" (or "Save & View")
Result: the chart is empty, until the page is reloaded.
A simple page view works, because the Chart.js JavaScript is only loaded with the asynchronous result and, when loaded, initializes the whole page. The event is needed when the JavaScript is already loaded, e.g. after saving with the in-place editor, or with several asynchronous charts on the same page depending on the timing.
Proposed fix
As suggested by Marius: create the new elements first, pass them to replaceWith and to the event. Calling the event with the parent of the placeholder isn't an option, since it would initialize again sibling elements that weren't changed.
const newElements = $($.parseHTML(xhr.responseText, document, false)); element.replaceWith(newElements); $(document).trigger('xwiki:dom:updated', {elements: newElements.filter('*').toArray()});
- $.parseHTML rather than $(xhr.responseText): $() only parses the string as HTML when it starts with <.
- false drops the inline scripts of the result, which replaceWith executes today. Inline scripts are a bad practice and a security risk, and the scripts needed by the result are declared in an HTTP header handled by xwiki.js, but this is a behaviour change for asynchronous content relying on inline scripts, to mention in the release notes.
- Add a functional test checking that the content rendered asynchronously gets initialized, since
XWIKI-24559didn't have one.
Attachments
Issue Links
- relates to
-
XWIKI-24559 Send a JS event after finishing the asynchronous rendering of some xwiki content
-
- Closed
-