@qooxdoo/framework 7.0.0-beta.3 → 7.0.0-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/Manifest.json +1 -1
  3. package/README.md +9 -3
  4. package/lib/compiler/compile-info.json +60 -58
  5. package/lib/compiler/index.js +3242 -1883
  6. package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/theme/custom/css/custom.css.map +1 -1
  7. package/lib/resource/qx/tool/loadsass.js +6 -4
  8. package/lib/resource/qx/tool/schema/compile-1-0-0.json +6 -11
  9. package/package.json +17 -3
  10. package/source/class/qx/Bootstrap.js +22 -1
  11. package/source/class/qx/bom/Blocker.js +2 -1
  12. package/source/class/qx/core/Environment.js +3 -12
  13. package/source/class/qx/core/MProperty.js +1 -1
  14. package/source/class/qx/dev/unit/Sinon.js +1 -1
  15. package/source/class/qx/io/__init__.js +5 -3
  16. package/source/class/qx/io/exception/Cancel.js +34 -0
  17. package/source/class/qx/io/exception/Exception.js +38 -0
  18. package/source/class/qx/io/exception/Protocol.js +26 -0
  19. package/source/class/qx/io/exception/Transport.js +39 -0
  20. package/source/class/qx/io/exception/__init__.js +4 -0
  21. package/source/class/qx/io/graphql/Client.js +112 -0
  22. package/source/class/qx/io/graphql/__init__.js +9 -0
  23. package/source/class/qx/io/graphql/protocol/Message.js +65 -0
  24. package/source/class/qx/io/graphql/protocol/Request.js +95 -0
  25. package/source/class/qx/io/graphql/protocol/Response.js +61 -0
  26. package/source/class/qx/io/graphql/protocol/__init__.js +6 -0
  27. package/source/class/qx/io/jsonrpc/Client.js +323 -0
  28. package/source/class/qx/io/jsonrpc/__init__.js +15 -0
  29. package/source/class/qx/io/jsonrpc/protocol/Batch.js +97 -0
  30. package/source/class/qx/io/jsonrpc/protocol/Error.js +63 -0
  31. package/source/class/qx/io/jsonrpc/protocol/Message.js +48 -0
  32. package/source/class/qx/io/jsonrpc/protocol/Notification.js +45 -0
  33. package/source/class/qx/io/jsonrpc/protocol/Parser.js +81 -0
  34. package/source/class/qx/io/jsonrpc/protocol/Request.js +93 -0
  35. package/source/class/qx/io/jsonrpc/protocol/Result.js +48 -0
  36. package/source/class/qx/io/jsonrpc/protocol/__init__.js +5 -0
  37. package/source/class/qx/io/request/authentication/Bearer.js +52 -0
  38. package/source/class/qx/io/transport/AbstractClient.js +100 -0
  39. package/source/class/qx/io/transport/AbstractTransport.js +41 -0
  40. package/source/class/qx/io/transport/Fetch.js +95 -0
  41. package/source/class/qx/io/transport/ITransport.js +40 -0
  42. package/source/class/qx/io/transport/PostMessage.js +55 -0
  43. package/source/class/qx/io/transport/Websocket.js +97 -0
  44. package/source/class/qx/io/transport/Xhr.js +139 -0
  45. package/source/class/qx/io/transport/__init__.js +18 -0
  46. package/source/class/qx/test/core/Assert.js +1 -1
  47. package/source/class/qx/test/core/Environment.js +0 -3
  48. package/source/class/qx/test/io/MAssert.js +46 -0
  49. package/source/class/qx/test/io/graphql/Client.js +169 -0
  50. package/source/class/qx/test/io/graphql/ClientFetch.js +34 -0
  51. package/source/class/qx/test/io/graphql/Request.js +42 -0
  52. package/source/class/qx/test/io/jsonrpc/Client.js +267 -0
  53. package/source/class/qx/test/io/jsonrpc/Protocol.js +80 -0
  54. package/source/class/qx/test/io/transport/PostMessage.js +56 -0
  55. package/source/class/qx/test/io/transport/Websocket.js +63 -0
  56. package/source/class/qx/test/ui/embed/Iframe.js +1 -1
  57. package/source/class/qx/test/util/DateFormat.js +45 -6
  58. package/source/class/qx/tool/cli/Cli.js +1 -0
  59. package/source/class/qx/tool/cli/commands/Compile.js +13 -3
  60. package/source/class/qx/tool/cli/commands/Es6ify.js +93 -0
  61. package/source/class/qx/tool/cli/commands/package/Install.js +1 -1
  62. package/source/class/qx/tool/cli/commands/package/Publish.js +14 -0
  63. package/source/class/qx/tool/compiler/ClassFile.js +67 -27
  64. package/source/class/qx/tool/compiler/Es6ify.js +368 -0
  65. package/source/class/qx/tool/compiler/makers/AppMaker.js +2 -1
  66. package/source/class/qx/tool/compiler/targets/Target.js +57 -47
  67. package/source/class/qx/tool/compiler/targets/meta/AbstractJavascriptMeta.js +25 -18
  68. package/source/class/qx/tool/compiler/targets/meta/BootJs.js +16 -16
  69. package/source/class/qx/tool/compiler/targets/meta/PolyfillJs.js +11 -3
  70. package/source/class/qx/tool/compiler/targets/meta/Uglify.js +10 -10
  71. package/source/class/qx/ui/core/Widget.js +70 -0
  72. package/source/class/qx/ui/decoration/MLinearBackgroundGradient.js +2 -1
  73. package/source/class/qx/ui/form/ComboBox.js +8 -3
  74. package/source/class/qx/ui/form/DateField.js +16 -1
  75. package/source/class/qx/ui/form/MenuButton.js +8 -4
  76. package/source/class/qx/ui/form/SelectBox.js +8 -3
  77. package/source/class/qx/ui/menu/AbstractButton.js +12 -8
  78. package/source/class/qx/ui/menu/Menu.js +18 -8
  79. package/source/class/qx/ui/table/pane/Model.js +10 -4
  80. package/source/class/qx/ui/window/Window.js +8 -0
  81. package/source/class/qx/util/format/DateFormat.js +44 -17
  82. package/source/resource/qx/tool/loadsass.js +6 -4
  83. package/source/resource/qx/tool/schema/compile-1-0-0.json +6 -11
  84. package/source/translation/hr.po +297 -0
  85. package/lib/resource/qx/static/blank.gif +0 -0
  86. package/source/class/qx/io/remote/Exchange.js +0 -1063
  87. package/source/class/qx/io/remote/Request.js +0 -1021
  88. package/source/class/qx/io/remote/RequestQueue.js +0 -521
  89. package/source/class/qx/io/remote/Response.js +0 -137
  90. package/source/class/qx/io/remote/Rpc.js +0 -1075
  91. package/source/class/qx/io/remote/RpcError.js +0 -198
  92. package/source/class/qx/io/remote/__init__.js +0 -88
  93. package/source/class/qx/io/remote/transport/Abstract.js +0 -513
  94. package/source/class/qx/io/remote/transport/Iframe.js +0 -652
  95. package/source/class/qx/io/remote/transport/Script.js +0 -475
  96. package/source/class/qx/io/remote/transport/XmlHttp.js +0 -1019
  97. package/source/class/qx/io/remote/transport/__init__.js +0 -3
  98. package/source/class/qx/test/io/remote/AbstractRequest.js +0 -150
  99. package/source/class/qx/test/io/remote/RequestIframe.js +0 -105
  100. package/source/class/qx/test/io/remote/RequestXhr.js +0 -151
  101. package/source/class/qx/test/io/remote/Rpc.js +0 -205
  102. package/source/class/qx/test/io/remote/__init__.js +0 -4
  103. package/source/class/qx/test/io/remote/transport/Iframe.js +0 -67
  104. package/source/class/qx/test/io/remote/transport/XmlHttp.js +0 -133
  105. package/source/class/qx/test/io/remote/transport/__init__.js +0 -4
