jsf.js_next_gen 4.0.0-RC.35 → 4.0.0-RC.37
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/.nyc_output/09ca9ebc-2305-4357-8db9-48ddfc7dfde2.json +1 -0
- package/.nyc_output/7c496a14-166e-4aa5-85b9-47b22b055ad8.json +1 -0
- package/.nyc_output/processinfo/09ca9ebc-2305-4357-8db9-48ddfc7dfde2.json +1 -0
- package/.nyc_output/processinfo/7c496a14-166e-4aa5-85b9-47b22b055ad8.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -1
- package/dist/docs/assets/search.js +1 -1
- package/dist/docs/functions/faces.ajax.addOnError.html +6 -4
- package/dist/docs/functions/faces.ajax.addOnEvent.html +2 -0
- package/dist/docs/functions/faces.ajax.request.html +7 -7
- package/dist/docs/functions/faces.ajax.response.html +0 -1
- package/dist/docs/functions/faces.push.close.html +3 -1
- package/dist/docs/functions/faces.push.open.html +3 -1
- package/dist/docs/functions/faces.util.chain.html +3 -3
- package/dist/docs/functions/myfaces.ab.html +8 -3
- package/dist/docs/functions/myfaces.onOnDomReady.html +72 -0
- package/dist/docs/modules/myfaces.html +3 -1
- package/dist/docs/variables/myfaces.oam.html +2 -1
- package/dist/window/faces-development.js +303 -728
- package/dist/window/faces-development.js.br +0 -0
- package/dist/window/faces-development.js.gz +0 -0
- package/dist/window/faces-development.js.map +1 -1
- package/dist/window/faces.js +1 -1
- package/dist/window/faces.js.br +0 -0
- package/dist/window/faces.js.gz +0 -0
- package/dist/window/faces.js.map +1 -1
- package/dist/window/jsf-development.js +303 -728
- package/dist/window/jsf-development.js.br +0 -0
- package/dist/window/jsf-development.js.gz +0 -0
- package/dist/window/jsf-development.js.map +1 -1
- package/dist/window/jsf.js +1 -1
- package/dist/window/jsf.js.br +0 -0
- package/dist/window/jsf.js.gz +0 -0
- package/dist/window/jsf.js.map +1 -1
- package/package.json +7 -6
- package/src/main/typescript/@types/definitions/index.d.ts +5 -5
- package/src/main/typescript/api/_api.ts +55 -20
- package/src/main/typescript/impl/AjaxImpl.ts +10 -7
- package/src/main/typescript/test/frameworkBase/_ext/monadish/DomQueryTest.spec.ts +3 -3
- package/src/main/typescript/test/frameworkBase/_ext/shared/StandardInits.ts +35 -0
- package/src/main/typescript/test/xhrCore/TobagoFileUploadTest.spec.ts +109 -0
- package/target/api/_api.js +53 -18
- package/target/api/_api.js.map +1 -1
- package/target/impl/AjaxImpl.js +8 -4
- package/target/impl/AjaxImpl.js.map +1 -1
- package/target/impl/util/XhrQueueController.js +82 -0
- package/target/impl/util/XhrQueueController.js.map +1 -0
- package/target/impl/xhrCore/XhrQueHandler.js +11 -0
- package/target/impl/xhrCore/XhrQueHandler.js.map +1 -0
- package/target/impl/xhrCore/XhrQueueController.js +62 -0
- package/target/impl/xhrCore/XhrQueueController.js.map +1 -0
- package/target/test/frameworkBase/_ext/monadish/DomQueryTest.spec.js.map +1 -1
- package/target/test/frameworkBase/_ext/shared/StandardInits.js +36 -0
- package/target/test/frameworkBase/_ext/shared/StandardInits.js.map +1 -1
- package/target/test/xhrCore/TobagoFileUploadTest.spec.js +128 -0
- package/target/test/xhrCore/TobagoFileUploadTest.spec.js.map +1 -0
- package/.nyc_output/2303b649-59d9-485c-9228-73b0ec8787a7.json +0 -1
- package/.nyc_output/756f2f03-c85b-4cdb-9b92-5799eb45ef1e.json +0 -1
- package/.nyc_output/processinfo/2303b649-59d9-485c-9228-73b0ec8787a7.json +0 -1
- package/.nyc_output/processinfo/756f2f03-c85b-4cdb-9b92-5799eb45ef1e.json +0 -1
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jsf.js_next_gen",
|
|
3
|
-
"version": "4.0.0-RC.
|
|
3
|
+
"version": "4.0.0-RC.37",
|
|
4
4
|
"description": "A next generation typescript reimplementation of jsf.js",
|
|
5
5
|
"main": "dist/window/faces.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"doc": "npx typedoc --tsconfig src/main/typescript/tsconfig-typedoc.json",
|
|
8
|
-
"test": "env TS_NODE_PROJECT=./src/main/typescript/tsconfig.json mocha",
|
|
9
|
-
"coverage": "env TS_NODE_PROJECT=./src/
|
|
8
|
+
"test": "cross-env TS_NODE_PROJECT=./src/main/typescript/tsconfig.json mocha",
|
|
9
|
+
"coverage": "cross-env TS_NODE_PROJECT=./src/main/typescript/tsconfig.json nyc --reporter=html --reporter=text mocha",
|
|
10
10
|
"build-production": "webpack --mode production --env FILE_NAME=jsf && ts-node ./remap.ts --production",
|
|
11
11
|
"build-development": "webpack --mode development --env FILE_NAME=jsf-development && ts-node ./remap.ts --development",
|
|
12
12
|
"build": "npm run doc && npm run build-development && npm run build-production",
|
|
@@ -23,17 +23,18 @@
|
|
|
23
23
|
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
|
24
24
|
"@types/chai": "^4.3.4",
|
|
25
25
|
"@types/mocha": "^10.0.1",
|
|
26
|
-
"@types/node": "^18.
|
|
26
|
+
"@types/node": "^18.14.2",
|
|
27
27
|
"@types/sinon": "^10.0.13",
|
|
28
28
|
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
|
29
29
|
"chai": "^4.3.7",
|
|
30
30
|
"compression-webpack-plugin": "^10.0.0",
|
|
31
|
+
"cross-env": "^7.0.3",
|
|
31
32
|
"html-webpack-plugin": "^5.5.0",
|
|
32
33
|
"http-server": "^14.1.1",
|
|
33
34
|
"jsdom": "^21.1.0",
|
|
34
35
|
"jsdom-global": "^3.0.2",
|
|
35
36
|
"mocha": "^10.2.0",
|
|
36
|
-
"npm-check-updates": "^16.
|
|
37
|
+
"npm-check-updates": "^16.7.10",
|
|
37
38
|
"nyc": "^15.1.0",
|
|
38
39
|
"replace-in-file": "^6.3.5",
|
|
39
40
|
"rxjs": "^7.8.0",
|
|
@@ -41,7 +42,7 @@
|
|
|
41
42
|
"terser-webpack-plugin": "^5.3.6",
|
|
42
43
|
"ts-loader": "^9.4.2",
|
|
43
44
|
"ts-node": "^10.9.1",
|
|
44
|
-
"typedoc": "^0.23.
|
|
45
|
+
"typedoc": "^0.23.26",
|
|
45
46
|
"typescript": "^4.9.5",
|
|
46
47
|
"webpack": "^5.75.0",
|
|
47
48
|
"webpack-cli": "^5.0.1",
|
|
@@ -50,10 +50,10 @@ declare global {
|
|
|
50
50
|
* <li> errorData.status : the error status message</li>
|
|
51
51
|
* <li> errorData.serverErrorName : the server error name in case of a server error</li>
|
|
52
52
|
* <li> errorData.serverErrorMessage : the server error message in case of a server error</li>
|
|
53
|
-
* <li> errorData.source : the issuing source element which triggered the
|
|
54
|
-
* <li> eventData.responseCode: the response code (aka http
|
|
55
|
-
* <li> eventData.responseText: the
|
|
56
|
-
* <li> eventData.responseXML: the
|
|
53
|
+
* <li> errorData.source : the issuing source element which triggered the request </li>
|
|
54
|
+
* <li> eventData.responseCode: the response code (aka http request response code, 401 etc...) </li>
|
|
55
|
+
* <li> eventData.responseText: the response text </li>
|
|
56
|
+
* <li> eventData.responseXML: the response xml </li>
|
|
57
57
|
* </ul>
|
|
58
58
|
*/
|
|
59
59
|
interface IErrorData {
|
|
@@ -78,7 +78,7 @@ declare global {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
interface Ajax {
|
|
81
|
-
request(element: Element, event?: Event, options?:
|
|
81
|
+
request(element: Element, event?: Event, options?: Options): void;
|
|
82
82
|
response(request: XMLHttpRequest, context?: Context): void;
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -99,7 +99,7 @@ export module faces {
|
|
|
99
99
|
return Implementation.getClientWindow(rootNode);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
//private helper functions
|
|
102
|
+
// private helper functions
|
|
103
103
|
function getSeparatorChar(): string {
|
|
104
104
|
const sep = '#{facesContext.namingContainerSeparatorChar}';
|
|
105
105
|
//We now enable standalone mode, the separator char was not mapped we make a fallback to 2.3 behavior
|
|
@@ -117,19 +117,19 @@ export module faces {
|
|
|
117
117
|
/**
|
|
118
118
|
* this function has to send the ajax requests
|
|
119
119
|
*
|
|
120
|
-
* following
|
|
120
|
+
* following request conditions must be met:
|
|
121
121
|
* <ul>
|
|
122
|
-
* <li> the
|
|
123
|
-
* <li> the
|
|
124
|
-
* <li> the
|
|
125
|
-
* <li> all requests must be queued with a client side
|
|
122
|
+
* <li> the request must be sent asynchronously! </li>
|
|
123
|
+
* <li> the request must be a POST!!! request </li>
|
|
124
|
+
* <li> the request url must be the form action attribute </li>
|
|
125
|
+
* <li> all requests must be queued with a client side request queue to ensure the request ordering!</li>
|
|
126
126
|
* </ul>
|
|
127
127
|
*
|
|
128
128
|
* @param {String|Node} element: any dom element no matter being it html or jsf, from which the event is emitted
|
|
129
129
|
* @param {EVENT} event: any javascript event supported by that object
|
|
130
130
|
* @param {Map} options : map of options being pushed into the ajax cycle
|
|
131
131
|
*/
|
|
132
|
-
export function request(element: Element, event?: Event, options?:
|
|
132
|
+
export function request(element: Element, event?: Event, options?: Options): void {
|
|
133
133
|
Implementation.request(element, event, options)
|
|
134
134
|
}
|
|
135
135
|
|
|
@@ -138,7 +138,6 @@ export module faces {
|
|
|
138
138
|
* @param request the request object having triggered this response
|
|
139
139
|
* @param context the request context
|
|
140
140
|
*
|
|
141
|
-
* TODO add info on what can be in the context
|
|
142
141
|
*/
|
|
143
142
|
export function response(request: XMLHttpRequest, context?: Context): void {
|
|
144
143
|
Implementation.response(request, context);
|
|
@@ -153,13 +152,13 @@ export module faces {
|
|
|
153
152
|
* <li> errorData.status : the error status message</li>
|
|
154
153
|
* <li> errorData.serverErrorName : the server error name in case of a server error</li>
|
|
155
154
|
* <li> errorData.serverErrorMessage : the server error message in case of a server error</li>
|
|
156
|
-
* <li> errorData.source : the issuing source element which triggered the
|
|
157
|
-
* <li> eventData.responseCode: the response code (aka http
|
|
158
|
-
* <li> eventData.responseText: the
|
|
159
|
-
* <li> eventData.responseXML: the
|
|
155
|
+
* <li> errorData.source : the issuing source element which triggered the request </li>
|
|
156
|
+
* <li> eventData.responseCode: the response code (aka http request response code, 401 etc...) </li>
|
|
157
|
+
* <li> eventData.responseText: the request response text </li>
|
|
158
|
+
* <li> eventData.responseXML: the request response xml </li>
|
|
160
159
|
* </ul>
|
|
161
160
|
*
|
|
162
|
-
* @param
|
|
161
|
+
* @param errorFunc error handler must be of the format <i>function errorListener(<errorData>)</i>
|
|
163
162
|
*/
|
|
164
163
|
export function addOnError(errorFunc: (data: ErrorData) => void): void {
|
|
165
164
|
Implementation.addOnError(<any>errorFunc);
|
|
@@ -169,7 +168,7 @@ export module faces {
|
|
|
169
168
|
* Adds a global event listener to the ajax event queue. The event listener must be a function
|
|
170
169
|
* of following format: <i>function eventListener(<eventData>)</i>
|
|
171
170
|
*
|
|
172
|
-
* @param
|
|
171
|
+
* @param eventFunc event must be of the format <i>function eventListener(<eventData>)</i>
|
|
173
172
|
*/
|
|
174
173
|
export function addOnEvent(eventFunc: (data: EventData) => void): void {
|
|
175
174
|
Implementation.addOnEvent(<any>eventFunc);
|
|
@@ -184,12 +183,12 @@ export module faces {
|
|
|
184
183
|
* if any of the code returns false, the execution
|
|
185
184
|
* is terminated prematurely skipping the rest of the code!
|
|
186
185
|
*
|
|
187
|
-
* @param {
|
|
186
|
+
* @param {HTMLElement | String} source, the callee object
|
|
188
187
|
* @param {Event} event, the event object of the callee event triggering this function
|
|
189
188
|
* @param funcs ... arbitrary array of functions or strings
|
|
190
189
|
* @returns true if the chain has succeeded false otherwise
|
|
191
190
|
*/
|
|
192
|
-
export function chain(source, event, ...funcs: Array<Function | string>): boolean {
|
|
191
|
+
export function chain(source: HTMLElement | string, event: Event | null, ...funcs: Array<Function | string>): boolean {
|
|
193
192
|
return Implementation.chain(source, event, ...(funcs as EvalFuncs));
|
|
194
193
|
}
|
|
195
194
|
}
|
|
@@ -220,7 +219,7 @@ export module faces {
|
|
|
220
219
|
|
|
221
220
|
/**
|
|
222
221
|
* Open the web socket on the given channel.
|
|
223
|
-
* @param
|
|
222
|
+
* @param socketClientId The name of the web socket channel.
|
|
224
223
|
* @throws Error is thrown, if the channel is unknown.
|
|
225
224
|
*/
|
|
226
225
|
export function open(socketClientId: string): void {
|
|
@@ -229,7 +228,7 @@ export module faces {
|
|
|
229
228
|
|
|
230
229
|
/**
|
|
231
230
|
* Close the web socket on the given channel.
|
|
232
|
-
* @param
|
|
231
|
+
* @param socketClientId The id of the web socket client.
|
|
233
232
|
* @throws Error is thrown, if the channel is unknown.
|
|
234
233
|
*/
|
|
235
234
|
export function close(socketClientId: string): void {
|
|
@@ -249,8 +248,8 @@ export module myfaces {
|
|
|
249
248
|
* @param event the event
|
|
250
249
|
* @param eventName event name for java.jakarta.faces.behavior.evemnt
|
|
251
250
|
* @param execute execute list as passed down in faces.ajax.request
|
|
252
|
-
* @param render
|
|
253
|
-
* @param options
|
|
251
|
+
* @param render the render list as string
|
|
252
|
+
* @param options the options which need to be mered in
|
|
254
253
|
*/
|
|
255
254
|
export function ab(source: Element, event: Event, eventName: string, execute: string, render: string, options: Options = {}): void {
|
|
256
255
|
if (eventName) {
|
|
@@ -267,6 +266,42 @@ export module myfaces {
|
|
|
267
266
|
(window?.faces ?? window.jsf).ajax.request(source, event, options);
|
|
268
267
|
}
|
|
269
268
|
|
|
269
|
+
|
|
270
|
+
const onReadyChain: Array<() => void> = [];
|
|
271
|
+
let readyStateListener = null;
|
|
272
|
+
// noinspection JSUnusedGlobalSymbols
|
|
273
|
+
/**
|
|
274
|
+
* Helper function in the myfaces namespace to handle document ready properly for the load case
|
|
275
|
+
* the ajax case, does not need proper treatment, since it is deferred anyway.
|
|
276
|
+
* Used by command script as helper function!
|
|
277
|
+
*
|
|
278
|
+
* @param executionFunc the function to be executed upon ready
|
|
279
|
+
*/
|
|
280
|
+
export function onOnDomReady(executionFunc: () => void) {
|
|
281
|
+
if(document.readyState !== "complete") {
|
|
282
|
+
onReadyChain.push(executionFunc);
|
|
283
|
+
if(!readyStateListener) {
|
|
284
|
+
readyStateListener = () => {
|
|
285
|
+
window.removeEventListener("DOMContentLoaded", readyStateListener);
|
|
286
|
+
readyStateListener = null;
|
|
287
|
+
try {
|
|
288
|
+
onReadyChain.forEach(func => func());
|
|
289
|
+
} finally {
|
|
290
|
+
//done we clear now the ready chain
|
|
291
|
+
onReadyChain.length = 0;
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
window.addEventListener("DOMContentLoaded", readyStateListener);
|
|
295
|
+
}
|
|
296
|
+
} else {
|
|
297
|
+
if(readyStateListener) {
|
|
298
|
+
readyStateListener();
|
|
299
|
+
}
|
|
300
|
+
executionFunc();
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
}
|
|
304
|
+
|
|
270
305
|
/**
|
|
271
306
|
* legacy oam functions
|
|
272
307
|
*/
|
|
@@ -20,7 +20,6 @@ import {XhrRequest} from "./xhrCore/XhrRequest";
|
|
|
20
20
|
import {AsynchronousQueue} from "./util/AsyncQueue";
|
|
21
21
|
import {AssocArrayCollector, Config, DQ, Lang, LazyStream, Optional, Stream} from "mona-dish";
|
|
22
22
|
import {Assertions} from "./util/Assertions";
|
|
23
|
-
import {XhrFormData} from "./xhrCore/XhrFormData";
|
|
24
23
|
import {ExtConfig, ExtDomQuery} from "./util/ExtDomQuery";
|
|
25
24
|
import {ErrorData} from "./xhrCore/ErrorData";
|
|
26
25
|
import {EventData} from "./xhrCore/EventData";
|
|
@@ -113,11 +112,15 @@ export module Implementation {
|
|
|
113
112
|
a) Monad like structures for querying because this keeps the code denser and adds abstractions
|
|
114
113
|
that always was the strong point of jquery and it still is better in this regard than what ecmascript provides
|
|
115
114
|
|
|
116
|
-
b) Streams and
|
|
115
|
+
b) Streams and lazy streams like java has, a pull stream construct, ecmascript does not have anything like it.
|
|
116
|
+
(it has array filters and maps, but ES2015 does not support flatMap)
|
|
117
117
|
Another option would have been rxjs but that would have introduced a code dependency and probably more code. We might
|
|
118
|
-
move to RXJS if the need arises however. But for now I would rather stick with my small self grown library which works
|
|
118
|
+
move to RXJS if the need arises, however. But for now I would rather stick with my small self grown library which works
|
|
119
119
|
quite well and where I can patch quickly (I have used it in several industrial projects, so it works well
|
|
120
120
|
and is heavily fortified by unit tests (140 testcases as time of writing this))
|
|
121
|
+
The long term plan is to eliminate the Stream usage as soon as we can move up to ES2019 (adding the missing
|
|
122
|
+
functions as shims, is a no go, because we are a library, and absolutey do not Shim anything which can leak
|
|
123
|
+
into the global namespace!)
|
|
121
124
|
|
|
122
125
|
c) A neutral json like configuration which allows assignments of arbitrary values with reduce code which then can be
|
|
123
126
|
transformed into different data representations
|
|
@@ -189,7 +192,7 @@ export module Implementation {
|
|
|
189
192
|
/**
|
|
190
193
|
* @return the project stage also emitted by the server:
|
|
191
194
|
* it cannot be cached and must be delivered over the server
|
|
192
|
-
* The value for it comes from the
|
|
195
|
+
* The value for it comes from the request parameter of the faces.js script called "stage".
|
|
193
196
|
*/
|
|
194
197
|
export function getProjectStage(): string | null {
|
|
195
198
|
return resolveGlobalConfig()?.projectStage ??
|
|
@@ -205,7 +208,7 @@ export module Implementation {
|
|
|
205
208
|
|
|
206
209
|
/* run through all script tags and try to find the one that includes faces.js */
|
|
207
210
|
const foundStage = ExtDomQuery.searchJsfJsFor(/stage=([^&;]*)/).value as string;
|
|
208
|
-
return (foundStage in ProjectStages) ? foundStage :
|
|
211
|
+
return (foundStage in ProjectStages) ? foundStage : ProjectStages.Production; // MYFACES-4572: default is production
|
|
209
212
|
}
|
|
210
213
|
|
|
211
214
|
/**
|
|
@@ -215,7 +218,7 @@ export module Implementation {
|
|
|
215
218
|
* @param event
|
|
216
219
|
* @param funcs
|
|
217
220
|
*/
|
|
218
|
-
export function chain(source:
|
|
221
|
+
export function chain(source: HTMLElement | string, event: Event | null, ...funcs: EvalFuncs): boolean {
|
|
219
222
|
// we can use our lazy stream each functionality to run our chain here..
|
|
220
223
|
// by passing a boolean as return value into the onElem call
|
|
221
224
|
// we can stop early at the first false, just like the spec requests
|
|
@@ -500,7 +503,7 @@ export module Implementation {
|
|
|
500
503
|
* or non-existent. If they exist all of them must be the same
|
|
501
504
|
*/
|
|
502
505
|
|
|
503
|
-
let formWindowId: Optional<string> = searchRoot.stream.map
|
|
506
|
+
let formWindowId: Optional<string> = searchRoot.stream.map(getValue).reduce(differenceCheck, INIT);
|
|
504
507
|
|
|
505
508
|
|
|
506
509
|
//if the resulting window id is set on altered then we have an unresolvable problem
|
|
@@ -376,7 +376,7 @@ describe('DOMQuery tests', function () {
|
|
|
376
376
|
expect(length2 == 8).to.be.true;
|
|
377
377
|
|
|
378
378
|
let count = DomQuery.byId("embed1").elements
|
|
379
|
-
.stream.map
|
|
379
|
+
.stream.map(item => item.disabled ? 1 : 0)
|
|
380
380
|
.reduce((val1, val2) => val1 + val2, 0);
|
|
381
381
|
expect(count.value).to.eq(1);
|
|
382
382
|
|
|
@@ -385,12 +385,12 @@ describe('DOMQuery tests', function () {
|
|
|
385
385
|
.each(item => item.disabled = false);
|
|
386
386
|
|
|
387
387
|
count = DomQuery.byId("embed1").elements
|
|
388
|
-
.stream.map
|
|
388
|
+
.stream.map(item => item.disabled ? 1 : 0)
|
|
389
389
|
.reduce((val1, val2) => val1 + val2, 0);
|
|
390
390
|
expect(count.value).to.eq(0);
|
|
391
391
|
|
|
392
392
|
count = DomQuery.byId("embed1").elements
|
|
393
|
-
.stream.map
|
|
393
|
+
.stream.map(item => item.attr("checked").isPresent() ? 1 : 0)
|
|
394
394
|
.reduce((val1, val2) => val1 + val2, 0);
|
|
395
395
|
expect(count.value).to.eq(1);
|
|
396
396
|
|
|
@@ -111,6 +111,38 @@ export module StandardInits {
|
|
|
111
111
|
</html>`;
|
|
112
112
|
|
|
113
113
|
|
|
114
|
+
/**
|
|
115
|
+
* a page based on Tobago for a file upload
|
|
116
|
+
*/
|
|
117
|
+
const HTML_TOBAGO_FILE_FORM = `<!DOCTYPE html>
|
|
118
|
+
<html lang='de'>
|
|
119
|
+
<head>
|
|
120
|
+
<meta charset='UTF-8'>
|
|
121
|
+
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
|
|
122
|
+
<title>Test</title>
|
|
123
|
+
</head>
|
|
124
|
+
<body>
|
|
125
|
+
<tobago-page locale='de' class='container-fluid' id='page' focus-on-error='true' wait-overlay-delay-full='1000' wait-overlay-delay-ajax='1000'>
|
|
126
|
+
<form action='/content/100-upload/File_Upload.xhtml' id='page::form' method='post' enctype='multipart/form-data' accept-charset='UTF-8' data-tobago-context-path=''>
|
|
127
|
+
<input type='hidden' name='javax.faces.source' id='javax.faces.source' disabled='disabled'>
|
|
128
|
+
<tobago-focus id='page::lastFocusId'>
|
|
129
|
+
<input type='hidden' name='page::lastFocusId' id='page::lastFocusId::field'>
|
|
130
|
+
</tobago-focus>
|
|
131
|
+
<input type='hidden' name='org.apache.myfaces.tobago.webapp.Secret' id='org.apache.myfaces.tobago.webapp.Secret' value='secretValue'>
|
|
132
|
+
<tobago-file id='page:fileAjax' class='tobago-auto-spacing'>
|
|
133
|
+
<div class='input-group'>
|
|
134
|
+
<input type='file' tabindex='-1' id='page:fileAjax::field' class='form-control' name='page:fileAjax'>
|
|
135
|
+
<tobago-behavior event='change' client-id='page:fileAjax' field-id='page:fileAjax::field' execute='page:fileAjax'></tobago-behavior>
|
|
136
|
+
<label class='input-group-text' for='page:fileAjax::field'><span><i class='bi-folder2-open'></i></span></label>
|
|
137
|
+
</div>
|
|
138
|
+
</tobago-file>
|
|
139
|
+
<div class='tobago-page-menuStore'>
|
|
140
|
+
</div>
|
|
141
|
+
<span id='page::jsf-state-container'><input type='hidden' name='javax.faces.ViewState' id='j_id__v_0:javax.faces.ViewState:1' value='viewStateValue' autocomplete='off'><input type='hidden' name='javax.faces.RenderKitId' value='tobago'><input type='hidden' id='j_id__v_0:javax.faces.ClientWindow:1' name='javax.faces.ClientWindow' value='clientWindowValue'></span>
|
|
142
|
+
</form>
|
|
143
|
+
</tobago-page>
|
|
144
|
+
</body>
|
|
145
|
+
</html>`;
|
|
114
146
|
|
|
115
147
|
/**
|
|
116
148
|
* a page simulating basically a simple faces form
|
|
@@ -350,6 +382,9 @@ export module StandardInits {
|
|
|
350
382
|
export function defaultFileForm(withJsf = true): Promise<() => void> {
|
|
351
383
|
return init(HTML_FILE_FORM_DEFAULT, withJsf);
|
|
352
384
|
}
|
|
385
|
+
export function tobagoFileForm(withJsf = true): Promise<() => void> {
|
|
386
|
+
return init(HTML_TOBAGO_FILE_FORM, withJsf);
|
|
387
|
+
}
|
|
353
388
|
export function defaultFileForm_23(withJsf = true): Promise<() => void> {
|
|
354
389
|
return init(HTML_FILE_FORM_DEFAULT.replace(/jakarta/gi, "javax"), withJsf, false);
|
|
355
390
|
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/*! Licensed to the Apache Software Foundation (ASF) under one or more
|
|
2
|
+
* contributor license agreements. See the NOTICE file distributed with
|
|
3
|
+
* this work for additional information regarding copyright ownership.
|
|
4
|
+
* The ASF licenses this file to you under the Apache License, Version 2.0
|
|
5
|
+
* (the "License"); you may not use this file except in compliance with
|
|
6
|
+
* the License. You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import {describe, it} from "mocha";
|
|
17
|
+
import * as sinon from "sinon";
|
|
18
|
+
import {expect} from "chai";
|
|
19
|
+
import {StandardInits} from "../frameworkBase/_ext/shared/StandardInits";
|
|
20
|
+
import {DomQuery} from "mona-dish";
|
|
21
|
+
import {Implementation} from "../../impl/AjaxImpl";
|
|
22
|
+
import defaultFileForm = StandardInits.tobagoFileForm;
|
|
23
|
+
|
|
24
|
+
declare var faces: any;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* specialized tests testing the xhr core behavior when it hits the xmlHttpRequest object
|
|
28
|
+
*/
|
|
29
|
+
describe('Tests on the xhr core when it starts to call the request', function () {
|
|
30
|
+
beforeEach(async function () {
|
|
31
|
+
|
|
32
|
+
let waitForResult = defaultFileForm();
|
|
33
|
+
return waitForResult.then((close) => {
|
|
34
|
+
|
|
35
|
+
this.xhr = sinon.useFakeXMLHttpRequest();
|
|
36
|
+
this.requests = [];
|
|
37
|
+
|
|
38
|
+
this.respond = (response: string): XMLHttpRequest => {
|
|
39
|
+
let xhrReq = this.requests.shift();
|
|
40
|
+
xhrReq.responsetype = "text/xml";
|
|
41
|
+
xhrReq.respond(200, {'Content-Type': 'text/xml'}, response);
|
|
42
|
+
return xhrReq;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
this.xhr.onCreate = (xhr) => {
|
|
46
|
+
this.requests.push(xhr);
|
|
47
|
+
};
|
|
48
|
+
(<any>global).XMLHttpRequest = this.xhr;
|
|
49
|
+
window.XMLHttpRequest = this.xhr;
|
|
50
|
+
|
|
51
|
+
this.closeIt = () => {
|
|
52
|
+
(<any>global).XMLHttpRequest = window.XMLHttpRequest = this.xhr.restore();
|
|
53
|
+
Implementation.reset();
|
|
54
|
+
close();
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
});
|
|
59
|
+
afterEach(function () {
|
|
60
|
+
this.closeIt();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('tobago file upload', function (done) {
|
|
64
|
+
let send = sinon.spy(XMLHttpRequest.prototype, "send");
|
|
65
|
+
|
|
66
|
+
const POST = "POST";
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
let fileUploadField = DomQuery.byId("page:fileAjax::field");
|
|
70
|
+
let actionElement = DomQuery.byId("page:fileAjax");
|
|
71
|
+
|
|
72
|
+
fileUploadField.addEventListener("change", (event: Event) => {
|
|
73
|
+
faces.ajax.request(
|
|
74
|
+
actionElement,
|
|
75
|
+
event,
|
|
76
|
+
{
|
|
77
|
+
"javax.faces.behavior.event": "change",
|
|
78
|
+
execute: 'page:fileAjax',
|
|
79
|
+
render: null
|
|
80
|
+
});
|
|
81
|
+
}).dispatchEvent(new Event("change"));
|
|
82
|
+
|
|
83
|
+
expect(this.requests.length).to.eq(1);
|
|
84
|
+
let request = this.requests[0];
|
|
85
|
+
expect(request.method).to.eq(POST);
|
|
86
|
+
expect(request.async).to.be.true;
|
|
87
|
+
expect(send.called).to.be.true;
|
|
88
|
+
expect(send.callCount).to.eq(1);
|
|
89
|
+
expect(request.requestBody instanceof FormData).to.be.true;
|
|
90
|
+
|
|
91
|
+
let formData: FormData = request.requestBody;
|
|
92
|
+
expect(formData.get("page::lastFocusId")).to.eq("");
|
|
93
|
+
expect(formData.get("org.apache.myfaces.tobago.webapp.Secret")).to.eq("secretValue");
|
|
94
|
+
expect(formData.get("javax.faces.ViewState")).to.eq("viewStateValue");
|
|
95
|
+
expect(formData.get("javax.faces.RenderKitId")).to.eq("tobago");
|
|
96
|
+
expect(formData.get("javax.faces.ClientWindow")).to.eq("clientWindowValue");
|
|
97
|
+
expect(formData.get("javax.faces.behavior.event")).to.eq("change");
|
|
98
|
+
expect(formData.get("jakarta.faces.partial.event")).to.eq("change");
|
|
99
|
+
expect(formData.get("jakarta.faces.source")).to.eq("page:fileAjax");
|
|
100
|
+
expect(formData.get("jakarta.faces.partial.ajax")).to.eq("true");
|
|
101
|
+
expect(formData.get("page::form")).to.eq("page::form");
|
|
102
|
+
expect(formData.get("jakarta.faces.partial.execute")).to.eq("page:fileAjax");
|
|
103
|
+
|
|
104
|
+
} finally {
|
|
105
|
+
send.restore();
|
|
106
|
+
}
|
|
107
|
+
done();
|
|
108
|
+
});
|
|
109
|
+
});
|
package/target/api/_api.js
CHANGED
|
@@ -95,7 +95,7 @@ var faces;
|
|
|
95
95
|
return AjaxImpl_1.Implementation.getClientWindow(rootNode);
|
|
96
96
|
}
|
|
97
97
|
faces.getClientWindow = getClientWindow;
|
|
98
|
-
//private helper functions
|
|
98
|
+
// private helper functions
|
|
99
99
|
function getSeparatorChar() {
|
|
100
100
|
const sep = '#{facesContext.namingContainerSeparatorChar}';
|
|
101
101
|
//We now enable standalone mode, the separator char was not mapped we make a fallback to 2.3 behavior
|
|
@@ -109,12 +109,12 @@ var faces;
|
|
|
109
109
|
/**
|
|
110
110
|
* this function has to send the ajax requests
|
|
111
111
|
*
|
|
112
|
-
* following
|
|
112
|
+
* following request conditions must be met:
|
|
113
113
|
* <ul>
|
|
114
|
-
* <li> the
|
|
115
|
-
* <li> the
|
|
116
|
-
* <li> the
|
|
117
|
-
* <li> all requests must be queued with a client side
|
|
114
|
+
* <li> the request must be sent asynchronously! </li>
|
|
115
|
+
* <li> the request must be a POST!!! request </li>
|
|
116
|
+
* <li> the request url must be the form action attribute </li>
|
|
117
|
+
* <li> all requests must be queued with a client side request queue to ensure the request ordering!</li>
|
|
118
118
|
* </ul>
|
|
119
119
|
*
|
|
120
120
|
* @param {String|Node} element: any dom element no matter being it html or jsf, from which the event is emitted
|
|
@@ -130,7 +130,6 @@ var faces;
|
|
|
130
130
|
* @param request the request object having triggered this response
|
|
131
131
|
* @param context the request context
|
|
132
132
|
*
|
|
133
|
-
* TODO add info on what can be in the context
|
|
134
133
|
*/
|
|
135
134
|
function response(request, context) {
|
|
136
135
|
AjaxImpl_1.Implementation.response(request, context);
|
|
@@ -145,13 +144,13 @@ var faces;
|
|
|
145
144
|
* <li> errorData.status : the error status message</li>
|
|
146
145
|
* <li> errorData.serverErrorName : the server error name in case of a server error</li>
|
|
147
146
|
* <li> errorData.serverErrorMessage : the server error message in case of a server error</li>
|
|
148
|
-
* <li> errorData.source : the issuing source element which triggered the
|
|
149
|
-
* <li> eventData.responseCode: the response code (aka http
|
|
150
|
-
* <li> eventData.responseText: the
|
|
151
|
-
* <li> eventData.responseXML: the
|
|
147
|
+
* <li> errorData.source : the issuing source element which triggered the request </li>
|
|
148
|
+
* <li> eventData.responseCode: the response code (aka http request response code, 401 etc...) </li>
|
|
149
|
+
* <li> eventData.responseText: the request response text </li>
|
|
150
|
+
* <li> eventData.responseXML: the request response xml </li>
|
|
152
151
|
* </ul>
|
|
153
152
|
*
|
|
154
|
-
* @param
|
|
153
|
+
* @param errorFunc error handler must be of the format <i>function errorListener(<errorData>)</i>
|
|
155
154
|
*/
|
|
156
155
|
function addOnError(errorFunc) {
|
|
157
156
|
AjaxImpl_1.Implementation.addOnError(errorFunc);
|
|
@@ -161,7 +160,7 @@ var faces;
|
|
|
161
160
|
* Adds a global event listener to the ajax event queue. The event listener must be a function
|
|
162
161
|
* of following format: <i>function eventListener(<eventData>)</i>
|
|
163
162
|
*
|
|
164
|
-
* @param
|
|
163
|
+
* @param eventFunc event must be of the format <i>function eventListener(<eventData>)</i>
|
|
165
164
|
*/
|
|
166
165
|
function addOnEvent(eventFunc) {
|
|
167
166
|
AjaxImpl_1.Implementation.addOnEvent(eventFunc);
|
|
@@ -176,7 +175,7 @@ var faces;
|
|
|
176
175
|
* if any of the code returns false, the execution
|
|
177
176
|
* is terminated prematurely skipping the rest of the code!
|
|
178
177
|
*
|
|
179
|
-
* @param {
|
|
178
|
+
* @param {HTMLElement | String} source, the callee object
|
|
180
179
|
* @param {Event} event, the event object of the callee event triggering this function
|
|
181
180
|
* @param funcs ... arbitrary array of functions or strings
|
|
182
181
|
* @returns true if the chain has succeeded false otherwise
|
|
@@ -205,7 +204,7 @@ var faces;
|
|
|
205
204
|
push.init = init;
|
|
206
205
|
/**
|
|
207
206
|
* Open the web socket on the given channel.
|
|
208
|
-
* @param
|
|
207
|
+
* @param socketClientId The name of the web socket channel.
|
|
209
208
|
* @throws Error is thrown, if the channel is unknown.
|
|
210
209
|
*/
|
|
211
210
|
function open(socketClientId) {
|
|
@@ -214,7 +213,7 @@ var faces;
|
|
|
214
213
|
push.open = open;
|
|
215
214
|
/**
|
|
216
215
|
* Close the web socket on the given channel.
|
|
217
|
-
* @param
|
|
216
|
+
* @param socketClientId The id of the web socket client.
|
|
218
217
|
* @throws Error is thrown, if the channel is unknown.
|
|
219
218
|
*/
|
|
220
219
|
function close(socketClientId) {
|
|
@@ -234,8 +233,8 @@ var myfaces;
|
|
|
234
233
|
* @param event the event
|
|
235
234
|
* @param eventName event name for java.jakarta.faces.behavior.evemnt
|
|
236
235
|
* @param execute execute list as passed down in faces.ajax.request
|
|
237
|
-
* @param render
|
|
238
|
-
* @param options
|
|
236
|
+
* @param render the render list as string
|
|
237
|
+
* @param options the options which need to be mered in
|
|
239
238
|
*/
|
|
240
239
|
function ab(source, event, eventName, execute, render, options = {}) {
|
|
241
240
|
var _a, _b;
|
|
@@ -252,6 +251,42 @@ var myfaces;
|
|
|
252
251
|
((_b = window === null || window === void 0 ? void 0 : window.faces) !== null && _b !== void 0 ? _b : window.jsf).ajax.request(source, event, options);
|
|
253
252
|
}
|
|
254
253
|
myfaces.ab = ab;
|
|
254
|
+
const onReadyChain = [];
|
|
255
|
+
let readyStateListener = null;
|
|
256
|
+
// noinspection JSUnusedGlobalSymbols
|
|
257
|
+
/**
|
|
258
|
+
* Helper function in the myfaces namespace to handle document ready properly for the load case
|
|
259
|
+
* the ajax case, does not need proper treatment, since it is deferred anyway.
|
|
260
|
+
* Used by command script as helper function!
|
|
261
|
+
*
|
|
262
|
+
* @param executionFunc the function to be executed upon ready
|
|
263
|
+
*/
|
|
264
|
+
function onOnDomReady(executionFunc) {
|
|
265
|
+
if (document.readyState !== "complete") {
|
|
266
|
+
onReadyChain.push(executionFunc);
|
|
267
|
+
if (!readyStateListener) {
|
|
268
|
+
readyStateListener = () => {
|
|
269
|
+
window.removeEventListener("DOMContentLoaded", readyStateListener);
|
|
270
|
+
readyStateListener = null;
|
|
271
|
+
try {
|
|
272
|
+
onReadyChain.forEach(func => func());
|
|
273
|
+
}
|
|
274
|
+
finally {
|
|
275
|
+
//done we clear now the ready chain
|
|
276
|
+
onReadyChain.length = 0;
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
window.addEventListener("DOMContentLoaded", readyStateListener);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
if (readyStateListener) {
|
|
284
|
+
readyStateListener();
|
|
285
|
+
}
|
|
286
|
+
executionFunc();
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
myfaces.onOnDomReady = onOnDomReady;
|
|
255
290
|
/**
|
|
256
291
|
* legacy oam functions
|
|
257
292
|
*/
|
package/target/api/_api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_api.js","sourceRoot":"","sources":["../../src/main/typescript/api/_api.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;GAcG;AACH,+CAAgD;AAChD,+CAA0C;AAC1C,oDAAiD;AACjD,8CAAqH;AAIrH,4EAA4E;AAC5E,yBAAyB;AACzB,IAAc,KAAK,
|
|
1
|
+
{"version":3,"file":"_api.js","sourceRoot":"","sources":["../../src/main/typescript/api/_api.ts"],"names":[],"mappings":"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"}
|