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
Change comment: There is no comment for this version
To version 38.1
edited by Vincent Massol
on 2017/09/01
Change comment: Copied from platform:DevGuide.JavaScriptAPI

Summary

Details

Page properties
Author
... ... @@ -1,1 +1,1 @@
1 -XWiki.mflorea
1 +XWiki.VincentMassol
Content
... ... @@ -28,8 +28,8 @@
28 28  document.observe("xwiki:dom:loaded", function(){
29 29   // Initialization that can rely on the fact the DOM is XWiki-tranformed goes here.
30 30  });
31 -{{/code}})))
32 -(((
31 +{{/code}}
32 +)))(((
33 33  {{info}}
34 34  It is recommended to bind startup scripts to this event instead of ##window.load## or ##document.dom:loaded##.
35 35  {{/info}}
... ... @@ -91,13 +91,12 @@
91 91   // do something specific
92 92   }
93 93  });
94 -{{/code}})))
95 -(((
94 +{{/code}}
95 +)))(((
96 96  {{warning}}
97 97  While most properties can be accessed as ##event.memo.property##, this doesn't work with ##event.memo.continue## since ##continue## is a reserved keyword.
98 98  {{/warning}}
99 -)))
100 -(((
99 +)))(((
101 101  All these events contain as extra information, in the second parameter sent to event listeners (the memo), the original click event (if any, and which can be stopped to prevent the action from completing), and the form being submitted, as ##event.memo.originalEvent##, and ##event.memo.form## respectively.
102 102  )))
103 103  
... ... @@ -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  
168 +== Deferred Dependency Loading ==
169 +
170 +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().
171 +
172 +{{code language="js"}}
173 +require.config({
174 + paths: {
175 + module: "path/to/module"
176 + },
177 + shim: {
178 + module: {
179 + exports: 'someGlobalVariable',
180 + deps: ['anotherModule']
181 + }
182 + }
183 +});
184 +{{/code}}
185 +
186 +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:
187 +
188 +{{code language="js"}}
189 +require(['path/to/config'], function() {
190 + require(['module'], function(module) {
191 + // Do something with the module.
192 + });
193 +});
194 +{{/code}}
195 +
196 +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:
197 +
198 +{{code language="js"}}
199 +require(['deferred!module'], function(modulePromise) {
200 + modulePromise.done(function(module) {
201 + // Do something with the module, if the module is loaded by someone else.
202 + });
203 +});
204 +{{/code}}
205 +
206 +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).
207 +
208 +Examples where this could be useful:
209 +
210 +* extend the tree widget (if it's available on the current page)
211 +* extend the WYSIWYG editor (if it's loaded on the current page)
212 +
213 +An alternative is for each module that wants to support extensions to fire some custom events when they are loaded.
214 +
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.
... ... @@ -311,3 +311,4 @@
311 311  {{code}}
312 312  this.entities = XWiki.EntityReferenceTree.fromJSONObject(transport.responseText.evalJSON());
313 313  {{/code}}
360 +)))

Get Connected