You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If you open a page in Structure mode, Django CMS will load the 'structure HTML' first and use an XHR call to fetch the actual contents of the page. When you close the Structure mode the page source is replaced with the actual contents of the paged, fetched earlier with the XHR call. All scripts on the page are loaded, but in sync instead of in order of appearance. This will cause libraries not being loaded in time.
Expected behaviour
The script-tags should be loaded / executed in order of appearance. E.g. If you have a jQuery script-tag and a jQuery plugin tag, its important to load jQuery before the plugin otherwise you'll get a jQuery is not defined.
Actual behaviour
The script-tags are loaded synchronously and executed once loaded, but not in order of appearance. E.g. the jQuery plugin can't find jQuery.
Environment
Python version: All (Javascript issue)
Django version: All (Javascript issue)
django CMS version: 3.5.x and 3.6.x
The text was updated successfully, but these errors were encountered:
The contents of the body is appended by the _loadContent() method, using bodyElement.append(body);. This will call the [append()](https://api.jquery.com/append/) method from jQuery. This method will load all scripts at once and execute them directly after loading them, so not in order of apearence.
I'm not sure what would be the correct fix for this issue. The jQuery append() behaviour is correct (following W3C), but the behaviour in Django CMS is not (the result starting in 'content' mode is different from the result from starting in 'structure' mode.).
Once option would be to dynamically replace all script tags with a new tag that add a async = true attribute, like suggested here: https://stackoverflow.com/a/8578840/522248 (the Google/Facebook method).
Pro: it works like charm
Con: it might be slower due to 'async' loading which is not the same as executing in order (not sure) and you might alter behaviour of some other scripts
Another option would be to roll back to the old behaviour where the original page is simply loaded and the StructureBoard is loaded via XHR.
Maybe this might be a help: Personally I think it might be a plan to use a bundler for all your js code and init them with a single function. In our case we lost all references because of the DOM manipulations done after saving a plugin.
This pattern works for us:
We us webpack to bundle all JS libraries and our JS Code
We initialize all our JS dependent components with a function which looks if an html element has a specific class
On a fresh page load we wait till the dom is ready and call that init function
A simplified example of that from our code... Since we write everything in React and don't use jQuery it wont work out of the box but maybe its a help?!:
import domready from 'domready';
const req = require.context('./', true, /\.jsx$/);
const components =[{
name: 'react--calculator',
module: 'modules/calculator/calculatorPreview.jsx'
}]
const loadComponents = () => {
components.forEach(component => {
let ReactElement;
const nodes = document.querySelectorAll(`.${component.name}`);
if (nodes.length > 0) {
ReactElement = req('./' + component.module);
}
ReactDOM.render(React.createElement(ReactElement, {}), node);
}
}
domready(loadComponents);
//
// Listen to DOM Mutations which happen on every cms plugin save...
domready(() => {
((CMS || {}).$ || {})(window).on('cms-content-refresh', function() {
loadComponents();
});
});
Summary
If you open a page in Structure mode, Django CMS will load the 'structure HTML' first and use an XHR call to fetch the actual contents of the page. When you close the Structure mode the page source is replaced with the actual contents of the paged, fetched earlier with the XHR call. All scripts on the page are loaded, but in sync instead of in order of appearance. This will cause libraries not being loaded in time.
Expected behaviour
The script-tags should be loaded / executed in order of appearance. E.g. If you have a jQuery script-tag and a jQuery plugin tag, its important to load jQuery before the plugin otherwise you'll get a jQuery is not defined.
Actual behaviour
The script-tags are loaded synchronously and executed once loaded, but not in order of appearance. E.g. the jQuery plugin can't find jQuery.
Environment
The text was updated successfully, but these errors were encountered: