@qooxdoo/framework 7.0.0-beta.5 → 7.0.0-beta.6
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.
- package/CHANGELOG.md +3 -0
- package/Manifest.json +1 -1
- package/README.md +7 -3
- package/lib/compiler/compile-info.json +67 -67
- package/lib/compiler/index.js +2176 -1397
- package/lib/resource/qx/tool/loadsass.js +6 -4
- package/package.json +15 -2
- package/source/class/qx/io/__init__.js +5 -3
- package/source/class/qx/io/exception/Cancel.js +34 -0
- package/source/class/qx/io/exception/Exception.js +38 -0
- package/source/class/qx/io/exception/Protocol.js +26 -0
- package/source/class/qx/io/exception/Transport.js +39 -0
- package/source/class/qx/io/exception/__init__.js +4 -0
- package/source/class/qx/io/graphql/Client.js +112 -0
- package/source/class/qx/io/graphql/__init__.js +9 -0
- package/source/class/qx/io/graphql/protocol/Message.js +65 -0
- package/source/class/qx/io/graphql/protocol/Request.js +95 -0
- package/source/class/qx/io/graphql/protocol/Response.js +61 -0
- package/source/class/qx/io/graphql/protocol/__init__.js +6 -0
- package/source/class/qx/io/jsonrpc/Client.js +323 -0
- package/source/class/qx/io/jsonrpc/__init__.js +15 -0
- package/source/class/qx/io/jsonrpc/protocol/Batch.js +97 -0
- package/source/class/qx/io/jsonrpc/protocol/Error.js +63 -0
- package/source/class/qx/io/jsonrpc/protocol/Message.js +48 -0
- package/source/class/qx/io/jsonrpc/protocol/Notification.js +45 -0
- package/source/class/qx/io/jsonrpc/protocol/Parser.js +81 -0
- package/source/class/qx/io/jsonrpc/protocol/Request.js +93 -0
- package/source/class/qx/io/jsonrpc/protocol/Result.js +48 -0
- package/source/class/qx/io/jsonrpc/protocol/__init__.js +5 -0
- package/source/class/qx/io/request/authentication/Bearer.js +52 -0
- package/source/class/qx/io/transport/AbstractClient.js +100 -0
- package/source/class/qx/io/transport/AbstractTransport.js +41 -0
- package/source/class/qx/io/transport/Fetch.js +95 -0
- package/source/class/qx/io/transport/ITransport.js +40 -0
- package/source/class/qx/io/transport/PostMessage.js +55 -0
- package/source/class/qx/io/transport/Websocket.js +97 -0
- package/source/class/qx/io/transport/Xhr.js +139 -0
- package/source/class/qx/io/transport/__init__.js +18 -0
- package/source/class/qx/test/io/MAssert.js +46 -0
- package/source/class/qx/test/io/graphql/Client.js +169 -0
- package/source/class/qx/test/io/graphql/ClientFetch.js +34 -0
- package/source/class/qx/test/io/graphql/Request.js +42 -0
- package/source/class/qx/test/io/jsonrpc/Client.js +267 -0
- package/source/class/qx/test/io/jsonrpc/Protocol.js +80 -0
- package/source/class/qx/test/io/transport/PostMessage.js +56 -0
- package/source/class/qx/test/io/transport/Websocket.js +63 -0
- package/source/class/qx/test/ui/embed/Iframe.js +1 -1
- package/source/class/qx/test/util/DateFormat.js +45 -6
- package/source/class/qx/tool/cli/commands/Compile.js +3 -3
- package/source/class/qx/tool/cli/commands/package/Publish.js +14 -0
- package/source/class/qx/tool/compiler/makers/AppMaker.js +2 -1
- package/source/class/qx/tool/compiler/targets/Target.js +2 -1
- package/source/class/qx/tool/compiler/targets/meta/PolyfillJs.js +11 -3
- package/source/class/qx/ui/form/ComboBox.js +8 -3
- package/source/class/qx/ui/form/MenuButton.js +8 -4
- package/source/class/qx/ui/form/SelectBox.js +8 -3
- package/source/class/qx/ui/menu/AbstractButton.js +12 -8
- package/source/class/qx/ui/menu/Menu.js +18 -8
- package/source/class/qx/ui/table/pane/Model.js +10 -4
- package/source/class/qx/util/format/DateFormat.js +44 -17
- package/source/resource/qx/tool/loadsass.js +6 -4
- package/source/translation/hr.po +297 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/* ************************************************************************
|
|
2
|
+
|
|
3
|
+
qooxdoo - the new era of web development
|
|
4
|
+
|
|
5
|
+
http://qooxdoo.org
|
|
6
|
+
|
|
7
|
+
Copyright:
|
|
8
|
+
2020 Christian Boulanger
|
|
9
|
+
|
|
10
|
+
License:
|
|
11
|
+
MIT: https://opensource.org/licenses/MIT
|
|
12
|
+
See the LICENSE file in the project's top-level directory for details.
|
|
13
|
+
|
|
14
|
+
Authors:
|
|
15
|
+
* Christian Boulanger (cboulanger)
|
|
16
|
+
|
|
17
|
+
************************************************************************ */
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A JSON-RPC v2.0 request object
|
|
21
|
+
*
|
|
22
|
+
* @see https://www.jsonrpc.org/specification#request_object
|
|
23
|
+
*/
|
|
24
|
+
qx.Class.define("qx.io.jsonrpc.protocol.Request", {
|
|
25
|
+
extend: qx.io.jsonrpc.protocol.Notification,
|
|
26
|
+
statics: {
|
|
27
|
+
/**
|
|
28
|
+
* Static counter for all request ids
|
|
29
|
+
*/
|
|
30
|
+
__current_request_id : 0,
|
|
31
|
+
|
|
32
|
+
getCurrentId() {
|
|
33
|
+
return qx.io.jsonrpc.protocol.Request.__current_request_id;
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
resetId() {
|
|
37
|
+
qx.io.jsonrpc.protocol.Request.__current_request_id = 0;
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
properties: {
|
|
41
|
+
/**
|
|
42
|
+
* The integer id of the request
|
|
43
|
+
*/
|
|
44
|
+
id : {
|
|
45
|
+
check: value => qx.lang.Type.isNumber(value) && parseInt(value, 10) === value
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* JSON-RPC request constructor
|
|
51
|
+
* @param {String} method
|
|
52
|
+
* @param {Array|Object?} params
|
|
53
|
+
* @param {Number?} id
|
|
54
|
+
* Optional integer id. If not provided, an auto-incremented id will be
|
|
55
|
+
* used.
|
|
56
|
+
*/
|
|
57
|
+
construct(method, params, id) {
|
|
58
|
+
this.base(arguments, method, params);
|
|
59
|
+
if (id === undefined) {
|
|
60
|
+
id = ++qx.io.jsonrpc.protocol.Request.__current_request_id;
|
|
61
|
+
}
|
|
62
|
+
this.set({id});
|
|
63
|
+
this.__promise = new qx.Promise();
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
members: {
|
|
67
|
+
|
|
68
|
+
__promise : null,
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Getter for promise which resolves with the result to the request
|
|
72
|
+
* @return {qx.Promise}
|
|
73
|
+
*/
|
|
74
|
+
getPromise() {
|
|
75
|
+
return this.__promise;
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Determines how an exception during transport is handled. Standard
|
|
80
|
+
* behavior is to reject the request's promise with that exception.
|
|
81
|
+
* Classes inheriting from this class might handle it differently, i.e.
|
|
82
|
+
* by allowing the transport to retry after a timeout occurred.
|
|
83
|
+
* @param {qx.io.exception.Transport} exception
|
|
84
|
+
*/
|
|
85
|
+
handleTransportException(exception) {
|
|
86
|
+
try {
|
|
87
|
+
this.getPromise().reject(exception);
|
|
88
|
+
} catch (e) {
|
|
89
|
+
this.warn("Promise has already been rejected");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/* ************************************************************************
|
|
2
|
+
|
|
3
|
+
qooxdoo - the new era of web development
|
|
4
|
+
|
|
5
|
+
http://qooxdoo.org
|
|
6
|
+
|
|
7
|
+
Copyright:
|
|
8
|
+
2020 Christian Boulanger
|
|
9
|
+
|
|
10
|
+
License:
|
|
11
|
+
MIT: https://opensource.org/licenses/MIT
|
|
12
|
+
See the LICENSE file in the project's top-level directory for details.
|
|
13
|
+
|
|
14
|
+
Authors:
|
|
15
|
+
* Christian Boulanger (cboulanger)
|
|
16
|
+
|
|
17
|
+
************************************************************************ */
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A JSON-RPC v2.0 result object, which is a response to a {@link qx.io.jsonrpc.protocol.Request},
|
|
21
|
+
* indicating a successfully processed request.
|
|
22
|
+
*
|
|
23
|
+
* @see https://www.jsonrpc.org/specification#response_object
|
|
24
|
+
*/
|
|
25
|
+
qx.Class.define("qx.io.jsonrpc.protocol.Result",{
|
|
26
|
+
extend: qx.io.jsonrpc.protocol.Message,
|
|
27
|
+
properties: {
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The integer id of the request
|
|
31
|
+
*/
|
|
32
|
+
id : {
|
|
33
|
+
check: value => qx.lang.Type.isNumber(value) && parseInt(value, 10) === value
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
result : {
|
|
37
|
+
nullable: true
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
/**
|
|
41
|
+
* The result messsage constructor
|
|
42
|
+
* @param {Number} id^
|
|
43
|
+
* @param {*} result
|
|
44
|
+
*/
|
|
45
|
+
construct(id, result) {
|
|
46
|
+
this.set({id, result})
|
|
47
|
+
}
|
|
48
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/* ************************************************************************
|
|
2
|
+
|
|
3
|
+
qooxdoo - the new era of web development
|
|
4
|
+
|
|
5
|
+
http://qooxdoo.org
|
|
6
|
+
|
|
7
|
+
Copyright:
|
|
8
|
+
2004-2011 1&1 Internet AG, Germany, http://www.1und1.de
|
|
9
|
+
|
|
10
|
+
License:
|
|
11
|
+
MIT: https://opensource.org/licenses/MIT
|
|
12
|
+
See the LICENSE file in the project's top-level directory for details.
|
|
13
|
+
|
|
14
|
+
Authors:
|
|
15
|
+
* Tristan Koch (tristankoch)
|
|
16
|
+
* Christian Boulanger (cboulanger)
|
|
17
|
+
|
|
18
|
+
************************************************************************ */
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Bearer (token) authentication.
|
|
22
|
+
*/
|
|
23
|
+
qx.Class.define("qx.io.request.authentication.Bearer",
|
|
24
|
+
{
|
|
25
|
+
|
|
26
|
+
extend: qx.core.Object,
|
|
27
|
+
|
|
28
|
+
implement: qx.io.request.authentication.IAuthentication,
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param token {string} The token to use.
|
|
32
|
+
*/
|
|
33
|
+
construct : function(token)
|
|
34
|
+
{
|
|
35
|
+
this.__credentials = token;
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
members :
|
|
39
|
+
{
|
|
40
|
+
__credentials : null,
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Headers to include for bearer (token) authentication.
|
|
44
|
+
* @return {Map} Map containing the authentication credentials
|
|
45
|
+
*/
|
|
46
|
+
getAuthHeaders: function() {
|
|
47
|
+
return [
|
|
48
|
+
{key: "Authorization", value: "Bearer " + this.__credentials}
|
|
49
|
+
];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* ************************************************************************
|
|
2
|
+
|
|
3
|
+
qooxdoo - the new era of web development
|
|
4
|
+
|
|
5
|
+
http://qooxdoo.org
|
|
6
|
+
|
|
7
|
+
Copyright:
|
|
8
|
+
2020 Christian Boulanger
|
|
9
|
+
|
|
10
|
+
License:
|
|
11
|
+
MIT: https://opensource.org/licenses/MIT
|
|
12
|
+
See the LICENSE file in the project's top-level directory for details.
|
|
13
|
+
|
|
14
|
+
Authors:
|
|
15
|
+
* Christian Boulanger (cboulanger)
|
|
16
|
+
|
|
17
|
+
************************************************************************ */
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* This class provides a the base class for all clients that use the
|
|
21
|
+
* transport implementations in this namespace. Since the static method
|
|
22
|
+
* `registerTransport` cannot be inherited by subclasses, they mus proxy it
|
|
23
|
+
* by adding `registerTransport : qx.io.transport.AbstractClient.registerTransport`
|
|
24
|
+
* to their `statics` section.
|
|
25
|
+
*
|
|
26
|
+
*/
|
|
27
|
+
qx.Class.define("qx.io.transport.AbstractClient", {
|
|
28
|
+
extend: qx.core.Object,
|
|
29
|
+
type: "abstract",
|
|
30
|
+
|
|
31
|
+
statics: {
|
|
32
|
+
/**
|
|
33
|
+
* Register a transport class for use with uris that match the given
|
|
34
|
+
* regular expression. The client will use the transport which first
|
|
35
|
+
* matches, starting with the last added transport
|
|
36
|
+
* @param {RegExp} uriRegExp
|
|
37
|
+
* A regular expression which the URI must match
|
|
38
|
+
* @param {qx.io.transport.ITransport} transportClass
|
|
39
|
+
* The qooxdoo class implementing the transport
|
|
40
|
+
*/
|
|
41
|
+
registerTransport(uriRegExp, transportClass) {
|
|
42
|
+
if (!this.constructor.__transports) {
|
|
43
|
+
this.constructor.__transports = [];
|
|
44
|
+
}
|
|
45
|
+
if (!qx.lang.Type.isRegExp(uriRegExp)) {
|
|
46
|
+
throw new Error("First argument must be a regular expression!");
|
|
47
|
+
}
|
|
48
|
+
if (!qx.Interface.classImplements(transportClass, qx.io.transport.ITransport)) {
|
|
49
|
+
throw new Error("Transport class must implement qx.io.transport.ITransport");
|
|
50
|
+
}
|
|
51
|
+
this.constructor.__transports.push({ uriRegExp, transport: transportClass});
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
properties: {
|
|
57
|
+
/**
|
|
58
|
+
* The transport object
|
|
59
|
+
*/
|
|
60
|
+
transport: {
|
|
61
|
+
check : "qx.io.transport.ITransport"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
members: {
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Given a transport object implementing {@link qx.io.transport.ITransport}
|
|
69
|
+
* select that transport; if a string URI is passed, select one that has
|
|
70
|
+
* been registered for that class of URIs.
|
|
71
|
+
* @param {qx.io.transport.ITransport|String} transportOrUri
|
|
72
|
+
* @throws qx.io.exception.Transport
|
|
73
|
+
*/
|
|
74
|
+
selectTransport(transportOrUri) {
|
|
75
|
+
let transport;
|
|
76
|
+
let uri;
|
|
77
|
+
if (qx.lang.Type.isString(transportOrUri)) {
|
|
78
|
+
if (!this.constructor.__transports) {
|
|
79
|
+
throw new Error("No transport has been registered. Put @use(qx.io.transport.X) in the doc block of your class, X being the transport class of your choice (such as qx.io.transport.Xhr for http transport).");
|
|
80
|
+
}
|
|
81
|
+
uri = transportOrUri;
|
|
82
|
+
for (let registeredTransport of this.constructor.__transports.reverse()) {
|
|
83
|
+
if (uri.match(registeredTransport.uriRegExp)) {
|
|
84
|
+
// eslint-disable-next-line new-cap
|
|
85
|
+
transport = new registeredTransport.transport(uri);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (!transport) {
|
|
89
|
+
throw new qx.io.exception.Transport(`No matching transport for URI '${transportOrUri}'`, qx.io.exception.Transport.INVALID_URI);
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
if (!(transportOrUri instanceof qx.core.Object) || !qx.Interface.classImplements(transportOrUri.constructor, qx.io.transport.ITransport)) {
|
|
93
|
+
throw new Error("Argument must be an qooxdoo object implementing qx.io.transport.ITransport");
|
|
94
|
+
}
|
|
95
|
+
transport = transportOrUri;
|
|
96
|
+
}
|
|
97
|
+
this.setTransport(transport);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract class for JSON-RPC transports
|
|
3
|
+
*
|
|
4
|
+
* For the moment, any special configuration of the transport, such as
|
|
5
|
+
* authentication, must be done on the level of the underlying implementation,
|
|
6
|
+
* an abstract API will be added later.
|
|
7
|
+
*/
|
|
8
|
+
qx.Class.define("qx.io.transport.AbstractTransport", {
|
|
9
|
+
|
|
10
|
+
extend: qx.core.Object,
|
|
11
|
+
type: "abstract",
|
|
12
|
+
|
|
13
|
+
properties : {
|
|
14
|
+
/**
|
|
15
|
+
* A representation of the the endpoint, which is either a uri (a String)
|
|
16
|
+
* or an object (such as in the case of the PostMessage transport)
|
|
17
|
+
*/
|
|
18
|
+
endpoint : {
|
|
19
|
+
check : v => typeof v == "string" || typeof v == "object",
|
|
20
|
+
nullable: true,
|
|
21
|
+
event : "changeEndpoint"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
events : {
|
|
26
|
+
/**
|
|
27
|
+
* Event fired when a message is received from the endpoint. Event data
|
|
28
|
+
* is an UTF-8 encoded string
|
|
29
|
+
*/
|
|
30
|
+
"message" : "qx.event.type.Data"
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Constructor
|
|
35
|
+
* @param {String|Object} endpoint
|
|
36
|
+
*/
|
|
37
|
+
construct(endpoint) {
|
|
38
|
+
this.base(arguments);
|
|
39
|
+
this.setEndpoint(endpoint);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The implementation of a HTTP Transport using the Fetch API,
|
|
3
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
|
|
4
|
+
*/
|
|
5
|
+
qx.Class.define("qx.io.transport.Fetch", {
|
|
6
|
+
extend: qx.io.transport.AbstractTransport,
|
|
7
|
+
implement: [qx.io.transport.ITransport],
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Constructor.
|
|
11
|
+
*
|
|
12
|
+
* @param {String} url The URL of the http endpoint
|
|
13
|
+
*/
|
|
14
|
+
construct(url) {
|
|
15
|
+
this.base(arguments, url);
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
members: {
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @type {Object}
|
|
22
|
+
*/
|
|
23
|
+
__tranportImpl: null,
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Returns the object which implements the transport on the
|
|
27
|
+
* underlying level, so that transport-specific configuration
|
|
28
|
+
* can be done on it. In the case of the Fetch API, the
|
|
29
|
+
* "implementation" is a configuration object which will be
|
|
30
|
+
* passed to the `fetch` method as second parameter.
|
|
31
|
+
*
|
|
32
|
+
* @return {Object}
|
|
33
|
+
*/
|
|
34
|
+
getTransportImpl() {
|
|
35
|
+
if (!this.__tranportImpl) {
|
|
36
|
+
this.__tranportImpl = this._createTransportImpl();
|
|
37
|
+
}
|
|
38
|
+
return this.__tranportImpl;
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Transport the given message to the endpoint
|
|
43
|
+
*
|
|
44
|
+
* @param {String} message
|
|
45
|
+
*
|
|
46
|
+
* @return {qx.Promise} Promise that resolves (with no data)
|
|
47
|
+
* when the message has been successfully sent out, and rejects
|
|
48
|
+
* when there is an error or a cancellation up to that point.
|
|
49
|
+
* @ignore(fetch)
|
|
50
|
+
*/
|
|
51
|
+
async send(message) {
|
|
52
|
+
qx.core.Assert.assertString(message);
|
|
53
|
+
let init = this.getTransportImpl();
|
|
54
|
+
init.body = message;
|
|
55
|
+
let response;
|
|
56
|
+
try {
|
|
57
|
+
response = await fetch(this.getEndpoint(), init);
|
|
58
|
+
} catch (e) {
|
|
59
|
+
throw new qx.io.exception.Transport(e.message, e.code);
|
|
60
|
+
}
|
|
61
|
+
if (!response.ok) {
|
|
62
|
+
switch (response.status) {
|
|
63
|
+
case 400:
|
|
64
|
+
// "400 Bad Request" is a really a protocol error (syntax error)
|
|
65
|
+
break;
|
|
66
|
+
default:
|
|
67
|
+
throw new qx.io.exception.Transport(response.statusText, response.status);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
let responseData = await response.text();
|
|
71
|
+
// notify listeners
|
|
72
|
+
this.fireDataEvent("message", responseData);
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Factory method to create a request object. In this implementation,
|
|
77
|
+
* it returns an object that will be used as the `init` parameter of the
|
|
78
|
+
* fetch method.
|
|
79
|
+
* @return {Object}
|
|
80
|
+
*/
|
|
81
|
+
_createTransportImpl() {
|
|
82
|
+
let init = {};
|
|
83
|
+
init.headers = {
|
|
84
|
+
'Content-Type': 'application/json',
|
|
85
|
+
'Accept': 'application/json',
|
|
86
|
+
};
|
|
87
|
+
init.method = "POST";
|
|
88
|
+
return init;
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
defer() {
|
|
93
|
+
qx.io.graphql.Client.registerTransport(/^http/, qx.io.transport.Fetch);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The interface for all transports located in this namespace
|
|
3
|
+
*/
|
|
4
|
+
qx.Interface.define("qx.io.transport.ITransport", {
|
|
5
|
+
properties: {
|
|
6
|
+
/**
|
|
7
|
+
* The URI of the endpoint
|
|
8
|
+
* @var {String}
|
|
9
|
+
*/
|
|
10
|
+
endpoint: {
|
|
11
|
+
event: "changeEndpoint"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
events: {
|
|
15
|
+
/**
|
|
16
|
+
* Event fired when a message is received from the endpoint. Event data
|
|
17
|
+
* is an UTF-8 encoded string
|
|
18
|
+
*/
|
|
19
|
+
"message": "qx.event.type.Data"
|
|
20
|
+
},
|
|
21
|
+
members : {
|
|
22
|
+
/**
|
|
23
|
+
* Transport the given message to the endpoint
|
|
24
|
+
*
|
|
25
|
+
* @param {String} message
|
|
26
|
+
* @return {qx.Promise} Promise that resolves (with no data)
|
|
27
|
+
* when the message has been successfully sent out, and rejects
|
|
28
|
+
* when there is an error or a cancellation up to that point.
|
|
29
|
+
*/
|
|
30
|
+
async send(message) {},
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Returns the object which implements the transport on the underlying
|
|
34
|
+
* level, so that transport-specific configuration can be done on it.
|
|
35
|
+
* The object might be a new one for each request.
|
|
36
|
+
* @return {Object}
|
|
37
|
+
*/
|
|
38
|
+
getTransportImpl() {}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An implementation of a PostMessage transport
|
|
3
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
|
|
4
|
+
* The transport is special isasmuch it is not used with an URI, but with the
|
|
5
|
+
* target Window or Worker object with acts as the endpoint of the message.
|
|
6
|
+
*/
|
|
7
|
+
qx.Class.define("qx.io.transport.PostMessage", {
|
|
8
|
+
extend: qx.io.transport.AbstractTransport,
|
|
9
|
+
implement: [qx.io.transport.ITransport],
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Constructor.
|
|
13
|
+
*
|
|
14
|
+
* @param {Window|Worker} windowOrWorker The target Window or Worker instance
|
|
15
|
+
* which is the endpoint for the request
|
|
16
|
+
*/
|
|
17
|
+
construct(windowOrWorker) {
|
|
18
|
+
windowOrWorker.addEventListener("message", evt => {
|
|
19
|
+
this.fireDataEvent("message", evt.data);
|
|
20
|
+
});
|
|
21
|
+
this.base(arguments, windowOrWorker);
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
members: {
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* PostMessage is a very simple protocol without configuration options.
|
|
28
|
+
* No transport implementation is needed.
|
|
29
|
+
* @return {null}
|
|
30
|
+
*/
|
|
31
|
+
getTransportImpl() {
|
|
32
|
+
return null;
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Transport the given message to the endpoint
|
|
37
|
+
*
|
|
38
|
+
* @param {String} message
|
|
39
|
+
*
|
|
40
|
+
* @return {qx.Promise} Promise that resolves (with no data)
|
|
41
|
+
* when the message has been successfully sent out, and rejects
|
|
42
|
+
* when there is an error or a cancellation up to that point.
|
|
43
|
+
* @ignore(fetch)
|
|
44
|
+
*/
|
|
45
|
+
async send(message) {
|
|
46
|
+
qx.core.Assert.assertString(message);
|
|
47
|
+
this.getEndpoint().postMessage(message);
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Empty stub since no transport implementation is needed.
|
|
52
|
+
*/
|
|
53
|
+
_createTransportImpl() {}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An implementation of a WebSocket transport
|
|
3
|
+
* @see https://developer.mozilla.org/de/docs/Web/API/WebSocket
|
|
4
|
+
* @ignore(WebSocket)
|
|
5
|
+
*/
|
|
6
|
+
qx.Class.define("qx.io.transport.Websocket", {
|
|
7
|
+
extend: qx.io.transport.AbstractTransport,
|
|
8
|
+
implement: [qx.io.transport.ITransport],
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Constructor.
|
|
12
|
+
*
|
|
13
|
+
* @param {String} url The URL of the http endpoint
|
|
14
|
+
*/
|
|
15
|
+
construct(url) {
|
|
16
|
+
this.base(arguments, url);
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
members: {
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @type {WebSocket}
|
|
23
|
+
*/
|
|
24
|
+
__tranportImpl: null,
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Returns the object which implements the transport on the
|
|
28
|
+
* underlying level, so that transport-specific configuration
|
|
29
|
+
* can be done on it.
|
|
30
|
+
*
|
|
31
|
+
* @return {WebSocket}
|
|
32
|
+
*/
|
|
33
|
+
getTransportImpl() {
|
|
34
|
+
if (!this.__tranportImpl) {
|
|
35
|
+
this.__tranportImpl = this._createTransportImpl();
|
|
36
|
+
}
|
|
37
|
+
return this.__tranportImpl;
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Transport the given message to the endpoint
|
|
42
|
+
*
|
|
43
|
+
* @param {String} message
|
|
44
|
+
*
|
|
45
|
+
* @return {qx.Promise} Promise that resolves (with no data)
|
|
46
|
+
* when the message has been successfully sent out, and rejects
|
|
47
|
+
* when there is an error or a cancellation up to that point.
|
|
48
|
+
* @ignore(fetch)
|
|
49
|
+
*/
|
|
50
|
+
async send(message) {
|
|
51
|
+
qx.core.Assert.assertString(message);
|
|
52
|
+
let ws = this.getTransportImpl();
|
|
53
|
+
if (!ws.readyState !== WebSocket.OPEN) {
|
|
54
|
+
await new Promise(resolve => ws.addEventListener("open", resolve));
|
|
55
|
+
}
|
|
56
|
+
ws.send(message);
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Factory method to create a websocket object.
|
|
61
|
+
* @return {WebSocket}
|
|
62
|
+
*/
|
|
63
|
+
_createTransportImpl() {
|
|
64
|
+
let ws = new WebSocket(this.getEndpoint());
|
|
65
|
+
ws.addEventListener("message", msgevt => {
|
|
66
|
+
this.fireDataEvent("message", msgevt.data)
|
|
67
|
+
});
|
|
68
|
+
ws.addEventListener("close", event => {
|
|
69
|
+
let error_message;
|
|
70
|
+
let error_code;
|
|
71
|
+
switch(event.code) {
|
|
72
|
+
case 1000:
|
|
73
|
+
// everything ok
|
|
74
|
+
break;
|
|
75
|
+
default:
|
|
76
|
+
// todo translate websocket error codes into qx.io.exception.Transport error codes
|
|
77
|
+
// see https://github.com/Luka967/websocket-close-codes
|
|
78
|
+
error_message = "Error " + event.code;
|
|
79
|
+
error_code = qx.io.exception.Transport.FAILED;
|
|
80
|
+
}
|
|
81
|
+
if (error_message) {
|
|
82
|
+
throw new qx.io.exception.Transport(error_message, error_code, event);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
return ws;
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
destruct() {
|
|
90
|
+
this.__tranportImpl.close();
|
|
91
|
+
this.__tranportImpl = null;
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
defer() {
|
|
95
|
+
qx.io.graphql.Client.registerTransport(/^ws/, qx.io.transport.Websocket);
|
|
96
|
+
}
|
|
97
|
+
});
|