@@ -1,1075 +0,0 @@
1
- /* ************************************************************************
2
-
3
- qooxdoo - the new era of web development
4
-
5
- http://qooxdoo.org
6
-
7
- Copyright:
8
- 2006 STZ-IDA, Germany, http://www.stz-ida.de
9
- 2006 Derrell Lipman
10
-
11
- License:
12
- MIT: https://opensource.org/licenses/MIT
13
- See the LICENSE file in the project's top-level directory for details.
14
-
15
- Authors:
16
- * Andreas Junghans (lucidcake)
17
- * Derrell Lipman (derrell)
18
-
19
- ************************************************************************ */
20
-
21
- /**
22
- * Provides a Remote Procedure Call (RPC) implementation.
23
- *
24
- * Each instance of this class represents a "Service". These services can
25
- * correspond to various concepts on the server side (depending on the
26
- * programming language/environment being used), but usually, a service means
27
- * a class on the server.
28
- *
29
- * In case multiple instances of the same service are needed, they can be
30
- * distinguished by ids. If such an id is specified, the server routes all
31
- * calls to a service that have the same id to the same server-side instance.
32
- *
33
- * When calling a server-side method, the parameters and return values are
34
- * converted automatically. Supported types are int (and Integer), double
35
- * (and Double), String, Date, Map, and JavaBeans. Beans must have a default
36
- * constructor on the server side and are represented by simple JavaScript
37
- * objects on the client side (used as associative arrays with keys matching
38
- * the server-side properties). Beans can also be nested, but be careful not to
39
- * create circular references! There are no checks to detect these (which would
40
- * be expensive), so you as the user are responsible for avoiding them.
41
- *
42
- * A simple example:
43
- * <pre class='javascript'>
44
- * function callRpcServer ()
45
- * {
46
- * var rpc = new qx.io.remote.Rpc();
47
- * rpc.setTimeout(10000);
48
- * rpc.setUrl("http://127.0.0.1:8007");
49
- * rpc.setServiceName("qooxdoo.admin");
50
- *
51
- * // call a remote procedure -- takes no arguments, returns a string
52
- * var that = this;
53
- * this.RpcRunning = rpc.callAsync(
54
- * function(result, ex, id)
55
- * {
56
- * that.RpcRunning = null;
57
- * if (ex == null) {
58
- * alert(result);
59
- * } else {
60
- * alert("Async(" + id + ") exception: " + ex);
61
- * }
62
- * },
63
- * "fss.getBaseDir");
64
- * }
65
- * </pre>
66
- * __fss.getBaseDir__ is the remote procedure in this case, potential arguments
67
- * would be listed after the procedure name.
68
- * <p>
69
- * Passing data from the client (qooxdoo) side is demonstrated in the
70
- * qooxdoo-contrib project RpcExample. There are three ways to issue a remote
71
- * procedure call: synchronously (qx.io.remote.Rpc.callSync -- dangerous
72
- * because it blocks the whole browser, not just your application, so is
73
- * highly discouraged); async with results via a callback function
74
- * (qx.io.remote.Rpc.callAsync) and async with results via an event listener
75
- * (qx.io.remote.Rpc.callAsyncListeners).
76
- * <p>
77
- * @ignore(qx.core.ServerSettings.*)
78
- */
79
-
80
- qx.Class.define("qx.io.remote.Rpc",
81
- {
82
- extend : qx.core.Object,
83
-
84
-
85
-
86
-
87
- /*
88
- *****************************************************************************
89
- CONSTRUCTOR
90
- *****************************************************************************
91
- */
92
-
93
- /**
94
- * @param url {String} identifies the url where the service
95
- * is found. Note that if the url is to
96
- * a domain (server) other than where the
97
- * qooxdoo script came from, i.e. it is
98
- * cross-domain, then you must also call
99
- * the setCrossDomain(true) method to
100
- * enable the ScriptTransport instead of
101
- * the XmlHttpTransport, since the latter
102
- * can not handle cross-domain requests.
103
- *
104
- * @param serviceName {String} identifies the service. For the Java
105
- * implementation, this is the fully
106
- * qualified name of the class that offers
107
- * the service methods
108
- * (e.g. "my.pkg.MyService").
109
- */
110
- construct : function(url, serviceName)
111
- {
112
- this.base(arguments);
113
-
114
- if (url !== undefined)
115
- {
116
- this.setUrl(url);
117
- }
118
-
119
- if (serviceName != null)
120
- {
121
- this.setServiceName(serviceName);
122
- }
123
-
124
- if (qx.core.ServerSettings)
125
- {
126
- this.__currentServerSuffix = qx.core.ServerSettings.serverPathSuffix;
127
- }
128
- },
129
-
130
-
131
-
132
-
133
- /*
134
- *****************************************************************************
135
- EVENTS
136
- *****************************************************************************
137
- */
138
-
139
- events :
140
- {
141
- /**
142
- * Fired when call is completed.
143
- */
144
- "completed" : "qx.event.type.Event",
145
-
146
- /**
147
- * Fired when call aborted.
148
- */
149
- "aborted" : "qx.event.type.Event",
150
-
151
- /**
152
- * Fired when call failed.
153
- */
154
- "failed" : "qx.event.type.Event",
155
-
156
- /**
157
- * Fired when call timed out.
158
- */
159
- "timeout" : "qx.event.type.Event"
160
- },
161
-
162
-
163
-
164
- /*
165
- *****************************************************************************
166
- STATICS
167
- *****************************************************************************
168
- */
169
-
170
- statics :
171
- {
172
- /**
173
- * Origins of errors
174
- */
175
- origin :
176
- {
177
- server : 1,
178
- application : 2,
179
- transport : 3,
180
- local : 4
181
- },
182
-
183
-
184
- /**
185
- * Locally-detected errors
186
- */
187
- localError :
188
- {
189
- timeout : 1,
190
- abort : 2,
191
- nodata : 3
192
- },
193
-
194
-
195
- /**
196
- * Boolean flag which controls the stringification of date objects.
197
- * <code>null</code> for the default behavior, acts like false
198
- * <code>true</code> for stringifying dates the old, qooxdoo specific way
199
- * <code>false</code> using the native toJSON of date objects.
200
- *
201
- * When enabled, dates are converted to and parsed from
202
- * a literal that complies to the format
203
- *
204
- * <code>new Date(Date.UTC(year,month,day,hour,min,sec,ms))</code>
205
- *
206
- * The server can fairly easily parse this in its JSON
207
- * implementation by stripping off "new Date(Date.UTC("
208
- * from the beginning of the string, and "))" from the
209
- * end of the string. What remains is the set of
210
- * comma-separated date components, which are also very
211
- * easy to parse.
212
- *
213
- * The work-around compensates for the fact that while the
214
- * Date object is a primitive type in Javascript, the
215
- * specification neglects to provide a literal form for it.
216
- */
217
- CONVERT_DATES : null,
218
-
219
-
220
- /**
221
- * Boolean flag which controls whether to expect and verify a JSON
222
- * response.
223
- *
224
- * Should be <code>true</code> when backend returns valid JSON.
225
- *
226
- * Date literals are parsed when CONVERT_DATES is <code>true</code>
227
- * and comply to the format
228
- *
229
- * <code>"new Date(Date.UTC(year,month,day,hour,min,sec,ms))"</code>
230
- *
231
- * Note the surrounding quotes that encode the literal as string.
232
- *
233
- * Using valid JSON is recommended, because it allows to use
234
- * {@link qx.lang.Json#parse} for parsing. {@link qx.lang.Json#parse}
235
- * is preferred over the potentially insecure <code>eval</code>.
236
- */
237
- RESPONSE_JSON : null,
238
-
239
-
240
- /**
241
- * Creates an URL for talking to a local service. A local service is one that
242
- * lives in the same application as the page calling the service. For backends
243
- * that don't support this auto-generation, this method returns null.
244
- *
245
- * @param instanceId {String ? null} an optional identifier for the
246
- * server side instance that should be
247
- * used. All calls to the same service
248
- * with the same instance id are
249
- * routed to the same object instance
250
- * on the server. The instance id can
251
- * also be used to provide additional
252
- * data for the service instantiation
253
- * on the server.
254
- * @return {String} the url.
255
- */
256
- makeServerURL : function(instanceId)
257
- {
258
- var retVal = null;
259
-
260
- if (qx.core.ServerSettings)
261
- {
262
- retVal =
263
- qx.core.ServerSettings.serverPathPrefix +
264
- "/.qxrpc" +
265
- qx.core.ServerSettings.serverPathSuffix;
266
-
267
- if (instanceId != null)
268
- {
269
- retVal += "?instanceId=" + instanceId;
270
- }
271
- }
272
-
273
- return retVal;
274
- }
275
- },
276
-
277
-
278
-
279
-
280
- /*
281
- *****************************************************************************
282
- PROPERTIES
283
- *****************************************************************************
284
- */
285
-
286
- properties :
287
- {
288
- /*
289
- ---------------------------------------------------------------------------
290
- PROPERTIES
291
- ---------------------------------------------------------------------------
292
- */
293
-
294
- /** The timeout for asynchronous calls in milliseconds. */
295
- timeout :
296
- {
297
- check : "Integer",
298
- nullable : true
299
- },
300
-
301
-
302
- /**
303
- * Indicate that the request is cross domain.
304
- *
305
- * A request is cross domain if the request's URL points to a host other
306
- * than the local host. This switches the concrete implementation that is
307
- * used for sending the request from qx.io.remote.transport.XmlHttp to
308
- * qx.io.remote.transport.Script because only the latter can handle cross
309
- * domain requests.
310
- */
311
- crossDomain :
312
- {
313
- check : "Boolean",
314
- init : false
315
- },
316
-
317
-
318
- /** The URL at which the service is located. */
319
- url :
320
- {
321
- check : "String",
322
- nullable : true
323
- },
324
-
325
-
326
- /** The service name. */
327
- serviceName :
328
- {
329
- check : "String",
330
- nullable : true
331
- },
332
-
333
-
334
- /**
335
- * Data sent as "out of band" data in the request to the server. The
336
- * format of the data is opaque to RPC and may be recognized only by
337
- * particular servers It is up to the server to decide what to do with
338
- * it: whether to ignore it, handle it locally before calling the
339
- * specified method, or pass it on to the method. This server data is
340
- * not sent to the server if it has been set to 'null'.
341
- */
342
- serverData :
343
- {
344
- check : "Object",
345
- nullable : true
346
- },
347
-
348
-
349
- /**
350
- * Username to use for HTTP authentication. Null if HTTP authentication
351
- * is not used.
352
- */
353
- username :
354
- {
355
- check : "String",
356
- nullable : true
357
- },
358
-
359
-
360
- /**
361
- * Password to use for HTTP authentication. Null if HTTP authentication
362
- * is not used.
363
- */
364
- password :
365
- {
366
- check : "String",
367
- nullable : true
368
- },
369
-
370
-
371
- /**
372
- Use Basic HTTP Authentication
373
- */
374
- useBasicHttpAuth :
375
- {
376
- check : "Boolean",
377
- nullable : true
378
- },
379
-
380
- /**
381
- *
382
- * Whether to use the original qooxdoo RPC protocol or the
383
- * now-standardized Version 2 protocol. Defaults to the original qooxdoo
384
- * protocol for backward compatibility.
385
- *
386
- * Valid values are "qx1" and "2.0".
387
- */
388
- protocol :
389
- {
390
- init : "2.0",
391
- check : function(val) { return val == "qx1" || val == "2.0"; }
392
- }
393
- },
394
-
395
-
396
-
397
- /*
398
- *****************************************************************************
399
- MEMBERS
400
- *****************************************************************************
401
- */
402
-
403
- members :
404
- {
405
-
406
- __previousServerSuffix : null,
407
- __currentServerSuffix : null,
408
-
409
- /**
410
- * Factory method to create a request object. By default, a POST request
411
- * will be made, and the expected response type will be
412
- * "application/json". Classes extending this one may override this method
413
- * to obtain a Request object with different parameters.
414
- *
415
- * @return {qx.io.remote.Request}
416
- */
417
- createRequest: function()
418
- {
419
- return new qx.io.remote.Request(this.getUrl(),
420
- "POST",
421
- "application/json");
422
- },
423
-
424
- /**
425
- * Factory method to create the object containing the remote procedure
426
- * call data. By default, a qooxdoo-style RPC request is built, which
427
- * contains the following members: "service", "method", "id", and
428
- * "params". If a different style of RPC request is desired, a class
429
- * extending this one may override this method.
430
- *
431
- * @param id {Integer}
432
- * The unique sequence number of this request.
433
- *
434
- * @param method {String}
435
- * The name of the method to be called
436
- *
437
- * @param parameters {Array}
438
- * An array containing the arguments to the called method.
439
- *
440
- * @param serverData {var}
441
- * "Out-of-band" data to be provided to the server.
442
- *
443
- * @return {Object}
444
- * The object to be converted to JSON and passed to the JSON-RPC
445
- * server.
446
- */
447
- createRpcData: function(id, method, parameters, serverData)
448
- {
449
- var requestObject;
450
- var service;
451
-
452
- // Create a protocol-dependent request object
453
- if (this.getProtocol() == "qx1")
454
- {
455
- // Create a qooxdoo-modified version 1.0 rpc data object
456
- requestObject =
457
- {
458
- "service" :
459
- method == "refreshSession" ? null : this.getServiceName(),
460
- "method" : method,
461
- "id" : id,
462
- "params" : parameters
463
- };
464
-
465
- // Only add the server_data member if there is actually server data
466
- if (serverData)
467
- {
468
- requestObject.server_data = serverData;
469
- }
470
- }
471
- else
472
- {
473
- // If there's a service name, we'll prepend it to the method name
474
- service = this.getServiceName();
475
- if (service && service != "")
476
- {
477
- service += ".";
478
- }
479
- else
480
- {
481
- service = "";
482
- }
483
-
484
- // Create a standard version 2.0 rpc data object
485
- requestObject =
486
- {
487
- "jsonrpc" : "2.0",
488
- "method" : service + method,
489
- "id" : id,
490
- "params" : parameters
491
- };
492
- }
493
-
494
- return requestObject;
495
- },
496
-
497
-
498
- /**
499
- * Internal RPC call method
500
- *
501
- * @lint ignoreDeprecated(eval)
502
- *
503
- * @param args {Array}
504
- * array of arguments
505
- *
506
- * @param callType {Integer}
507
- * 0 = sync,
508
- * 1 = async with handler,
509
- * 2 = async event listeners
510
- *
511
- * @param refreshSession {Boolean}
512
- * whether a new session should be requested
513
- *
514
- * @return {var} the method call reference.
515
- * @throws {Error} An error.
516
- */
517
- _callInternal : function(args, callType, refreshSession)
518
- {
519
- var self = this;
520
- var offset = (callType == 0 ? 0 : 1);
521
- var whichMethod = (refreshSession ? "refreshSession" : args[offset]);
522
- var handler = args[0];
523
- var argsArray = [];
524
- var eventTarget = this;
525
- var protocol = this.getProtocol();
526
-
527
- for (var i=offset+1; i<args.length; ++i)
528
- {
529
- argsArray.push(args[i]);
530
- }
531
-
532
- var req = this.createRequest();
533
-
534
- // Get any additional out-of-band data to be sent to the server
535
- var serverData = this.getServerData();
536
-
537
- // Create the request object
538
- var rpcData = this.createRpcData(req.getSequenceNumber(),
539
- whichMethod,
540
- argsArray,
541
- serverData);
542
-
543
- req.setCrossDomain(this.getCrossDomain());
544
-
545
- if (this.getUsername())
546
- {
547
- req.setUseBasicHttpAuth(this.getUseBasicHttpAuth());
548
- req.setUsername(this.getUsername());
549
- req.setPassword(this.getPassword());
550
- }
551
-
552
- req.setTimeout(this.getTimeout());
553
- var ex = null;
554
- var id = null;
555
- var result = null;
556
- var response = null;
557
-
558
- var handleRequestFinished = function(eventType, eventTarget)
559
- {
560
- switch(callType)
561
- {
562
- case 0: // sync
563
- break;
564
-
565
- case 1: // async with handler function
566
- try
567
- {
568
- handler(result, ex, id);
569
- }
570
- catch(e)
571
- {
572
- eventTarget.error(
573
- "rpc handler threw an error:" +
574
- " id=" + id +
575
- " result=" + qx.lang.Json.stringify(result) +
576
- " ex=" + qx.lang.Json.stringify(ex),
577
- e);
578
- }
579
- break;
580
-
581
- case 2: // async with event listeners
582
- // Dispatch the event to our listeners.
583
- if (!ex)
584
- {
585
- eventTarget.fireDataEvent(eventType, response);
586
- }
587
- else
588
- {
589
- // Add the id to the exception
590
- ex.id = id;
591
-
592
- if (args[0]) // coalesce
593
- {
594
- // They requested that we coalesce all failure types to
595
- // "failed"
596
- eventTarget.fireDataEvent("failed", ex);
597
- }
598
- else
599
- {
600
- // No coalese so use original event type
601
- eventTarget.fireDataEvent(eventType, ex);
602
- }
603
- }
604
- }
605
- };
606
-
607
- var addToStringToObject = function(obj)
608
- {
609
- if (protocol == "qx1")
610
- {
611
- obj.toString = function()
612
- {
613
- switch(obj.origin)
614
- {
615
- case qx.io.remote.Rpc.origin.server:
616
- return "Server error " + obj.code + ": " + obj.message;
617
-
618
- case qx.io.remote.Rpc.origin.application:
619
- return "Application error " + obj.code + ": " + obj.message;
620
-
621
- case qx.io.remote.Rpc.origin.transport:
622
- return "Transport error " + obj.code + ": " + obj.message;
623
-
624
- case qx.io.remote.Rpc.origin.local:
625
- return "Local error " + obj.code + ": " + obj.message;
626
-
627
- default:
628
- return ("UNEXPECTED origin " + obj.origin +
629
- " error " + obj.code + ": " + obj.message);
630
- }
631
- };
632
- }
633
- else // protocol == "2.0"
634
- {
635
- obj.toString = function()
636
- {
637
- var ret;
638
-
639
- ret = "Error " + obj.code + ": " + obj.message;
640
- if (obj.data)
641
- {
642
- ret += " (" + obj.data + ")";
643
- }
644
-
645
- return ret;
646
- };
647
- }
648
- };
649
-
650
- var makeException = function(origin, code, message)
651
- {
652
- var ex = {};
653
- if (protocol == "qx1")
654
- {
655
- ex.origin = origin;
656
- }
657
- ex.code = code;
658
- ex.message = message;
659
- addToStringToObject(ex);
660
- return ex;
661
- };
662
-
663
- req.addListener("failed", function(evt)
664
- {
665
- var code = evt.getStatusCode();
666
- ex = makeException(qx.io.remote.Rpc.origin.transport,
667
- code,
668
- qx.io.remote.Exchange.statusCodeToString(code));
669
- id = this.getSequenceNumber();
670
- handleRequestFinished("failed", eventTarget);
671
- });
672
-
673
- req.addListener("timeout", function(evt)
674
- {
675
- this.debug("TIMEOUT OCCURRED");
676
- ex = makeException(qx.io.remote.Rpc.origin.local,
677
- qx.io.remote.Rpc.localError.timeout,
678
- "Local time-out expired for "+ whichMethod);
679
- id = this.getSequenceNumber();
680
- handleRequestFinished("timeout", eventTarget);
681
- });
682
-
683
- req.addListener("aborted", function(evt)
684
- {
685
- ex = makeException(qx.io.remote.Rpc.origin.local,
686
- qx.io.remote.Rpc.localError.abort,
687
- "Aborted " + whichMethod);
688
- id = this.getSequenceNumber();
689
- handleRequestFinished("aborted", eventTarget);
690
- });
691
-
692
- req.addListener("completed", function(evt)
693
- {
694
- response = evt.getContent();
695
-
696
- // server may have reset, giving us no data on our requests
697
- if (response === null)
698
- {
699
- ex = makeException(qx.io.remote.Rpc.origin.local,
700
- qx.io.remote.Rpc.localError.nodata,
701
- "No data in response to " + whichMethod);
702
- id = this.getSequenceNumber();
703
- handleRequestFinished("failed", eventTarget);
704
- return;
705
- }
706
-
707
- // Parse. Skip when response is already an object
708
- // because the script transport was used.
709
- if (!qx.lang.Type.isObject(response)) {
710
-
711
- // Handle converted dates
712
- if (self._isConvertDates()) {
713
-
714
- // Parse as JSON and revive date literals
715
- if (self._isResponseJson()) {
716
- response = qx.lang.Json.parse(response, function(key, value) {
717
- if (value && typeof value === "string") {
718
- if (value.indexOf("new Date(Date.UTC(") >= 0) {
719
- var m = value.match(/new Date\(Date.UTC\((\d+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)\)\)/);
720
- return new Date(Date.UTC(m[1],m[2],m[3],m[4],m[5],m[6],m[7]));
721
- }
722
- }
723
- return value;
724
- });
725
-
726
- // Eval
727
- } else {
728
- response = response && response.length > 0 ? eval('(' + response + ')') : null;
729
- }
730
-
731
- // No special date handling required, JSON assumed
732
- } else {
733
- response = qx.lang.Json.parse(response);
734
- }
735
- }
736
-
737
- id = response["id"];
738
-
739
- if (id != this.getSequenceNumber())
740
- {
741
- this.warn("Received id (" + id + ") does not match requested id " +
742
- "(" + this.getSequenceNumber() + ")!");
743
- }
744
-
745
- // Determine if an error was returned. Assume no error, initially.
746
- var eventType = "completed";
747
- var exTest = response["error"];
748
-
749
- if (exTest != null)
750
- {
751
- // There was an error
752
- result = null;
753
- addToStringToObject(exTest);
754
- ex = exTest;
755
-
756
- // Change the event type
757
- eventType = "failed";
758
- }
759
- else
760
- {
761
- result = response["result"];
762
-
763
- if (refreshSession)
764
- {
765
- result = eval("(" + result + ")");
766
- var newSuffix = qx.core.ServerSettings.serverPathSuffix;
767
-
768
- if (self.__currentServerSuffix != newSuffix)
769
- {
770
- self.__previousServerSuffix = self.__currentServerSuffix;
771
- self.__currentServerSuffix = newSuffix;
772
- }
773
-
774
- self.setUrl(self.fixUrl(self.getUrl()));
775
- }
776
- }
777
-
778
- handleRequestFinished(eventType, eventTarget);
779
- });
780
-
781
- // Provide a replacer when convert dates is enabled
782
- var replacer = null;
783
- if (this._isConvertDates()) {
784
- replacer = function(key, value) {
785
- // The value passed in is of type string, because the Date's
786
- // toJson gets applied before. Get value from containing object.
787
- value = this[key];
788
-
789
- if (qx.lang.Type.isDate(value)) {
790
- var dateParams =
791
- value.getUTCFullYear() + "," +
792
- value.getUTCMonth() + "," +
793
- value.getUTCDate() + "," +
794
- value.getUTCHours() + "," +
795
- value.getUTCMinutes() + "," +
796
- value.getUTCSeconds() + "," +
797
- value.getUTCMilliseconds();
798
- return "new Date(Date.UTC(" + dateParams + "))";
799
- }
800
- return value;
801
- };
802
- }
803
-
804
- req.setData(qx.lang.Json.stringify(rpcData, replacer));
805
- req.setAsynchronous(callType > 0);
806
-
807
- if (req.getCrossDomain())
808
- {
809
- // Our choice here has no effect anyway. This is purely informational.
810
- req.setRequestHeader("Content-Type",
811
- "application/x-www-form-urlencoded");
812
- }
813
- else
814
- {
815
- // When not cross-domain, set type to text/json
816
- req.setRequestHeader("Content-Type", "application/json");
817
- }
818
-
819
- // Do not parse as JSON. Later done conditionally.
820
- req.setParseJson(false);
821
-
822
- req.send();
823
-
824
- if (callType == 0)
825
- {
826
- if (ex != null)
827
- {
828
- var error = new Error(ex.toString());
829
- error.rpcdetails = ex;
830
- throw error;
831
- }
832
-
833
- return result;
834
- }
835
- else
836
- {
837
- return req;
838
- }
839
- },
840
-
841
-
842
- /**
843
- * Helper method to rewrite a URL with a stale session id (so that it includes
844
- * the correct session id afterwards).
845
- *
846
- * @param url {String} the URL to examine.
847
- * @return {String} the (possibly re-written) URL.
848
- */
849
- fixUrl : function(url)
850
- {
851
- if (this.__previousServerSuffix == null ||
852
- this.__currentServerSuffix == null ||
853
- this.__previousServerSuffix == "" ||
854
- this.__previousServerSuffix == this.__currentServerSuffix)
855
- {
856
- return url;
857
- }
858
-
859
- var index = url.indexOf(this.__previousServerSuffix);
860
-
861
- if (index == -1)
862
- {
863
- return url;
864
- }
865
-
866
- return (url.substring(0, index) +
867
- this.__currentServerSuffix +
868
- url.substring(index + this.__previousServerSuffix.length));
869
- },
870
-
871
-
872
- /**
873
- * Makes a synchronous server call. The method arguments (if any) follow
874
- * after the method name (as normal JavaScript arguments, separated by
875
- * commas, not as an array).
876
- *
877
- * If a problem occurs when making the call, an exception is thrown.
878
- *
879
- *
880
- * WARNING. With some browsers, the synchronous interface
881
- * causes the browser to hang while awaiting a response! If the server
882
- * decides to pause for a minute or two, your browser may do nothing
883
- * (including refreshing following window changes) until the response is
884
- * received. Instead, use the asynchronous interface.
885
- *
886
- *
887
- * YOU HAVE BEEN WARNED.
888
- *
889
- *
890
- * @param methodName {String} the name of the method to call.
891
- * @param args {Array} an array of values passed through to the backend.
892
- * @return {var} the result returned by the server.
893
- */
894
- callSync : function(methodName,args)
895
- {
896
- return this._callInternal(arguments, 0);
897
- },
898
-
899
-
900
- /**
901
- * Makes an asynchronous server call. The method arguments (if any) follow
902
- * after the method name (as normal JavaScript arguments, separated by
903
- * commas, not as an array).
904
- *
905
- * When an answer from the server arrives, the <code>handler</code>
906
- * function is called with the result of the call as the first, an
907
- * exception as the second parameter, and the id (aka sequence number) of
908
- * the invoking request as the third parameter. If the call was
909
- * successful, the second parameter is <code>null</code>. If there was a
910
- * problem, the second parameter contains an exception, and the first one
911
- * is <code>null</code>.
912
- *
913
- *
914
- * The return value of this method is a call reference that you can store
915
- * if you want to abort the request later on. This value should be treated
916
- * as opaque and can change completely in the future! The only thing you
917
- * can rely on is that the <code>abort</code> method will accept this
918
- * reference and that you can retrieve the sequence number of the request
919
- * by invoking the getSequenceNumber() method (see below).
920
- *
921
- *
922
- * If a specific method is being called, asynchronously, a number of times
923
- * in succession, the getSequenceNumber() method may be used to
924
- * disambiguate which request a response corresponds to. The sequence
925
- * number value is a value which increments with each request.)
926
- *
927
- *
928
- * @param handler {Function} the callback function.
929
- * @param methodName {String} the name of the method to call.
930
- * @param args {Array} an array of values passed through to the backend.
931
- * @return {var} the method call reference.
932
- */
933
- callAsync : function(handler, methodName, args)
934
- {
935
- return this._callInternal(arguments, 1);
936
- },
937
-
938
-
939
- /**
940
- * Makes an asynchronous server call and dispatches an event upon completion
941
- * or failure. The method arguments (if any) follow after the method name
942
- * (as normal JavaScript arguments, separated by commas, not as an array).
943
- *
944
- * When an answer from the server arrives (or fails to arrive on time), if
945
- * an exception occurred, a "failed", "timeout" or "aborted" event, as
946
- * appropriate, is dispatched to any waiting event listeners. If no
947
- * exception occurred, a "completed" event is dispatched.
948
- *
949
- *
950
- * When a "failed", "timeout" or "aborted" event is dispatched, the event
951
- * data contains an object with the properties 'origin', 'code', 'message'
952
- * and 'id'. The object has a toString() function which may be called to
953
- * convert the exception to a string.
954
- *
955
- *
956
- * When a "completed" event is dispatched, the event data contains a
957
- * map with the JSON-RPC sequence number and result:
958
- * <p>
959
- * {
960
- * id: rpc_id,
961
- * result: json-rpc result
962
- * }
963
- *
964
- *
965
- * The return value of this method is a call reference that you can store
966
- * if you want to abort the request later on. This value should be treated
967
- * as opaque and can change completely in the future! The only thing you
968
- * can rely on is that the <code>abort</code> method will accept this
969
- * reference and that you can retrieve the sequence number of the request
970
- * by invoking the getSequenceNumber() method (see below).
971
- *
972
- *
973
- * If a specific method is being called, asynchronously, a number of times
974
- * in succession, the getSequenceNumber() method may be used to
975
- * disambiguate which request a response corresponds to. The sequence
976
- * number value is a value which increments with each request.)
977
- *
978
- *
979
- * @param coalesce {Boolean} coalesce all failure types ("failed",
980
- * "timeout", and "aborted") to "failed".
981
- * This is reasonable in many cases, as
982
- * the provided exception contains adequate
983
- * disambiguating information.
984
- * @param methodName {String} the name of the method to call.
985
- * @param args {Array} an array of values passed through to the backend.
986
- * @return {var} the method call reference.
987
- */
988
- callAsyncListeners : function(coalesce, methodName, args)
989
- {
990
- return this._callInternal(arguments, 2);
991
- },
992
-
993
-
994
- /**
995
- * Refreshes a server session by retrieving the session id again from the
996
- * server.
997
- *
998
- * The specified handler function is called when the refresh is
999
- * complete. The first parameter can be <code>true</code> (indicating that
1000
- * a refresh either wasn't necessary at this time or it was successful) or
1001
- * <code>false</code> (indicating that a refresh would have been necessary
1002
- * but can't be performed because the server backend doesn't support
1003
- * it). If there is a non-null second parameter, it's an exception
1004
- * indicating that there was an error when refreshing the session.
1005
- *
1006
- *
1007
- * @param handler {Function} a callback function that is called when the
1008
- * refresh is complete (or failed).
1009
- */
1010
- refreshSession : function(handler)
1011
- {
1012
- if (qx.core.ServerSettings &&
1013
- qx.core.ServerSettings.serverPathSuffix)
1014
- {
1015
- var timeDiff =
1016
- (new Date()).getTime() - qx.core.ServerSettings.lastSessionRefresh;
1017
-
1018
- if (timeDiff / 1000 >
1019
- (qx.core.ServerSettings.sessionTimeoutInSeconds - 30))
1020
- {
1021
- // this.info("refreshing session");
1022
- this._callInternal([ handler ], 1, true);
1023
- }
1024
- else
1025
- {
1026
- handler(true); // session refresh was OK (in this case: not needed)
1027
- }
1028
- }
1029
- else
1030
- {
1031
- handler(false); // no refresh possible, but would be necessary
1032
- }
1033
- },
1034
-
1035
-
1036
- /**
1037
- * Whether to convert date objects to pseudo literals and
1038
- * parse with eval.
1039
- *
1040
- * Controlled by {@link #CONVERT_DATES}.
1041
- *
1042
- * @return {Boolean} Whether to convert.
1043
- */
1044
- _isConvertDates: function() {
1045
- return !!(qx.io.remote.Rpc.CONVERT_DATES);
1046
- },
1047
-
1048
-
1049
- /**
1050
- * Whether to expect and verify a JSON response.
1051
- *
1052
- * Controlled by {@link #RESPONSE_JSON}.
1053
- *
1054
- * @return {Boolean} Whether to expect JSON.
1055
- */
1056
- _isResponseJson: function() {
1057
- return !!(qx.io.remote.Rpc.RESPONSE_JSON);
1058
- },
1059
-
1060
-
1061
- /**
1062
- * Aborts an asynchronous server call. Consequently, the callback function
1063
- * provided to <code>callAsync</code> or <code>callAsyncListeners</code>
1064
- * will be called with an exception.
1065
- *
1066
- * @param opaqueCallRef {var} the call reference as returned by
1067
- * <code>callAsync</code> or
1068
- * <code>callAsyncListeners</code>
1069
- */
1070
- abort : function(opaqueCallRef)
1071
- {
1072
- opaqueCallRef.abort();
1073
- }
1074
- }
1075
- });