Changes for page XWiki JavaScript API

Last modified by Simon Urli on 2022/09/14

<
From version < 36.2 >
edited by Marius Dumitru Florea
on 2016/01/28
To version < 37.1 >
edited by Marius Dumitru Florea
on 2016/04/05
>
Change comment: There is no comment for this version

Summary

Details

Page properties
Content
... ... @@ -166,6 +166,53 @@
166 166  
167 167  The best part is, any scripts which are loaded using require are loaded //asynchronously// (all at the same time) and if they are not required, they are never loaded at all.
168 168  
169 +== Deferred Dependency Loading ==
170 +
171 +Loading (transitive) dependencies through RequireJS works if those modules are known by RequireJS. In order to make a module known you need to tell RequireJS where to load that module from. A module can be located in various places: in a WebJar, in the skin, in a JSX object or even in a file attached to a wiki page. If the module you need is common enough that is loaded on every page (like the 'jquery' module) then chances are it is already known (configured in javascript.vm). Otherwise you need to configure the dependency by using require.config().
172 +
173 +{{code language="js"}}
174 +require.config({
175 + paths: {
176 + module: "path/to/module"
177 + },
178 + shim: {
179 + module: {
180 + exports: 'someGlobalVariable',
181 + deps: ['anotherModule']
182 + }
183 + }
184 +});
185 +{{/code}}
186 +
187 +If two scripts need the same dependency then they will have to duplicate the require configuration. In order to avoid this you could move the configuration in a separate file and write something like this:
188 +
189 +{{code language="js"}}
190 +require(['path/to/config'], function() {
191 + require(['module'], function(module) {
192 + // Do something with the module.
193 + });
194 +});
195 +{{/code}}
196 +
197 +but you would still duplicate the configuration path in both scripts. Now, suppose that one of the scripts is only extending a feature provided by the dependency module. This means that it doesn't necessarily need to bring the dependency. It only needs to extend the module if it's present. This can be achieved starting with XWiki 8.1M1 like this:
198 +
199 +{{code language="js"}}
200 +require(['deferred!module'], function(modulePromise) {
201 + modulePromise.done(function(module) {
202 + // Do something with the module, if the module is loaded by someone else.
203 + });
204 +});
205 +{{/code}}
206 +
207 +In other words, the script says to RequireJS "let me know when this module is loaded by someone else" (someone else being an other script on the same page). This looks similar with the solution where the require configuration is in a separate file, but the advantage is that the path is not duplicated (i.e. we can move the module to a different path without affecting the scripts that use it).
208 +
209 +Examples where this could be useful:
210 +
211 +* extend the tree widget (if it's available on the current page)
212 +* extend the WYSIWYG editor (if it's loaded on the current page)
213 +
214 +An alternative is for each module that wants to support extensions to fire some custom events when they are loaded.
215 +
169 169  == Bridging custom XWiki events between Prototype and jQuery ==
170 170  
171 171  Starting with XWiki 6.4 you can catch from jQuery the custom XWiki events that are fired from Prototype.

Get Connected