jsf.js_next_gen 4.0.1-alpha.0 → 4.0.1-beta.2
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/README.md +0 -12
- package/dist/docs/assets/search.js +1 -1
- package/dist/docs/functions/faces.ajax.addOnError.html +4 -4
- 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.util.chain.html +3 -3
- package/dist/docs/functions/myfaces.ab.html +1 -1
- package/dist/docs/functions/{myfaces.onDomReady.html → myfaces.onOnDomReady.html} +5 -5
- package/dist/docs/index.html +0 -14
- package/dist/docs/modules/myfaces.html +2 -2
- package/dist/docs/variables/myfaces.oam.html +1 -1
- package/dist/window/faces-development.js +1323 -1300
- 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 +1323 -1300
- 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 +3 -3
- package/pom.xml +1 -1
- package/src/main/typescript/@types/definitions/index.d.ts +5 -5
- package/src/main/typescript/api/_api.ts +12 -13
- package/src/main/typescript/impl/AjaxImpl.ts +68 -65
- package/src/main/typescript/impl/core/Const.ts +2 -5
- package/src/main/typescript/impl/util/AsyncQueue.ts +133 -0
- package/src/main/typescript/impl/util/AsyncRunnable.ts +6 -81
- package/src/main/typescript/impl/util/ExtDomQuery.ts +9 -7
- package/src/main/typescript/impl/util/FileUtils.ts +22 -26
- package/src/main/typescript/impl/util/HiddenInputBuilder.ts +3 -7
- package/src/main/typescript/impl/util/Lang.ts +4 -61
- package/src/main/typescript/impl/xhrCore/EventData.ts +3 -3
- package/src/main/typescript/impl/xhrCore/ResponseProcessor.ts +10 -12
- package/src/main/typescript/impl/xhrCore/XhrFormData.ts +19 -32
- package/src/main/typescript/impl/xhrCore/XhrRequest.ts +72 -51
- package/src/main/typescript/myfaces/OamSubmit.ts +6 -6
- package/src/main/typescript/test/frameworkBase/_ext/monadish/DomQueryTest.spec.ts +40 -179
- package/src/main/typescript/test/frameworkBase/_ext/monadish/MonadTest.spec.ts +4 -4
- package/src/main/typescript/test/frameworkBase/_ext/monadish/StreamTest.spec.ts +231 -0
- package/src/main/typescript/test/frameworkBase/_ext/shared/StandardInits.ts +4 -5
- package/src/main/typescript/test/queue/AsynchronousProbe.ts +5 -5
- package/src/main/typescript/test/queue/AsynchronousQueueTest.spec.ts +3 -4
- package/src/main/typescript/test/xhrCore/ClientWindow.spec.ts +78 -0
- package/src/main/typescript/test/xhrCore/EventTests.spec.ts +22 -28
- package/src/main/typescript/test/xhrCore/NamespacesRequestTest.spec.ts +4 -4
- package/src/main/typescript/test/xhrCore/RequestParamsTest.spec.ts +2 -2
- package/src/main/typescript/test/xhrCore/RequestTest.spec.ts +6 -80
- package/src/main/typescript/test/xhrCore/RequestTest_23.spec.ts +1 -6
- package/src/main/typescript/test/xhrCore/ResponseTest.spec.ts +22 -23
- package/src/main/typescript/test/xhrCore/TobagoFileUploadTest.spec.ts +5 -5
- package/target/api/_api.js +11 -12
- package/target/api/_api.js.map +1 -1
- package/target/impl/AjaxImpl.js +59 -55
- package/target/impl/AjaxImpl.js.map +1 -1
- package/target/impl/core/Const.js +5 -7
- package/target/impl/core/Const.js.map +1 -1
- package/target/impl/util/AsyncRunnable.js +0 -60
- package/target/impl/util/AsyncRunnable.js.map +1 -1
- package/target/impl/util/ExtDomQuery.js +8 -8
- package/target/impl/util/ExtDomQuery.js.map +1 -1
- package/target/impl/util/FileUtils.js +20 -21
- package/target/impl/util/FileUtils.js.map +1 -1
- package/target/impl/util/HiddenInputBuilder.js +3 -7
- package/target/impl/util/HiddenInputBuilder.js.map +1 -1
- package/target/impl/util/Lang.js +1 -52
- package/target/impl/util/Lang.js.map +1 -1
- package/target/impl/xhrCore/EventData.js +2 -2
- package/target/impl/xhrCore/EventData.js.map +1 -1
- package/target/impl/xhrCore/ResponseProcessor.js +7 -9
- package/target/impl/xhrCore/ResponseProcessor.js.map +1 -1
- package/target/impl/xhrCore/XhrFormData.js +15 -29
- package/target/impl/xhrCore/XhrFormData.js.map +1 -1
- package/target/impl/xhrCore/XhrRequest.js +64 -43
- package/target/impl/xhrCore/XhrRequest.js.map +1 -1
- package/target/myfaces/OamSubmit.js +3 -5
- package/target/myfaces/OamSubmit.js.map +1 -1
- package/target/test/frameworkBase/_ext/monadish/DomQueryTest.spec.js +37 -138
- package/target/test/frameworkBase/_ext/monadish/DomQueryTest.spec.js.map +1 -1
- package/target/test/frameworkBase/_ext/monadish/MonadTest.spec.js +4 -4
- package/target/test/frameworkBase/_ext/monadish/MonadTest.spec.js.map +1 -1
- package/target/test/frameworkBase/_ext/shared/StandardInits.js +4 -5
- package/target/test/frameworkBase/_ext/shared/StandardInits.js.map +1 -1
- package/target/test/queue/AsynchronousQueueTest.spec.js +3 -3
- package/target/test/queue/AsynchronousQueueTest.spec.js.map +1 -1
- package/target/test/xhrCore/ClientWindow.spec.js +90 -0
- package/target/test/xhrCore/ClientWindow.spec.js.map +1 -0
- package/target/test/xhrCore/EventTests.spec.js +19 -26
- package/target/test/xhrCore/EventTests.spec.js.map +1 -1
- package/target/test/xhrCore/NamespacesRequestTest.spec.js +3 -3
- package/target/test/xhrCore/NamespacesRequestTest.spec.js.map +1 -1
- package/target/test/xhrCore/RequestParamsTest.spec.js +1 -1
- package/target/test/xhrCore/RequestParamsTest.spec.js.map +1 -1
- package/target/test/xhrCore/RequestTest.spec.js +4 -73
- package/target/test/xhrCore/RequestTest.spec.js.map +1 -1
- package/target/test/xhrCore/RequestTest_23.spec.js +0 -6
- package/target/test/xhrCore/RequestTest_23.spec.js.map +1 -1
- package/target/test/xhrCore/ResponseTest.spec.js +15 -22
- package/target/test/xhrCore/ResponseTest.spec.js.map +1 -1
- package/target/test/xhrCore/TobagoFileUploadTest.spec.js +5 -5
- package/target/test/xhrCore/TobagoFileUploadTest.spec.js.map +1 -1
- package/plans for 4.0.1.txt +0 -8
- package/src/main/typescript/impl/util/XhrQueueController.ts +0 -112
- package/src/main/typescript/test/frameworkBase/_ext/monadish/fixtures/blank.css +0 -0
- package/src/main/typescript/test/frameworkBase/_ext/monadish/markups/tobago-with-header.ts +0 -921
- package/src/main/typescript/test/frameworkBase/_ext/monadish/markups/tobago-without-header.ts +0 -108
- package/src/main/typescript/test/frameworkBase/_ext/shared/fixtures/jakarta.faces.resource/faces.js.jsf +0 -0
- package/src/main/typescript/test/myfaces/OnLoadSpec.ts +0 -52
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jsf.js_next_gen",
|
|
3
|
-
"version": "4.0.1-
|
|
3
|
+
"version": "4.0.1-beta.2",
|
|
4
4
|
"description": "A next generation typescript reimplementation of jsf.js",
|
|
5
5
|
"main": "dist/window/faces.js",
|
|
6
6
|
"scripts": {
|
|
@@ -23,7 +23,7 @@
|
|
|
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.14.
|
|
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",
|
|
@@ -49,6 +49,6 @@
|
|
|
49
49
|
"webpack-dev-server": "^4.11.1"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"mona-dish": "0.
|
|
52
|
+
"mona-dish": "0.26.0"
|
|
53
53
|
}
|
|
54
54
|
}
|
package/pom.xml
CHANGED
|
@@ -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
|
|
|
@@ -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,10 +152,10 @@ 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
161
|
* @param errorFunc error handler must be of the format <i>function errorListener(<errorData>)</i>
|
|
@@ -189,7 +188,7 @@ export module faces {
|
|
|
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
|
}
|
|
@@ -278,7 +277,7 @@ export module myfaces {
|
|
|
278
277
|
*
|
|
279
278
|
* @param executionFunc the function to be executed upon ready
|
|
280
279
|
*/
|
|
281
|
-
export function
|
|
280
|
+
export function onOnDomReady(executionFunc: () => void) {
|
|
282
281
|
if(document.readyState !== "complete") {
|
|
283
282
|
onReadyChain.push(executionFunc);
|
|
284
283
|
if(!readyStateListener) {
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
import {IListener} from "./util/IListener";
|
|
18
18
|
import {Response} from "./xhrCore/Response";
|
|
19
19
|
import {XhrRequest} from "./xhrCore/XhrRequest";
|
|
20
|
-
import {
|
|
20
|
+
import {AsynchronousQueue} from "./util/AsyncQueue";
|
|
21
|
+
import {AssocArrayCollector, Config, DomQuery, DQ, DQ$, Lang, LazyStream, Optional, Stream} from "mona-dish";
|
|
21
22
|
import {Assertions} from "./util/Assertions";
|
|
22
23
|
import {ExtConfig, ExtDomQuery} from "./util/ExtDomQuery";
|
|
23
24
|
import {ErrorData} from "./xhrCore/ErrorData";
|
|
@@ -40,7 +41,7 @@ import {
|
|
|
40
41
|
P_CLIENT_WINDOW,
|
|
41
42
|
P_EVT,
|
|
42
43
|
P_EXECUTE,
|
|
43
|
-
|
|
44
|
+
P_PARTIAL_SOURCE,
|
|
44
45
|
P_RENDER,
|
|
45
46
|
P_RESET_VALUES,
|
|
46
47
|
P_WINDOW_ID,
|
|
@@ -51,8 +52,9 @@ import {
|
|
|
51
52
|
VIEW_ID,
|
|
52
53
|
$faces,
|
|
53
54
|
EMPTY_STR,
|
|
55
|
+
CTX_PARAM_MF_INTERNAL,
|
|
54
56
|
NAMED_VIEWROOT,
|
|
55
|
-
NAMING_CONTAINER_ID,
|
|
57
|
+
NAMING_CONTAINER_ID, $nsp
|
|
56
58
|
} from "./core/Const";
|
|
57
59
|
import {
|
|
58
60
|
resolveDefaults,
|
|
@@ -61,7 +63,6 @@ import {
|
|
|
61
63
|
resolveTimeout, resolveViewId, resolveViewRootId, resoveNamingContainerMapper
|
|
62
64
|
} from "./xhrCore/RequestDataResolver";
|
|
63
65
|
import {encodeFormData} from "./util/FileUtils";
|
|
64
|
-
import {XhrQueueController} from "./util/XhrQueueController";
|
|
65
66
|
|
|
66
67
|
/*
|
|
67
68
|
* allowed project stages
|
|
@@ -90,8 +91,6 @@ enum BlockFilter {
|
|
|
90
91
|
params = "params"
|
|
91
92
|
}
|
|
92
93
|
|
|
93
|
-
|
|
94
|
-
|
|
95
94
|
/**
|
|
96
95
|
* Core Implementation
|
|
97
96
|
* to distinct between api and impl
|
|
@@ -111,7 +110,17 @@ export module Implementation {
|
|
|
111
110
|
it provides following
|
|
112
111
|
|
|
113
112
|
a) Monad like structures for querying because this keeps the code denser and adds abstractions
|
|
114
|
-
that always was the strong point of
|
|
113
|
+
that always was the strong point of jquery and it still is better in this regard than what ecmascript provides
|
|
114
|
+
|
|
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
|
+
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
|
|
119
|
+
quite well and where I can patch quickly (I have used it in several industrial projects, so it works well
|
|
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!)
|
|
115
124
|
|
|
116
125
|
c) A neutral json like configuration which allows assignments of arbitrary values with reduce code which then can be
|
|
117
126
|
transformed into different data representations
|
|
@@ -148,14 +157,12 @@ export module Implementation {
|
|
|
148
157
|
import getMessage = ExtLang.getMessage;
|
|
149
158
|
import getGlobalConfig = ExtLang.getGlobalConfig;
|
|
150
159
|
import assert = Assertions.assert;
|
|
151
|
-
import ofAssoc = ExtLang.ofAssoc;
|
|
152
|
-
import collectAssoc = ExtLang.collectAssoc;
|
|
153
160
|
|
|
154
161
|
let projectStage: string = null;
|
|
155
162
|
let separator: string = null;
|
|
156
163
|
let eventQueue = [];
|
|
157
164
|
let errorQueue = [];
|
|
158
|
-
export let requestQueue:
|
|
165
|
+
export let requestQueue: AsynchronousQueue<XhrRequest> = null;
|
|
159
166
|
/*error reporting threshold*/
|
|
160
167
|
let threshold = "ERROR";
|
|
161
168
|
|
|
@@ -185,7 +192,7 @@ export module Implementation {
|
|
|
185
192
|
/**
|
|
186
193
|
* @return the project stage also emitted by the server:
|
|
187
194
|
* it cannot be cached and must be delivered over the server
|
|
188
|
-
* The value for it comes from the
|
|
195
|
+
* The value for it comes from the request parameter of the faces.js script called "stage".
|
|
189
196
|
*/
|
|
190
197
|
export function getProjectStage(): string | null {
|
|
191
198
|
return resolveGlobalConfig()?.projectStage ??
|
|
@@ -211,21 +218,17 @@ export module Implementation {
|
|
|
211
218
|
* @param event
|
|
212
219
|
* @param funcs
|
|
213
220
|
*/
|
|
214
|
-
export function chain(source:
|
|
215
|
-
// we can use our lazy stream each functionality to run our chain here
|
|
221
|
+
export function chain(source: HTMLElement | string, event: Event | null, ...funcs: EvalFuncs): boolean {
|
|
222
|
+
// we can use our lazy stream each functionality to run our chain here..
|
|
216
223
|
// by passing a boolean as return value into the onElem call
|
|
217
224
|
// we can stop early at the first false, just like the spec requests
|
|
218
225
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
return returnVal !== false;
|
|
226
|
-
});
|
|
227
|
-
return ret;
|
|
228
|
-
|
|
226
|
+
return LazyStream.of(...funcs)
|
|
227
|
+
.map(func => resolveAndExecute(source, event, func))
|
|
228
|
+
// we use the return false == stop as an early stop, onElem stops at the first false
|
|
229
|
+
.onElem((opResult: boolean) => opResult)
|
|
230
|
+
//last ensures we run until the first false is returned
|
|
231
|
+
.last().value;
|
|
229
232
|
}
|
|
230
233
|
|
|
231
234
|
/**
|
|
@@ -275,7 +278,7 @@ export module Implementation {
|
|
|
275
278
|
|
|
276
279
|
requestCtx.assignIf(!!windowId, P_WINDOW_ID).value = windowId;
|
|
277
280
|
|
|
278
|
-
// old non
|
|
281
|
+
// old non spec behavior will be removed after it is clear whether the removal breaks any code
|
|
279
282
|
requestCtx.assign(CTX_PARAM_REQ_PASS_THR).value = extractLegacyParams(options.value);
|
|
280
283
|
|
|
281
284
|
// spec conform behavior, all passthrough params must be under "passthrough
|
|
@@ -307,14 +310,14 @@ export module Implementation {
|
|
|
307
310
|
requestCtx.assign(ON_ERROR).value = options.value?.onerror;
|
|
308
311
|
|
|
309
312
|
/**
|
|
310
|
-
*
|
|
313
|
+
* lets drag the myfaces config params also in
|
|
311
314
|
*/
|
|
312
315
|
requestCtx.assign(MYFACES).value = options.value?.myfaces;
|
|
313
316
|
|
|
314
317
|
/**
|
|
315
318
|
* binding contract the jakarta.faces.source must be set
|
|
316
319
|
*/
|
|
317
|
-
requestCtx.assign(CTX_PARAM_REQ_PASS_THR,
|
|
320
|
+
requestCtx.assign(CTX_PARAM_REQ_PASS_THR, P_PARTIAL_SOURCE).value = elementId;
|
|
318
321
|
|
|
319
322
|
/**
|
|
320
323
|
* jakarta.faces.partial.ajax must be set to true
|
|
@@ -341,9 +344,6 @@ export module Implementation {
|
|
|
341
344
|
// won't hurt but for the sake of compatibility we are going to add it
|
|
342
345
|
requestCtx.assign(CTX_PARAM_REQ_PASS_THR, formId).value = formId;
|
|
343
346
|
internalCtx.assign(CTX_PARAM_SRC_CTL_ID).value = elementId;
|
|
344
|
-
// reintroduction of PPS as per myfaces 2.3 (myfaces.pps = true, only the executes are submitted)
|
|
345
|
-
internalCtx.assign(CTX_PARAM_PPS).value = extractMyFacesParams(options.value)?.[MYFACES_OPTION_PPS] ?? false;
|
|
346
|
-
|
|
347
347
|
|
|
348
348
|
assignClientWindowId(form, requestCtx);
|
|
349
349
|
assignExecute(options, requestCtx, form, elementId);
|
|
@@ -424,7 +424,7 @@ export module Implementation {
|
|
|
424
424
|
}
|
|
425
425
|
} finally {
|
|
426
426
|
if (clearRequestQueue) {
|
|
427
|
-
requestQueue.
|
|
427
|
+
requestQueue.cleanup();
|
|
428
428
|
}
|
|
429
429
|
}
|
|
430
430
|
}
|
|
@@ -467,12 +467,29 @@ export module Implementation {
|
|
|
467
467
|
/*
|
|
468
468
|
* the search root for the dom element search
|
|
469
469
|
*/
|
|
470
|
-
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
let searchRoot = ((node) ? DQ.byId(node): DQ$("form"));
|
|
473
|
+
let inputs = searchRoot
|
|
474
|
+
.filterSelector(`input[name='${$nsp(P_CLIENT_WINDOW)}']`)
|
|
475
|
+
.orElseLazy(() => searchRoot.querySelectorAll(`input[name='${$nsp(P_CLIENT_WINDOW)}']`))
|
|
471
476
|
|
|
472
477
|
/*
|
|
473
|
-
* lazy helper to fetch the window id from the
|
|
478
|
+
* lazy helper to fetch the window id from the included faces.js
|
|
474
479
|
*/
|
|
475
|
-
let
|
|
480
|
+
let fetchWindowIdFromJSFJS = () => ExtDomQuery.searchJsfJsFor(/jfwid=([^&;]*)/).orElse(null).value;
|
|
481
|
+
|
|
482
|
+
/*
|
|
483
|
+
* fetch window id from the url
|
|
484
|
+
*/
|
|
485
|
+
let fetchWindowIdFromURL = function () {
|
|
486
|
+
const href = window.location.href, windowId = "jfwid";
|
|
487
|
+
const regex = new RegExp("[\\?&]" + windowId + "=([^&#\\;]*)");
|
|
488
|
+
const results = regex.exec(href);
|
|
489
|
+
//initial trial over the url and a regexp
|
|
490
|
+
if (results != null) return results[1];
|
|
491
|
+
return null;
|
|
492
|
+
};
|
|
476
493
|
|
|
477
494
|
/*
|
|
478
495
|
* functional double check based on stream reduction
|
|
@@ -482,7 +499,7 @@ export module Implementation {
|
|
|
482
499
|
* @param value1
|
|
483
500
|
* @param value2
|
|
484
501
|
*/
|
|
485
|
-
let differenceCheck = (value1: string, value2: string) => {
|
|
502
|
+
let differenceCheck = (value1: string, value2: string): string => {
|
|
486
503
|
if(value1 == INIT) {
|
|
487
504
|
return value2;
|
|
488
505
|
} else if (value1 == ALTERED || value1 != value2) {
|
|
@@ -496,15 +513,14 @@ export module Implementation {
|
|
|
496
513
|
*
|
|
497
514
|
* @param item
|
|
498
515
|
*/
|
|
499
|
-
let getValue = (item: DQ) => item.
|
|
516
|
+
let getValue = (item: DQ): string => item.val as string;
|
|
500
517
|
/*
|
|
501
518
|
* fetch the window id from the forms
|
|
502
519
|
* window ids must be present in all forms
|
|
503
520
|
* or non-existent. If they exist all of them must be the same
|
|
504
521
|
*/
|
|
505
522
|
|
|
506
|
-
let formWindowId: Optional<string> =
|
|
507
|
-
.map<string>(getValue).reduce(differenceCheck, INIT));
|
|
523
|
+
let formWindowId: Optional<string> = inputs.stream.map(getValue).reduce(differenceCheck, INIT);
|
|
508
524
|
|
|
509
525
|
|
|
510
526
|
//if the resulting window id is set on altered then we have an unresolvable problem
|
|
@@ -513,7 +529,7 @@ export module Implementation {
|
|
|
513
529
|
/*
|
|
514
530
|
* return the window id or null
|
|
515
531
|
*/
|
|
516
|
-
return formWindowId.value != INIT ? formWindowId.value :
|
|
532
|
+
return formWindowId.value != INIT ? formWindowId.value : (fetchWindowIdFromURL() || fetchWindowIdFromJSFJS());
|
|
517
533
|
}
|
|
518
534
|
|
|
519
535
|
/**
|
|
@@ -542,7 +558,7 @@ export module Implementation {
|
|
|
542
558
|
let formElements = element.deepElements.encodeFormElement()
|
|
543
559
|
|
|
544
560
|
// encode them! (file inputs are handled differently and are not part of the viewstate)
|
|
545
|
-
return encodeFormData(
|
|
561
|
+
return encodeFormData(formElements, resoveNamingContainerMapper(dummyContext));
|
|
546
562
|
}
|
|
547
563
|
|
|
548
564
|
/**
|
|
@@ -557,8 +573,8 @@ export module Implementation {
|
|
|
557
573
|
* adds a new request to our queue for further processing
|
|
558
574
|
*/
|
|
559
575
|
addRequestToQueue: function (elem: DQ, form: DQ, reqCtx: ExtConfig, respPassThr: Config, delay = 0, timeout = 0) {
|
|
560
|
-
requestQueue = requestQueue ?? new
|
|
561
|
-
requestQueue.enqueue(new XhrRequest(reqCtx, respPassThr, timeout), delay);
|
|
576
|
+
requestQueue = requestQueue ?? new AsynchronousQueue<XhrRequest>();
|
|
577
|
+
requestQueue.enqueue(new XhrRequest(elem, form, reqCtx, respPassThr, [], timeout), delay);
|
|
562
578
|
}
|
|
563
579
|
};
|
|
564
580
|
|
|
@@ -667,7 +683,7 @@ export module Implementation {
|
|
|
667
683
|
* can deal with them either prefixed ir not
|
|
668
684
|
* also resolves the absolute id case (it was assumed the server does this, but
|
|
669
685
|
* apparently the RI does not, so we have to follow the RI behavior here)
|
|
670
|
-
* @param componentIdToTransform the componentId which needs post
|
|
686
|
+
* @param componentIdToTransform the componentId which needs post processing
|
|
671
687
|
*/
|
|
672
688
|
const remapNamingContainer = componentIdToTransform => {
|
|
673
689
|
// pattern :<anything> must be prepended by viewRoot if there is one,
|
|
@@ -681,7 +697,7 @@ export module Implementation {
|
|
|
681
697
|
const hasLeadingSep = componentIdToTransform.indexOf(SEP) === 0;
|
|
682
698
|
const isAbsolutSearchExpr = hasLeadingSep || (rootNamingContainerId.length
|
|
683
699
|
&& componentIdToTransform.indexOf(rootNamingContainerPrefix) == 0);
|
|
684
|
-
let finalIdentifier
|
|
700
|
+
let finalIdentifier = "";
|
|
685
701
|
if (isAbsolutSearchExpr) {
|
|
686
702
|
//we cut off the leading sep if there is one
|
|
687
703
|
componentIdToTransform = hasLeadingSep ? componentIdToTransform.substring(1) : componentIdToTransform;
|
|
@@ -700,14 +716,14 @@ export module Implementation {
|
|
|
700
716
|
[rootNamingContainerPrefix, componentIdToTransform].join(EMPTY_STR) :
|
|
701
717
|
[nearestNamingContainerPrefix, componentIdToTransform].join(EMPTY_STR);
|
|
702
718
|
}
|
|
703
|
-
// We need to double
|
|
719
|
+
// We need to double check because we have scenarios where we have a naming container
|
|
704
720
|
// and no prepend (aka tobago testcase "must handle ':' in IDs properly", scenario 3,
|
|
705
721
|
// in this case we return the component id, and be happy
|
|
706
722
|
// we can roll a dom check here
|
|
707
723
|
return (!!document.getElementById(finalIdentifier)) ? finalIdentifier : componentIdToTransform;
|
|
708
724
|
};
|
|
709
725
|
|
|
710
|
-
// in this case we do not use lazy stream because it
|
|
726
|
+
// in this case we do not use lazy stream because it wont bring any code reduction
|
|
711
727
|
// or speedup
|
|
712
728
|
for (let cnt = 0; cnt < iterValues.length; cnt++) {
|
|
713
729
|
//avoid doubles
|
|
@@ -749,37 +765,24 @@ export module Implementation {
|
|
|
749
765
|
* the values required for params-through are processed in the ajax request
|
|
750
766
|
*
|
|
751
767
|
* Note this is a bug carried over from the old implementation
|
|
752
|
-
* the spec conform behavior is to use params for
|
|
768
|
+
* the spec conform behavior is to use params for passthrough values
|
|
753
769
|
* this will be removed soon, after it is cleared up whether removing
|
|
754
770
|
* it breaks any legacy code
|
|
755
771
|
*
|
|
756
772
|
* @param {Context} mappedOpts the options to be filtered
|
|
773
|
+
* @deprecated
|
|
757
774
|
*/
|
|
758
|
-
function extractLegacyParams(mappedOpts: Options):
|
|
759
|
-
//we now can use the full code reduction given by our stream api
|
|
760
|
-
//to filter
|
|
761
|
-
return ofAssoc(mappedOpts)
|
|
762
|
-
.filter((item => !(item[0] in BlockFilter)))
|
|
763
|
-
.reduce(collectAssoc, {});
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
/**
|
|
767
|
-
* extracts the myfaces config parameters which provide extra functionality
|
|
768
|
-
* on top of JSF
|
|
769
|
-
* @param mappedOpts
|
|
770
|
-
* @private
|
|
771
|
-
*/
|
|
772
|
-
function extractMyFacesParams(mappedOpts: Options): {[key: string]: any} {
|
|
775
|
+
function extractLegacyParams(mappedOpts: Options): Context {
|
|
773
776
|
//we now can use the full code reduction given by our stream api
|
|
774
777
|
//to filter
|
|
775
|
-
return ofAssoc(mappedOpts)
|
|
776
|
-
.filter(
|
|
777
|
-
.
|
|
778
|
+
return Stream.ofAssoc(mappedOpts)
|
|
779
|
+
.filter(item => !(item[0] in BlockFilter))
|
|
780
|
+
.collect(new AssocArrayCollector());
|
|
778
781
|
}
|
|
779
782
|
|
|
780
783
|
function remapArrayToAssocArr(arrayedParams: [[string, any]] | {[key: string]: any}): {[key: string]: any} {
|
|
781
784
|
if(Array.isArray(arrayedParams)) {
|
|
782
|
-
return arrayedParams.
|
|
785
|
+
return Stream.of(... arrayedParams).collect(new AssocArrayCollector());
|
|
783
786
|
}
|
|
784
787
|
return arrayedParams;
|
|
785
788
|
}
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
export const XML_ATTR_NAMED_VIEWROOT = "namedViewRoot";
|
|
22
22
|
export const NAMED_VIEWROOT = "namedViewRoot";
|
|
23
23
|
|
|
24
|
-
export const
|
|
25
|
-
export const NAMING_CONTAINER_ID = "myfaces.
|
|
24
|
+
export const P_PARTIAL_SOURCE = "jakarta.faces.source";
|
|
25
|
+
export const NAMING_CONTAINER_ID = "myfaces.partialId";
|
|
26
26
|
|
|
27
27
|
export const VIEW_ID = "myfaces.viewId";
|
|
28
28
|
export const P_VIEWSTATE = "jakarta.faces.ViewState";
|
|
@@ -108,7 +108,6 @@ export const CTX_PARAM_MF_INTERNAL = "myfaces.internal";
|
|
|
108
108
|
export const CTX_PARAM_SRC_FRM_ID = "myfaces.source.formId";
|
|
109
109
|
export const CTX_PARAM_SRC_CTL_ID = "myfaces.source.controlId";
|
|
110
110
|
export const CTX_PARAM_REQ_PASS_THR = "myfaces.request.passThrough";
|
|
111
|
-
export const CTX_PARAM_PPS = "myfaces.request.pps";
|
|
112
111
|
|
|
113
112
|
export const CONTENT_TYPE = "Content-Type";
|
|
114
113
|
export const HEAD_FACES_REQ = "Faces-Request";
|
|
@@ -142,8 +141,6 @@ export const PHASE_PROCESS_RESPONSE = "processResponse";
|
|
|
142
141
|
|
|
143
142
|
export const ERR_NO_PARTIAL_RESPONSE = "Partial response not set";
|
|
144
143
|
|
|
145
|
-
export const MYFACES_OPTION_PPS = "pps";
|
|
146
|
-
|
|
147
144
|
export const ATTR_URL = "url";
|
|
148
145
|
export const ATTR_NAME = "name";
|
|
149
146
|
export const ATTR_VALUE = "value";
|
|
@@ -0,0 +1,133 @@
|
|
|
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 {AsyncRunnable} from "./AsyncRunnable";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Asynchronous queue which starts to work
|
|
20
|
+
* through the callbacks until the queue is empty
|
|
21
|
+
*
|
|
22
|
+
* Every callback must be of async runnable
|
|
23
|
+
* which is sort of an extended promise which has
|
|
24
|
+
* added a dedicated cancel and start point
|
|
25
|
+
*
|
|
26
|
+
* This interface can be used as wrapper contract
|
|
27
|
+
* for normal promises if needed.
|
|
28
|
+
*/
|
|
29
|
+
export class AsynchronousQueue<T extends AsyncRunnable<any>> {
|
|
30
|
+
|
|
31
|
+
private runnableQueue = [];
|
|
32
|
+
private delayTimeout: null | ReturnType<typeof setTimeout>;
|
|
33
|
+
|
|
34
|
+
currentlyRunning: AsyncRunnable<any>;
|
|
35
|
+
|
|
36
|
+
constructor() {
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* simple is empty accessor, returns true if queue is empty atm
|
|
41
|
+
*/
|
|
42
|
+
get isEmpty(): boolean {
|
|
43
|
+
return !this.runnableQueue.length;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* enqueues an element and starts the
|
|
48
|
+
* asynchronous work loop if not already running
|
|
49
|
+
*
|
|
50
|
+
* @param element the element to be queued and processed
|
|
51
|
+
* @param delay possible delay after our usual process or drop if something newer is incoming algorithm
|
|
52
|
+
*/
|
|
53
|
+
enqueue(element: T, delay = 0) {
|
|
54
|
+
if (this.delayTimeout) {
|
|
55
|
+
clearTimeout(this.delayTimeout);
|
|
56
|
+
this.delayTimeout = null;
|
|
57
|
+
}
|
|
58
|
+
if (delay) {
|
|
59
|
+
this.delayTimeout = setTimeout(() => {
|
|
60
|
+
this.appendElement(element);
|
|
61
|
+
}) as any;
|
|
62
|
+
} else {
|
|
63
|
+
this.appendElement(element);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* fetches the next element from the queue (first in first out order)
|
|
69
|
+
*/
|
|
70
|
+
dequeue(): T | undefined{
|
|
71
|
+
return this.runnableQueue.shift();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* clears up all elements from the queue
|
|
76
|
+
*/
|
|
77
|
+
cleanup() {
|
|
78
|
+
this.currentlyRunning = null;
|
|
79
|
+
this.runnableQueue.length = 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* cancels the currently running element and then cleans up the queue
|
|
84
|
+
* aka cancel the queue entirely
|
|
85
|
+
*/
|
|
86
|
+
cancel() {
|
|
87
|
+
try {
|
|
88
|
+
if (this.currentlyRunning) {
|
|
89
|
+
this.currentlyRunning.cancel();
|
|
90
|
+
}
|
|
91
|
+
} finally {
|
|
92
|
+
this.cleanup();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private callForNextElementToProcess() {
|
|
97
|
+
this.runEntry();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private appendElement(element: T) {
|
|
101
|
+
//only if the first element is added we start with a trigger
|
|
102
|
+
//otherwise a process already is running and not finished yet at that
|
|
103
|
+
//time
|
|
104
|
+
this.runnableQueue.push(element);
|
|
105
|
+
if (!this.currentlyRunning) {
|
|
106
|
+
this.runEntry();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private runEntry() {
|
|
111
|
+
if (this.isEmpty) {
|
|
112
|
+
this.currentlyRunning = null;
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
this.currentlyRunning = this.dequeue();
|
|
116
|
+
this.currentlyRunning
|
|
117
|
+
.catch((e) => {
|
|
118
|
+
//in case of an error we always clean up the remaining calls
|
|
119
|
+
//to allow a clean recovery of the application
|
|
120
|
+
this.cleanup();
|
|
121
|
+
throw e;
|
|
122
|
+
})
|
|
123
|
+
.then(
|
|
124
|
+
//the idea is to trigger the next over an event to reduce
|
|
125
|
+
//the number of recursive calls (stacks might be limited
|
|
126
|
+
//compared to ram)
|
|
127
|
+
//naturally give we have a DOM, the DOM is the natural event dispatch system
|
|
128
|
+
//which we can use, to decouple the calls from a recursive stack call
|
|
129
|
+
//(the browser engine will take care of that)
|
|
130
|
+
() => this.callForNextElementToProcess()
|
|
131
|
+
).start();
|
|
132
|
+
}
|
|
133
|
+
}
|