jsf.js_next_gen 4.0.1-beta.2 → 4.0.1-beta.3
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 +6 -0
- package/dist/docs/assets/search.js +1 -1
- package/dist/docs/functions/myfaces.ab.html +1 -1
- package/dist/docs/functions/{myfaces.onOnDomReady.html → myfaces.onDomReady.html} +5 -5
- package/dist/docs/index.html +9 -0
- package/dist/docs/modules/myfaces.html +2 -2
- package/dist/docs/variables/myfaces.oam.html +1 -1
- package/dist/window/faces-development.js +1285 -1295
- 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 +1285 -1295
- 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 +5 -5
- package/plans for 4.0.1.txt +8 -0
- package/src/main/typescript/api/_api.ts +1 -1
- package/src/main/typescript/impl/AjaxImpl.ts +60 -44
- package/src/main/typescript/impl/core/Const.ts +5 -2
- package/src/main/typescript/impl/util/AsyncRunnable.ts +81 -6
- package/src/main/typescript/impl/util/ExtDomQuery.ts +7 -9
- package/src/main/typescript/impl/util/FileUtils.ts +26 -22
- package/src/main/typescript/impl/util/HiddenInputBuilder.ts +7 -3
- package/src/main/typescript/impl/util/Lang.ts +61 -4
- package/src/main/typescript/impl/util/XhrQueueController.ts +112 -0
- package/src/main/typescript/impl/xhrCore/EventData.ts +3 -3
- package/src/main/typescript/impl/xhrCore/ResponseProcessor.ts +12 -10
- package/src/main/typescript/impl/xhrCore/XhrFormData.ts +32 -19
- package/src/main/typescript/impl/xhrCore/XhrRequest.ts +51 -72
- package/src/main/typescript/myfaces/OamSubmit.ts +6 -6
- package/src/main/typescript/test/frameworkBase/_ext/monadish/DomQueryTest.spec.ts +179 -40
- package/src/main/typescript/test/frameworkBase/_ext/monadish/MonadTest.spec.ts +4 -4
- 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 +921 -0
- package/src/main/typescript/test/frameworkBase/_ext/monadish/markups/tobago-without-header.ts +108 -0
- package/src/main/typescript/test/frameworkBase/_ext/shared/StandardInits.ts +3 -2
- 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 +52 -0
- package/src/main/typescript/test/queue/AsynchronousProbe.ts +5 -5
- package/src/main/typescript/test/queue/AsynchronousQueueTest.spec.ts +4 -3
- package/src/main/typescript/test/xhrCore/EventTests.spec.ts +28 -22
- 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 +80 -6
- package/src/main/typescript/test/xhrCore/RequestTest_23.spec.ts +6 -1
- package/src/main/typescript/test/xhrCore/ResponseTest.spec.ts +23 -22
- package/target/api/_api.js +2 -2
- package/target/api/_api.js.map +1 -1
- package/target/impl/AjaxImpl.js +48 -38
- package/target/impl/AjaxImpl.js.map +1 -1
- package/target/impl/core/Const.js +7 -5
- package/target/impl/core/Const.js.map +1 -1
- package/target/impl/util/AsyncRunnable.js +60 -0
- 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 +21 -20
- package/target/impl/util/FileUtils.js.map +1 -1
- package/target/impl/util/HiddenInputBuilder.js +7 -3
- package/target/impl/util/HiddenInputBuilder.js.map +1 -1
- package/target/impl/util/Lang.js +52 -1
- 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 +9 -7
- package/target/impl/xhrCore/ResponseProcessor.js.map +1 -1
- package/target/impl/xhrCore/XhrFormData.js +29 -15
- package/target/impl/xhrCore/XhrFormData.js.map +1 -1
- package/target/impl/xhrCore/XhrRequest.js +43 -64
- package/target/impl/xhrCore/XhrRequest.js.map +1 -1
- package/target/myfaces/OamSubmit.js +5 -3
- package/target/myfaces/OamSubmit.js.map +1 -1
- package/target/test/frameworkBase/_ext/monadish/DomQueryTest.spec.js +138 -37
- 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 +3 -2
- 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/EventTests.spec.js +26 -19
- 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 +73 -4
- package/target/test/xhrCore/RequestTest.spec.js.map +1 -1
- package/target/test/xhrCore/RequestTest_23.spec.js +6 -0
- package/target/test/xhrCore/RequestTest_23.spec.js.map +1 -1
- package/target/test/xhrCore/ResponseTest.spec.js +22 -15
- package/target/test/xhrCore/ResponseTest.spec.js.map +1 -1
- package/src/main/typescript/impl/util/AsyncQueue.ts +0 -133
- package/src/main/typescript/test/frameworkBase/_ext/monadish/StreamTest.spec.ts +0 -231
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jsf.js_next_gen",
|
|
3
|
-
"version": "4.0.1-beta.
|
|
3
|
+
"version": "4.0.1-beta.3",
|
|
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.6",
|
|
27
27
|
"@types/sinon": "^10.0.13",
|
|
28
28
|
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
|
29
29
|
"chai": "^4.3.7",
|
|
@@ -39,16 +39,16 @@
|
|
|
39
39
|
"replace-in-file": "^6.3.5",
|
|
40
40
|
"rxjs": "^7.8.0",
|
|
41
41
|
"sinon": "^15.0.1",
|
|
42
|
-
"terser-webpack-plugin": "^5.3.
|
|
42
|
+
"terser-webpack-plugin": "^5.3.7",
|
|
43
43
|
"ts-loader": "^9.4.2",
|
|
44
44
|
"ts-node": "^10.9.1",
|
|
45
45
|
"typedoc": "^0.23.26",
|
|
46
46
|
"typescript": "^4.9.5",
|
|
47
|
-
"webpack": "^5.
|
|
47
|
+
"webpack": "^5.76.0",
|
|
48
48
|
"webpack-cli": "^5.0.1",
|
|
49
49
|
"webpack-dev-server": "^4.11.1"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"mona-dish": "0.
|
|
52
|
+
"mona-dish": "0.28.0"
|
|
53
53
|
}
|
|
54
54
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Brainstorming for 4.0.1
|
|
2
|
+
|
|
3
|
+
* Eliminate Streams - done, this was the biggest one
|
|
4
|
+
* Reintroduce partial page submit (myfaces.pps?), while never really used - done, pps=true is reintroduced
|
|
5
|
+
reducing the commit load onto execute!
|
|
6
|
+
|
|
7
|
+
queue size reduction... not really needed, there never was a usecase for it
|
|
8
|
+
|
|
@@ -277,7 +277,7 @@ export module myfaces {
|
|
|
277
277
|
*
|
|
278
278
|
* @param executionFunc the function to be executed upon ready
|
|
279
279
|
*/
|
|
280
|
-
export function
|
|
280
|
+
export function onDomReady(executionFunc: () => void) {
|
|
281
281
|
if(document.readyState !== "complete") {
|
|
282
282
|
onReadyChain.push(executionFunc);
|
|
283
283
|
if(!readyStateListener) {
|
|
@@ -17,8 +17,7 @@
|
|
|
17
17
|
import {IListener} from "./util/IListener";
|
|
18
18
|
import {Response} from "./xhrCore/Response";
|
|
19
19
|
import {XhrRequest} from "./xhrCore/XhrRequest";
|
|
20
|
-
import {
|
|
21
|
-
import {AssocArrayCollector, Config, DomQuery, DQ, DQ$, Lang, LazyStream, Optional, Stream} from "mona-dish";
|
|
20
|
+
import {Config, DQ, DQ$, Lang, Optional} from "mona-dish";
|
|
22
21
|
import {Assertions} from "./util/Assertions";
|
|
23
22
|
import {ExtConfig, ExtDomQuery} from "./util/ExtDomQuery";
|
|
24
23
|
import {ErrorData} from "./xhrCore/ErrorData";
|
|
@@ -41,7 +40,7 @@ import {
|
|
|
41
40
|
P_CLIENT_WINDOW,
|
|
42
41
|
P_EVT,
|
|
43
42
|
P_EXECUTE,
|
|
44
|
-
|
|
43
|
+
P_AJAX_SOURCE,
|
|
45
44
|
P_RENDER,
|
|
46
45
|
P_RESET_VALUES,
|
|
47
46
|
P_WINDOW_ID,
|
|
@@ -52,9 +51,11 @@ import {
|
|
|
52
51
|
VIEW_ID,
|
|
53
52
|
$faces,
|
|
54
53
|
EMPTY_STR,
|
|
55
|
-
CTX_PARAM_MF_INTERNAL,
|
|
56
54
|
NAMED_VIEWROOT,
|
|
57
|
-
NAMING_CONTAINER_ID,
|
|
55
|
+
NAMING_CONTAINER_ID,
|
|
56
|
+
CTX_PARAM_PPS,
|
|
57
|
+
MYFACES_OPTION_PPS,
|
|
58
|
+
$nsp
|
|
58
59
|
} from "./core/Const";
|
|
59
60
|
import {
|
|
60
61
|
resolveDefaults,
|
|
@@ -63,6 +64,7 @@ import {
|
|
|
63
64
|
resolveTimeout, resolveViewId, resolveViewRootId, resoveNamingContainerMapper
|
|
64
65
|
} from "./xhrCore/RequestDataResolver";
|
|
65
66
|
import {encodeFormData} from "./util/FileUtils";
|
|
67
|
+
import {XhrQueueController} from "./util/XhrQueueController";
|
|
66
68
|
|
|
67
69
|
/*
|
|
68
70
|
* allowed project stages
|
|
@@ -91,6 +93,8 @@ enum BlockFilter {
|
|
|
91
93
|
params = "params"
|
|
92
94
|
}
|
|
93
95
|
|
|
96
|
+
|
|
97
|
+
|
|
94
98
|
/**
|
|
95
99
|
* Core Implementation
|
|
96
100
|
* to distinct between api and impl
|
|
@@ -110,17 +114,7 @@ export module Implementation {
|
|
|
110
114
|
it provides following
|
|
111
115
|
|
|
112
116
|
a) Monad like structures for querying because this keeps the code denser and adds abstractions
|
|
113
|
-
that always was the strong point of
|
|
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!)
|
|
117
|
+
that always was the strong point of jQuery, and it still is better in this regard than what ecmascript provides
|
|
124
118
|
|
|
125
119
|
c) A neutral json like configuration which allows assignments of arbitrary values with reduce code which then can be
|
|
126
120
|
transformed into different data representations
|
|
@@ -157,12 +151,14 @@ export module Implementation {
|
|
|
157
151
|
import getMessage = ExtLang.getMessage;
|
|
158
152
|
import getGlobalConfig = ExtLang.getGlobalConfig;
|
|
159
153
|
import assert = Assertions.assert;
|
|
154
|
+
import ofAssoc = ExtLang.ofAssoc;
|
|
155
|
+
import collectAssoc = ExtLang.collectAssoc;
|
|
160
156
|
|
|
161
157
|
let projectStage: string = null;
|
|
162
158
|
let separator: string = null;
|
|
163
159
|
let eventQueue = [];
|
|
164
160
|
let errorQueue = [];
|
|
165
|
-
export let requestQueue:
|
|
161
|
+
export let requestQueue: XhrQueueController<XhrRequest> = null;
|
|
166
162
|
/*error reporting threshold*/
|
|
167
163
|
let threshold = "ERROR";
|
|
168
164
|
|
|
@@ -192,7 +188,7 @@ export module Implementation {
|
|
|
192
188
|
/**
|
|
193
189
|
* @return the project stage also emitted by the server:
|
|
194
190
|
* it cannot be cached and must be delivered over the server
|
|
195
|
-
* The value for it comes from the
|
|
191
|
+
* The value for it comes from the requestInternal parameter of the faces.js script called "stage".
|
|
196
192
|
*/
|
|
197
193
|
export function getProjectStage(): string | null {
|
|
198
194
|
return resolveGlobalConfig()?.projectStage ??
|
|
@@ -218,17 +214,21 @@ export module Implementation {
|
|
|
218
214
|
* @param event
|
|
219
215
|
* @param funcs
|
|
220
216
|
*/
|
|
221
|
-
export function chain(source:
|
|
222
|
-
// we can use our lazy stream each functionality to run our chain here
|
|
217
|
+
export function chain(source: any, event: Event, ...funcs: EvalFuncs): boolean {
|
|
218
|
+
// we can use our lazy stream each functionality to run our chain here.
|
|
223
219
|
// by passing a boolean as return value into the onElem call
|
|
224
220
|
// we can stop early at the first false, just like the spec requests
|
|
225
221
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
222
|
+
let ret;
|
|
223
|
+
funcs.every(func => {
|
|
224
|
+
let returnVal = resolveAndExecute(source, event, func);
|
|
225
|
+
if(returnVal !== false) {
|
|
226
|
+
ret = returnVal;
|
|
227
|
+
}
|
|
228
|
+
return returnVal !== false;
|
|
229
|
+
});
|
|
230
|
+
return ret;
|
|
231
|
+
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
/**
|
|
@@ -278,7 +278,7 @@ export module Implementation {
|
|
|
278
278
|
|
|
279
279
|
requestCtx.assignIf(!!windowId, P_WINDOW_ID).value = windowId;
|
|
280
280
|
|
|
281
|
-
// old non spec behavior will be removed after it is clear whether the removal breaks any code
|
|
281
|
+
// old non - spec behavior will be removed after it is clear whether the removal breaks any code
|
|
282
282
|
requestCtx.assign(CTX_PARAM_REQ_PASS_THR).value = extractLegacyParams(options.value);
|
|
283
283
|
|
|
284
284
|
// spec conform behavior, all passthrough params must be under "passthrough
|
|
@@ -310,14 +310,14 @@ export module Implementation {
|
|
|
310
310
|
requestCtx.assign(ON_ERROR).value = options.value?.onerror;
|
|
311
311
|
|
|
312
312
|
/**
|
|
313
|
-
*
|
|
313
|
+
* Fetch the myfaces config params
|
|
314
314
|
*/
|
|
315
315
|
requestCtx.assign(MYFACES).value = options.value?.myfaces;
|
|
316
316
|
|
|
317
317
|
/**
|
|
318
318
|
* binding contract the jakarta.faces.source must be set
|
|
319
319
|
*/
|
|
320
|
-
requestCtx.assign(CTX_PARAM_REQ_PASS_THR,
|
|
320
|
+
requestCtx.assign(CTX_PARAM_REQ_PASS_THR, P_AJAX_SOURCE).value = elementId;
|
|
321
321
|
|
|
322
322
|
/**
|
|
323
323
|
* jakarta.faces.partial.ajax must be set to true
|
|
@@ -344,6 +344,9 @@ export module Implementation {
|
|
|
344
344
|
// won't hurt but for the sake of compatibility we are going to add it
|
|
345
345
|
requestCtx.assign(CTX_PARAM_REQ_PASS_THR, formId).value = formId;
|
|
346
346
|
internalCtx.assign(CTX_PARAM_SRC_CTL_ID).value = elementId;
|
|
347
|
+
// reintroduction of PPS as per myfaces 2.3 (myfaces.pps = true, only the executes are submitted)
|
|
348
|
+
internalCtx.assign(CTX_PARAM_PPS).value = extractMyFacesParams(options.value)?.[MYFACES_OPTION_PPS] ?? false;
|
|
349
|
+
|
|
347
350
|
|
|
348
351
|
assignClientWindowId(form, requestCtx);
|
|
349
352
|
assignExecute(options, requestCtx, form, elementId);
|
|
@@ -424,7 +427,7 @@ export module Implementation {
|
|
|
424
427
|
}
|
|
425
428
|
} finally {
|
|
426
429
|
if (clearRequestQueue) {
|
|
427
|
-
requestQueue.
|
|
430
|
+
requestQueue.clear();
|
|
428
431
|
}
|
|
429
432
|
}
|
|
430
433
|
}
|
|
@@ -558,7 +561,7 @@ export module Implementation {
|
|
|
558
561
|
let formElements = element.deepElements.encodeFormElement()
|
|
559
562
|
|
|
560
563
|
// encode them! (file inputs are handled differently and are not part of the viewstate)
|
|
561
|
-
return encodeFormData(formElements, resoveNamingContainerMapper(dummyContext));
|
|
564
|
+
return encodeFormData(new ExtConfig(formElements), resoveNamingContainerMapper(dummyContext));
|
|
562
565
|
}
|
|
563
566
|
|
|
564
567
|
/**
|
|
@@ -573,8 +576,8 @@ export module Implementation {
|
|
|
573
576
|
* adds a new request to our queue for further processing
|
|
574
577
|
*/
|
|
575
578
|
addRequestToQueue: function (elem: DQ, form: DQ, reqCtx: ExtConfig, respPassThr: Config, delay = 0, timeout = 0) {
|
|
576
|
-
requestQueue = requestQueue ?? new
|
|
577
|
-
requestQueue.enqueue(new XhrRequest(
|
|
579
|
+
requestQueue = requestQueue ?? new XhrQueueController<XhrRequest>();
|
|
580
|
+
requestQueue.enqueue(new XhrRequest(reqCtx, respPassThr, timeout), delay);
|
|
578
581
|
}
|
|
579
582
|
};
|
|
580
583
|
|
|
@@ -683,7 +686,7 @@ export module Implementation {
|
|
|
683
686
|
* can deal with them either prefixed ir not
|
|
684
687
|
* also resolves the absolute id case (it was assumed the server does this, but
|
|
685
688
|
* apparently the RI does not, so we have to follow the RI behavior here)
|
|
686
|
-
* @param componentIdToTransform the componentId which needs post
|
|
689
|
+
* @param componentIdToTransform the componentId which needs post-processing
|
|
687
690
|
*/
|
|
688
691
|
const remapNamingContainer = componentIdToTransform => {
|
|
689
692
|
// pattern :<anything> must be prepended by viewRoot if there is one,
|
|
@@ -697,7 +700,7 @@ export module Implementation {
|
|
|
697
700
|
const hasLeadingSep = componentIdToTransform.indexOf(SEP) === 0;
|
|
698
701
|
const isAbsolutSearchExpr = hasLeadingSep || (rootNamingContainerId.length
|
|
699
702
|
&& componentIdToTransform.indexOf(rootNamingContainerPrefix) == 0);
|
|
700
|
-
let finalIdentifier
|
|
703
|
+
let finalIdentifier: string;
|
|
701
704
|
if (isAbsolutSearchExpr) {
|
|
702
705
|
//we cut off the leading sep if there is one
|
|
703
706
|
componentIdToTransform = hasLeadingSep ? componentIdToTransform.substring(1) : componentIdToTransform;
|
|
@@ -716,14 +719,14 @@ export module Implementation {
|
|
|
716
719
|
[rootNamingContainerPrefix, componentIdToTransform].join(EMPTY_STR) :
|
|
717
720
|
[nearestNamingContainerPrefix, componentIdToTransform].join(EMPTY_STR);
|
|
718
721
|
}
|
|
719
|
-
// We need to double
|
|
722
|
+
// We need to double-check because we have scenarios where we have a naming container
|
|
720
723
|
// and no prepend (aka tobago testcase "must handle ':' in IDs properly", scenario 3,
|
|
721
724
|
// in this case we return the component id, and be happy
|
|
722
725
|
// we can roll a dom check here
|
|
723
726
|
return (!!document.getElementById(finalIdentifier)) ? finalIdentifier : componentIdToTransform;
|
|
724
727
|
};
|
|
725
728
|
|
|
726
|
-
// in this case we do not use lazy stream because it
|
|
729
|
+
// in this case we do not use lazy stream because it won´t bring any code reduction
|
|
727
730
|
// or speedup
|
|
728
731
|
for (let cnt = 0; cnt < iterValues.length; cnt++) {
|
|
729
732
|
//avoid doubles
|
|
@@ -765,24 +768,37 @@ export module Implementation {
|
|
|
765
768
|
* the values required for params-through are processed in the ajax request
|
|
766
769
|
*
|
|
767
770
|
* Note this is a bug carried over from the old implementation
|
|
768
|
-
* the spec conform behavior is to use params for
|
|
771
|
+
* the spec conform behavior is to use params for pass - through values
|
|
769
772
|
* this will be removed soon, after it is cleared up whether removing
|
|
770
773
|
* it breaks any legacy code
|
|
771
774
|
*
|
|
772
775
|
* @param {Context} mappedOpts the options to be filtered
|
|
773
|
-
* @deprecated
|
|
774
776
|
*/
|
|
775
|
-
function extractLegacyParams(mappedOpts: Options):
|
|
777
|
+
function extractLegacyParams(mappedOpts: Options): {[key: string]: any} {
|
|
778
|
+
//we now can use the full code reduction given by our stream api
|
|
779
|
+
//to filter
|
|
780
|
+
return ofAssoc(mappedOpts)
|
|
781
|
+
.filter((item => !(item[0] in BlockFilter)))
|
|
782
|
+
.reduce(collectAssoc, {});
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* extracts the myfaces config parameters which provide extra functionality
|
|
787
|
+
* on top of JSF
|
|
788
|
+
* @param mappedOpts
|
|
789
|
+
* @private
|
|
790
|
+
*/
|
|
791
|
+
function extractMyFacesParams(mappedOpts: Options): {[key: string]: any} {
|
|
776
792
|
//we now can use the full code reduction given by our stream api
|
|
777
793
|
//to filter
|
|
778
|
-
return
|
|
779
|
-
.filter(item =>
|
|
780
|
-
.
|
|
794
|
+
return ofAssoc(mappedOpts)
|
|
795
|
+
.filter((item => (item[0] == "myfaces")))
|
|
796
|
+
.reduce(collectAssoc, {})?.[MYFACES];
|
|
781
797
|
}
|
|
782
798
|
|
|
783
799
|
function remapArrayToAssocArr(arrayedParams: [[string, any]] | {[key: string]: any}): {[key: string]: any} {
|
|
784
800
|
if(Array.isArray(arrayedParams)) {
|
|
785
|
-
return
|
|
801
|
+
return arrayedParams.reduce(collectAssoc, {} as any);
|
|
786
802
|
}
|
|
787
803
|
return arrayedParams;
|
|
788
804
|
}
|
|
@@ -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_AJAX_SOURCE = "jakarta.faces.source";
|
|
25
|
+
export const NAMING_CONTAINER_ID = "myfaces.NamingContainerId";
|
|
26
26
|
|
|
27
27
|
export const VIEW_ID = "myfaces.viewId";
|
|
28
28
|
export const P_VIEWSTATE = "jakarta.faces.ViewState";
|
|
@@ -108,6 +108,7 @@ 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";
|
|
111
112
|
|
|
112
113
|
export const CONTENT_TYPE = "Content-Type";
|
|
113
114
|
export const HEAD_FACES_REQ = "Faces-Request";
|
|
@@ -141,6 +142,8 @@ export const PHASE_PROCESS_RESPONSE = "processResponse";
|
|
|
141
142
|
|
|
142
143
|
export const ERR_NO_PARTIAL_RESPONSE = "Partial response not set";
|
|
143
144
|
|
|
145
|
+
export const MYFACES_OPTION_PPS = "pps";
|
|
146
|
+
|
|
144
147
|
export const ATTR_URL = "url";
|
|
145
148
|
export const ATTR_NAME = "name";
|
|
146
149
|
export const ATTR_VALUE = "value";
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* from the implementation side it is mostly registering callbacks
|
|
27
27
|
* and calling them at the appropriate time.
|
|
28
28
|
*/
|
|
29
|
-
export interface
|
|
29
|
+
export interface IAsyncRunnable<T> {
|
|
30
30
|
/**
|
|
31
31
|
* starts the runnable
|
|
32
32
|
*/
|
|
@@ -45,9 +45,9 @@ export interface AsyncRunnable<T> {
|
|
|
45
45
|
* and then triggers all the registered then functions
|
|
46
46
|
* when it is complete
|
|
47
47
|
*
|
|
48
|
-
* @param func
|
|
48
|
+
* @param func the then functor
|
|
49
49
|
*/
|
|
50
|
-
then(func: (data: any) => any):
|
|
50
|
+
then(func: (data: any) => any): IAsyncRunnable<T>;
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
53
|
* callback for catch functionality
|
|
@@ -59,7 +59,7 @@ export interface AsyncRunnable<T> {
|
|
|
59
59
|
*
|
|
60
60
|
* @param func
|
|
61
61
|
*/
|
|
62
|
-
catch(func: (data: any) => any):
|
|
62
|
+
catch(func: (data: any) => any): IAsyncRunnable<T>;
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
/**
|
|
@@ -68,5 +68,80 @@ export interface AsyncRunnable<T> {
|
|
|
68
68
|
* and once the finally time for the promise has
|
|
69
69
|
* come the finally functions must be performed
|
|
70
70
|
*/
|
|
71
|
-
finally(func: () => void):
|
|
72
|
-
}
|
|
71
|
+
finally(func: () => void): IAsyncRunnable<T>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* pretty much the same as cancellable Promise, but given
|
|
77
|
+
* we do not have that on browser level yet this is sort
|
|
78
|
+
* of a non - intrusive Shim!
|
|
79
|
+
*/
|
|
80
|
+
export abstract class AsyncRunnable<T> implements IAsyncRunnable<T>{
|
|
81
|
+
/**
|
|
82
|
+
* helper support so that we do not have to drag in Promise shims
|
|
83
|
+
*/
|
|
84
|
+
private catchFunctions: Array<Function> = [];
|
|
85
|
+
private thenFunctions: Array<Function> = [];
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* cancel the run of the runnable (which then depending on the implementation
|
|
89
|
+
* either triggers indirectly resolve or reject)
|
|
90
|
+
*/
|
|
91
|
+
abstract cancel(): void;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* extended functionality start to trigger the runnable
|
|
95
|
+
*/
|
|
96
|
+
abstract start(): void;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* resolve handler function which calls the then chain
|
|
100
|
+
* and after that finally
|
|
101
|
+
* @param data
|
|
102
|
+
*/
|
|
103
|
+
resolve(data: any) {
|
|
104
|
+
this.thenFunctions.reduce((inputVal: any, thenFunc: any) => {
|
|
105
|
+
return thenFunc(inputVal);
|
|
106
|
+
}, data)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* reject handler function which triggers the catch chain
|
|
111
|
+
* @param data
|
|
112
|
+
*/
|
|
113
|
+
reject(data: any) {
|
|
114
|
+
this.catchFunctions.reduce((inputVal: any, catchFunc: any) => {
|
|
115
|
+
return catchFunc(inputVal);
|
|
116
|
+
}, data);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* register a catch functor
|
|
121
|
+
* @param func the functor for the catch monad
|
|
122
|
+
*/
|
|
123
|
+
catch(func: (data: any) => any): IAsyncRunnable<T> {
|
|
124
|
+
this.catchFunctions.push(func);
|
|
125
|
+
return this;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* registers a finally functor
|
|
130
|
+
* @param func the functor for the finally handling chanin
|
|
131
|
+
*/
|
|
132
|
+
finally(func: () => void): IAsyncRunnable<T> {
|
|
133
|
+
// no ie11 support we probably are going to revert to shims for that one
|
|
134
|
+
this.catchFunctions.push(func);
|
|
135
|
+
this.thenFunctions.push(func);
|
|
136
|
+
return this;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @param func then functor similar to promise
|
|
141
|
+
*/
|
|
142
|
+
then(func: (data: any) => any): IAsyncRunnable<T> {
|
|
143
|
+
this.thenFunctions.push(func);
|
|
144
|
+
return this;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import {Config, IValueHolder, Optional, DomQuery, DQ
|
|
16
|
+
import {Config, IValueHolder, Optional, DomQuery, DQ} from "mona-dish";
|
|
17
17
|
import {$nsp, P_WINDOW_ID} from "../core/Const";
|
|
18
18
|
|
|
19
19
|
|
|
@@ -120,12 +120,10 @@ export class ExtDomQuery extends DQ {
|
|
|
120
120
|
}
|
|
121
121
|
// fallback if the currentScript method fails, we just search the jsf tags for nonce, this is
|
|
122
122
|
// the last possibility
|
|
123
|
-
let nonceScript = DQ
|
|
124
|
-
.querySelectorAll("script[src], link[src]")
|
|
125
|
-
.lazyStream
|
|
123
|
+
let nonceScript = Optional.fromNullable(DQ
|
|
124
|
+
.querySelectorAll("script[src], link[src]").asArray
|
|
126
125
|
.filter((item) => this.extractNonce(item) && item.attr(ATTR_SRC) != null)
|
|
127
|
-
.filter(item => IS_FACES_SOURCE(item.attr(ATTR_SRC).value))
|
|
128
|
-
.first();
|
|
126
|
+
.filter(item => IS_FACES_SOURCE(item.attr(ATTR_SRC).value))?.[0]);
|
|
129
127
|
|
|
130
128
|
if (nonceScript.isPresent()) {
|
|
131
129
|
return this.extractNonce(nonceScript.value);
|
|
@@ -144,13 +142,13 @@ export class ExtDomQuery extends DQ {
|
|
|
144
142
|
*/
|
|
145
143
|
searchJsfJsFor(regExp: RegExp): Optional<string> {
|
|
146
144
|
//perfect application for lazy stream
|
|
147
|
-
return DQ.querySelectorAll("script[src], link[src]").
|
|
145
|
+
return Optional.fromNullable(DQ.querySelectorAll("script[src], link[src]").asArray
|
|
148
146
|
.filter(item => IS_FACES_SOURCE(item.attr(ATTR_SRC).value))
|
|
149
147
|
.map(item => item.attr(ATTR_SRC).value.match(regExp))
|
|
150
148
|
.filter(item => item != null && item.length > 1)
|
|
151
149
|
.map((result: string[]) => {
|
|
152
150
|
return decodeURIComponent(result[1]);
|
|
153
|
-
})
|
|
151
|
+
})?.[0]);
|
|
154
152
|
}
|
|
155
153
|
|
|
156
154
|
globalEval(code: string, nonce ?: string): DQ {
|
|
@@ -332,6 +330,6 @@ export class ExtConfig extends Config {
|
|
|
332
330
|
if(!this.$nspEnabled) {
|
|
333
331
|
return accessPath;
|
|
334
332
|
}
|
|
335
|
-
return
|
|
333
|
+
return [...accessPath].map(key => $nsp(key));
|
|
336
334
|
}
|
|
337
335
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {Config, DomQuery, DQ} from "mona-dish";
|
|
2
2
|
import {ExtDomQuery} from "./ExtDomQuery";
|
|
3
3
|
import {$faces, EMPTY_STR} from "../core/Const";
|
|
4
4
|
|
|
@@ -22,27 +22,24 @@ export function encodeFormData(formData: Config,
|
|
|
22
22
|
}
|
|
23
23
|
const assocValues = formData.value;
|
|
24
24
|
|
|
25
|
-
const expandValueArrAndRename = key =>
|
|
25
|
+
const expandValueArrAndRename = key => assocValues[key].map(val => paramsMapper(key, val));
|
|
26
26
|
const isPropertyKey = key => assocValues.hasOwnProperty(key);
|
|
27
27
|
const isNotFile = ([, value]) => !(value instanceof ExtDomQuery.global().File);
|
|
28
28
|
const mapIntoUrlParam = keyVal => `${encodeURIComponent(keyVal[0])}=${encodeURIComponent(keyVal[1])}`;
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
return Object.keys(assocValues)
|
|
31
31
|
.filter(isPropertyKey)
|
|
32
32
|
.flatMap(expandValueArrAndRename)
|
|
33
|
-
//we cannot encode file elements that is handled by multipart requests anyway
|
|
34
33
|
.filter(isNotFile)
|
|
35
34
|
.map(mapIntoUrlParam)
|
|
36
|
-
.
|
|
37
|
-
|
|
38
|
-
return entries.join("&")
|
|
35
|
+
.join("&");
|
|
39
36
|
}
|
|
40
37
|
|
|
41
38
|
/**
|
|
42
39
|
* splits and decodes encoded values into strings containing of key=value
|
|
43
40
|
* @param encoded encoded string
|
|
44
41
|
*/
|
|
45
|
-
export function decodeEncodedValues(encoded: string):
|
|
42
|
+
export function decodeEncodedValues(encoded: string): string[][] {
|
|
46
43
|
const filterBlanks = item => !!(item || '').replace(/\s+/g, '');
|
|
47
44
|
const splitKeyValuePair = line => {
|
|
48
45
|
let index = line.indexOf("=");
|
|
@@ -53,9 +50,7 @@ export function decodeEncodedValues(encoded: string): Stream<string[]> {
|
|
|
53
50
|
};
|
|
54
51
|
|
|
55
52
|
let requestParamEntries = decodeURIComponent(encoded).split(/&/gi);
|
|
56
|
-
return
|
|
57
|
-
.filter(filterBlanks)
|
|
58
|
-
.map(splitKeyValuePair)
|
|
53
|
+
return requestParamEntries.filter(filterBlanks).map(splitKeyValuePair);
|
|
59
54
|
}
|
|
60
55
|
|
|
61
56
|
|
|
@@ -63,19 +58,28 @@ export function decodeEncodedValues(encoded: string): Stream<string[]> {
|
|
|
63
58
|
* gets all the input files and their corresponding file objects
|
|
64
59
|
* @param dataSource
|
|
65
60
|
*/
|
|
66
|
-
export function resolveFiles(dataSource: DQ):
|
|
61
|
+
export function resolveFiles(dataSource: DQ): [string, File][] {
|
|
62
|
+
|
|
63
|
+
const expandFilesArr = ([key, files]) => {
|
|
64
|
+
return [...files].map(file => [key, file]);
|
|
65
|
+
}
|
|
66
|
+
const remapFileInput = fileInput => {
|
|
67
|
+
return [fileInput.name.value || fileInput.id.value, fileInput.filesFromElem(0)];
|
|
68
|
+
}
|
|
67
69
|
|
|
68
|
-
const
|
|
69
|
-
const remapFileInput = fileInput => [fileInput.name.value || fileInput.id.value, fileInput.filesFromElem(0)];
|
|
70
|
-
return dataSource
|
|
70
|
+
const files = dataSource
|
|
71
71
|
.querySelectorAllDeep("input[type='file']")
|
|
72
|
-
.
|
|
72
|
+
.asArray;
|
|
73
|
+
|
|
74
|
+
const ret = files
|
|
73
75
|
.map(remapFileInput)
|
|
74
76
|
.flatMap(expandFilesArr);
|
|
77
|
+
|
|
78
|
+
return ret as any;
|
|
75
79
|
}
|
|
76
80
|
|
|
77
81
|
|
|
78
|
-
export function
|
|
82
|
+
export function fixEmptyParameters(keyVal: any[]): [string, any] {
|
|
79
83
|
return (keyVal.length < 3 ? [keyVal?.[0] ?? [], keyVal?.[1] ?? []] : keyVal) as [string, any];
|
|
80
84
|
}
|
|
81
85
|
|
|
@@ -83,7 +87,7 @@ export function fixEmmptyParameters(keyVal: any[]): [string, any] {
|
|
|
83
87
|
* returns the decoded viewState from parentItem
|
|
84
88
|
* @param parentItem
|
|
85
89
|
*/
|
|
86
|
-
function resolveViewState(parentItem: DomQuery):
|
|
90
|
+
function resolveViewState(parentItem: DomQuery): string[][] | [string, File][] {
|
|
87
91
|
const viewStateStr = $faces().getViewState(parentItem.getAsElem(0).value);
|
|
88
92
|
|
|
89
93
|
// we now need to decode it and then merge it into the target buf
|
|
@@ -94,11 +98,11 @@ function resolveViewState(parentItem: DomQuery): Stream<string[] | [string, File
|
|
|
94
98
|
|
|
95
99
|
/**
|
|
96
100
|
* gets all the inputs under the form parentItem
|
|
97
|
-
* as
|
|
101
|
+
* as array
|
|
98
102
|
* @param parentItem
|
|
99
103
|
*/
|
|
100
|
-
export function
|
|
101
|
-
const standardInputs = resolveViewState(parentItem);
|
|
104
|
+
export function getFormInputsAsArr(parentItem: DomQuery): string[][] | [string, File][] {
|
|
105
|
+
const standardInputs: any = resolveViewState(parentItem);
|
|
102
106
|
const fileInputs = resolveFiles(parentItem);
|
|
103
|
-
return
|
|
107
|
+
return standardInputs.concat(...fileInputs)
|
|
104
108
|
}
|
|
@@ -58,13 +58,17 @@ export class HiddenInputBuilder {
|
|
|
58
58
|
const SEP = $faces().separatorchar;
|
|
59
59
|
|
|
60
60
|
let existingStates = DQ$(`[name*='${$nsp(this.name)}']`);
|
|
61
|
-
let cnt = existingStates.
|
|
61
|
+
let cnt = existingStates.asArray.map(state => {
|
|
62
62
|
let ident: string = state.id.orElse("-1").value;
|
|
63
63
|
ident = ident.substring(ident.lastIndexOf(SEP)+1);
|
|
64
64
|
return parseInt(ident);
|
|
65
65
|
})
|
|
66
|
-
.filter(item =>
|
|
67
|
-
|
|
66
|
+
.filter(item => {
|
|
67
|
+
return !isNaN(item);
|
|
68
|
+
})
|
|
69
|
+
.reduce((item1, item2) => {
|
|
70
|
+
return Math.max(item1, item2);
|
|
71
|
+
}, -1);
|
|
68
72
|
//the maximum new ident is the current max + 1
|
|
69
73
|
cnt++;
|
|
70
74
|
|