Wiki source code of Page Ready

Version 4.1 by Marius Dumitru Florea on 2022/03/28

Show last authors
1 Most of XWiki's JavaScript code is [[organized in modules>>dev:Community.DevelopmentPractices||anchor="HJavaScriptBestPractices"]] following the [[Asynchronous module definition>>https://en.wikipedia.org/wiki/Asynchronous_module_definition]] (AMD) specification. These modules are loaded asynchronously, most of the time after the window ##load## event is fired so it's not easy to know when the page is fully ready for user interaction, i.e. when all the resources have been loaded and there are no pending HTTP requests or promises. Executing code after the page is ready is important for instance when performing client-side PDF export: the page should have all its elements ready, including those added dynamically and asynchronously, before we tell the browser to print the page. Similarly, when running automated functional tests we need to wait for the page to be ready before simulating user interaction, otherwise we end up having many failing flaky tests. The ##xwiki-page-ready## JavaScript module satisfies this need. Here's how you can use it:
2
3 {{code language="js"}}
4 require(['xwiki-page-ready'], function(pageReady) {
5 pageReady.afterPageReady(() => {
6 console.log('Page is ready!');
7 });
8 });
9 {{/code}}
10
11 The ##xwiki-page-ready## module intercepts automatically:
12
13 * window load event
14 * all ##XMLHttpRequest##s
15 * all ##fetch()## requests
16 * all script tag injections
17
18 (that happen around page load) and delays the page ready until they all finish. So normally you only need to know about ##afterPageReady()##, as shown above. Note that the callback passed to ##afterPageReady()## can return a promise in order to delay the other page ready callbacks. This is useful if you want to execute an asynchronous process after the page is ready but you also want to make the other callbacks wait (e.g. you want the print to PDF to include your changes):
19
20 require(['xwiki-page-ready'], function(pageReady) {
21 pageReady.afterPageReady(() => {
22 return new Promise((resolve, reject) => {
23 // Do some asynchronous processing and then call resolve() in order
24 // to allow the other page ready callbacks to be executed.
25 });
26 });
27 });
28
29 If you have JavaScript code that executes after the page is loaded with some delay and you want to also delay the page ready then here's how you can do it:
30
31 {{code language="js"}}
32 require(['xwiki-page-ready'], function(pageReady) {
33 pageReady.delayPageReady(new Promise((resolve, reject) => {
34 // Perform some asynchronous action and call resolve() when done.
35 }), 'the reason for delay');
36 });
37 {{/code}}
38
39 ##delayPageReady## accepts a promise, that delays the page ready until settled (either fulfilled or rejected), and an optional reason string, which is useful for debugging (see below).
40
41 When the page is ready the HTML root element is marked accordingly using the ##data-xwiki-page-ready="true"## attribute. If this doesn't happen then you can inspect the pending delays (that prevent the page ready) using the following code (even directly from the JavaScript console):
42
43 {{code language="js"}}
44 require(['xwiki-page-ready'], function(pageReady) {
45 console.log(pageReady.getPendingDelays());
46 });
47 {{/code}}
48
49 The optional reason parameter passed to ##delayPageReady## prooves very useful in this case to understand where the problem is (e.g. to understand which script or which fetch request are blocking the page ready).

Get Connected