jsf.js_next_gen 4.0.0-RC.22 → 4.0.0-RC.25
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/dist/window/faces-development.js +117 -33
- 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 +117 -33
- 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 +2 -2
- package/src/main/typescript/impl/AjaxImpl.ts +31 -3
- package/src/main/typescript/impl/core/Const.ts +1 -1
- package/src/main/typescript/impl/xhrCore/IResponseProcessor.ts +7 -0
- package/src/main/typescript/impl/xhrCore/RequestDataResolver.ts +28 -1
- package/src/main/typescript/impl/xhrCore/Response.ts +31 -26
- package/src/main/typescript/impl/xhrCore/ResponseProcessor.ts +16 -4
- package/src/main/typescript/impl/xhrCore/XhrFormData.ts +40 -18
- package/src/main/typescript/impl/xhrCore/XhrRequest.ts +17 -8
- package/src/main/typescript/test/xhrCore/FileUploadTest.spec.ts +2 -0
- package/src/main/typescript/test/xhrCore/NamespacesRequestTest.spec.ts +8 -8
- package/src/main/typescript/test/xhrCore/ResponseTest.spec.ts +6 -5
- package/src/main/typescript/test/xhrCore/ResponseTest23.spec.ts +2 -2
- package/src/main/typescript/test/xhrCore/XhrFormDataTest.spec.ts +1 -0
- package/target/impl/AjaxImpl.js +19 -1
- package/target/impl/AjaxImpl.js.map +1 -1
- package/target/impl/core/Const.js +2 -2
- package/target/impl/core/Const.js.map +1 -1
- package/target/impl/xhrCore/RequestDataResolver.js +28 -1
- package/target/impl/xhrCore/RequestDataResolver.js.map +1 -1
- package/target/impl/xhrCore/Response.js +16 -13
- package/target/impl/xhrCore/Response.js.map +1 -1
- package/target/impl/xhrCore/ResponseProcessor.js +14 -3
- package/target/impl/xhrCore/ResponseProcessor.js.map +1 -1
- package/target/impl/xhrCore/XhrFormData.js +31 -12
- package/target/impl/xhrCore/XhrFormData.js.map +1 -1
- package/target/impl/xhrCore/XhrRequest.js +1 -1
- package/target/impl/xhrCore/XhrRequest.js.map +1 -1
- package/target/test/xhrCore/FileUploadTest.spec.js +1 -0
- package/target/test/xhrCore/FileUploadTest.spec.js.map +1 -1
- package/target/test/xhrCore/NamespacesRequestTest.spec.js +8 -7
- package/target/test/xhrCore/NamespacesRequestTest.spec.js.map +1 -1
- package/target/test/xhrCore/ResponseTest.spec.js +6 -3
- package/target/test/xhrCore/ResponseTest.spec.js.map +1 -1
- package/target/test/xhrCore/ResponseTest23.spec.js +2 -2
- package/target/test/xhrCore/ResponseTest23.spec.js.map +1 -1
- package/target/test/xhrCore/XhrFormDataTest.spec.js +1 -0
- package/target/test/xhrCore/XhrFormDataTest.spec.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jsf.js_next_gen",
|
|
3
|
-
"version": "4.0.0-RC.
|
|
3
|
+
"version": "4.0.0-RC.25",
|
|
4
4
|
"description": "A next generation typescript reimplementation of jsf.js",
|
|
5
5
|
"main": "dist/window/faces.js",
|
|
6
6
|
"scripts": {
|
|
@@ -48,6 +48,6 @@
|
|
|
48
48
|
"webpack-dev-server": "^4.11.1"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"mona-dish": "^0.24.
|
|
51
|
+
"mona-dish": "^0.24.4"
|
|
52
52
|
}
|
|
53
53
|
}
|
|
@@ -48,13 +48,20 @@ import {
|
|
|
48
48
|
P_WINDOW_ID,
|
|
49
49
|
CTX_PARAM_RENDER,
|
|
50
50
|
SOURCE,
|
|
51
|
-
HTML_TAG_FORM,
|
|
51
|
+
HTML_TAG_FORM,
|
|
52
|
+
CTX_OPTIONS_PARAMS,
|
|
53
|
+
VIEW_ID,
|
|
54
|
+
$faces,
|
|
55
|
+
EMPTY_STR,
|
|
56
|
+
CTX_PARAM_MF_INTERNAL,
|
|
57
|
+
NAMED_VIEWROOT,
|
|
58
|
+
NAMING_CONTAINER_ID
|
|
52
59
|
} from "./core/Const";
|
|
53
60
|
import {
|
|
54
61
|
resolveDefaults,
|
|
55
62
|
resolveDelay,
|
|
56
63
|
resolveForm,
|
|
57
|
-
resolveTimeout, resolveViewId
|
|
64
|
+
resolveTimeout, resolveViewId, resolveViewRootId, resoveNamingContainerMapper
|
|
58
65
|
} from "./xhrCore/RequestDataResolver";
|
|
59
66
|
|
|
60
67
|
/*
|
|
@@ -337,6 +344,7 @@ export module Implementation {
|
|
|
337
344
|
assignClientWindowId(form, requestCtx);
|
|
338
345
|
assignExecute(options, requestCtx, form, elementId);
|
|
339
346
|
assignRender(options, requestCtx, form, elementId);
|
|
347
|
+
assignNamingContainerData(internalCtx, form);
|
|
340
348
|
|
|
341
349
|
//now we enqueue the request as asynchronous runnable into our request
|
|
342
350
|
//queue and let the queue take over the rest
|
|
@@ -522,7 +530,10 @@ export module Implementation {
|
|
|
522
530
|
throw new Error(getMessage("ERR_VIEWSTATE"));
|
|
523
531
|
}
|
|
524
532
|
|
|
525
|
-
|
|
533
|
+
const dummyContext = new Config({});
|
|
534
|
+
assignNamingContainerData(dummyContext, DQ.byId(form))
|
|
535
|
+
|
|
536
|
+
let formData = new XhrFormData(element, resoveNamingContainerMapper(dummyContext));
|
|
526
537
|
return formData.toString();
|
|
527
538
|
}
|
|
528
539
|
|
|
@@ -603,6 +614,23 @@ export module Implementation {
|
|
|
603
614
|
}
|
|
604
615
|
}
|
|
605
616
|
|
|
617
|
+
/**
|
|
618
|
+
* determines the current naming container
|
|
619
|
+
* and assigns it internally
|
|
620
|
+
*
|
|
621
|
+
* @param internalContext
|
|
622
|
+
* @param formElement
|
|
623
|
+
* @private
|
|
624
|
+
*/
|
|
625
|
+
function assignNamingContainerData(internalContext: Config, formElement: DQ) {
|
|
626
|
+
const viewRootId = resolveViewRootId(formElement);
|
|
627
|
+
|
|
628
|
+
if(!!viewRootId) {
|
|
629
|
+
internalContext.assign(NAMED_VIEWROOT).value = true;
|
|
630
|
+
internalContext.assign(NAMING_CONTAINER_ID).value = viewRootId;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
|
|
606
634
|
/**
|
|
607
635
|
* transforms the user values to the expected one
|
|
608
636
|
* with the proper none all form and this handling
|
|
@@ -22,7 +22,7 @@ export const XML_ATTR_NAMED_VIEWROOT = "namedViewRoot";
|
|
|
22
22
|
export const NAMED_VIEWROOT = "namedViewRoot";
|
|
23
23
|
|
|
24
24
|
export const P_PARTIAL_SOURCE = "jakarta.faces.source";
|
|
25
|
-
export const
|
|
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";
|
|
@@ -149,4 +149,11 @@ export interface IResponseProcessor {
|
|
|
149
149
|
* send last event
|
|
150
150
|
*/
|
|
151
151
|
done(): void;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* update internal state to
|
|
155
|
+
* check whether we still are in a named view root
|
|
156
|
+
* (can change after a navigation)
|
|
157
|
+
*/
|
|
158
|
+
updateNamedViewRootState();
|
|
152
159
|
}
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
DELAY_NONE,
|
|
24
24
|
EMPTY_FUNC,
|
|
25
25
|
EMPTY_STR,
|
|
26
|
-
ENCODED_URL,
|
|
26
|
+
ENCODED_URL, NAMED_VIEWROOT, NAMING_CONTAINER_ID,
|
|
27
27
|
P_VIEWSTATE,
|
|
28
28
|
REQ_TYPE_GET,
|
|
29
29
|
REQ_TYPE_POST
|
|
@@ -50,6 +50,7 @@ import {Assertions} from "../util/Assertions";
|
|
|
50
50
|
* @param funcName
|
|
51
51
|
*/
|
|
52
52
|
export function resolveHandlerFunc(requestContext: Config, responseContext: Config, funcName: string) {
|
|
53
|
+
responseContext = responseContext || new Config({});
|
|
53
54
|
return responseContext.getIf(funcName)
|
|
54
55
|
.orElseLazy(() =>requestContext.getIf(funcName).value)
|
|
55
56
|
.orElse(EMPTY_FUNC).value;
|
|
@@ -89,6 +90,32 @@ export function resolveViewId(form: DQ): string {
|
|
|
89
90
|
return form.id.value.indexOf(viewStateViewId) === 0 ? viewStateViewId : "";
|
|
90
91
|
}
|
|
91
92
|
|
|
93
|
+
export function resolveViewRootId(form: DQ): string {
|
|
94
|
+
const viewState = form.querySelectorAll(`input[type='hidden'][name*='${$nsp(P_VIEWSTATE)}']`).attr("name").orElse("").value;
|
|
95
|
+
const divider = $faces().separatorchar;
|
|
96
|
+
const viewId = viewState.split(divider, 2)[0];
|
|
97
|
+
//different to the identifier the form id is never prepended to the viewstate
|
|
98
|
+
return viewId.indexOf($nsp(P_VIEWSTATE)) === -1 ? viewId : "";
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* as per jsdoc before the request it must be ensured that every post argument
|
|
103
|
+
* is prefixed with the naming container id (there is an exception in mojarra with
|
|
104
|
+
* the element=element param, which we have to follow here as well.
|
|
105
|
+
* (inputs are prefixed by name anyway normally this only affects our standard parameters)
|
|
106
|
+
* @private
|
|
107
|
+
*/
|
|
108
|
+
export function resoveNamingContainerMapper(internalContext: Config): (key: string, value: any) => [string, any] {
|
|
109
|
+
const isNamedViewRoot = internalContext.getIf(NAMED_VIEWROOT).isPresent();
|
|
110
|
+
if(!isNamedViewRoot) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const partialId = internalContext.getIf(NAMING_CONTAINER_ID).value;
|
|
114
|
+
const SEP = $faces().separatorchar;
|
|
115
|
+
const prefix = partialId + SEP;
|
|
116
|
+
return (key: string, value: any) => (key.indexOf(prefix) == 0) ? [key, value] : [prefix + key, value];
|
|
117
|
+
}
|
|
118
|
+
|
|
92
119
|
export function resolveTimeout(options: Config): number {
|
|
93
120
|
let getCfg = ExtLang.getLocalOrGlobalConfig;
|
|
94
121
|
return options.getIf(CTX_OPTIONS_TIMEOUT).value ?? getCfg(options.value, CTX_OPTIONS_TIMEOUT, 0);
|
|
@@ -32,11 +32,11 @@ import {
|
|
|
32
32
|
P_VIEWBODY,
|
|
33
33
|
P_VIEWHEAD,
|
|
34
34
|
P_VIEWROOT,
|
|
35
|
-
|
|
35
|
+
NAMING_CONTAINER_ID,
|
|
36
36
|
XML_TAG_PARTIAL_RESP,
|
|
37
37
|
RESPONSE_XML,
|
|
38
38
|
XML_TAG_AFTER,
|
|
39
|
-
XML_TAG_BEFORE, NAMED_VIEWROOT, XML_ATTR_NAMED_VIEWROOT
|
|
39
|
+
XML_TAG_BEFORE, NAMED_VIEWROOT, XML_ATTR_NAMED_VIEWROOT, P_VIEWSTATE, $faces
|
|
40
40
|
} from "../core/Const";
|
|
41
41
|
import {resolveContexts, resolveResponseXML} from "./ResonseDataResolver";
|
|
42
42
|
import {ExtConfig} from "../util/ExtDomQuery";
|
|
@@ -76,6 +76,7 @@ export module Response {
|
|
|
76
76
|
// doing any evaluations even on embedded scripts.
|
|
77
77
|
// Usually this does not matter, the client window comes in almost last always anyway
|
|
78
78
|
// we maybe drop this deferred assignment in the future, but myfaces did it until now.
|
|
79
|
+
responseProcessor.updateNamedViewRootState();
|
|
79
80
|
responseProcessor.fixViewStates();
|
|
80
81
|
responseProcessor.fixClientWindow();
|
|
81
82
|
responseProcessor.globalEval();
|
|
@@ -86,21 +87,25 @@ export module Response {
|
|
|
86
87
|
/**
|
|
87
88
|
* highest node partial-response from there the main operations are triggered
|
|
88
89
|
*/
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
90
|
+
function processPartialTag(node: XMLQuery, responseProcessor: IResponseProcessor, internalContext) {
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
/*
|
|
94
|
+
https://javaee.github.io/javaserverfaces/docs/2.2/javadocs/web-partialresponse.html#ns_xsd
|
|
95
|
+
The "partial-response" element is the root of the partial response information hierarchy,
|
|
96
|
+
and contains nested elements for all possible elements that can exist in the response.
|
|
97
|
+
This element must have an "id" attribute whose value is the return from calling getContainerClientId()
|
|
98
|
+
on the UIViewRoot to which this response pertains.
|
|
99
|
+
*/
|
|
100
|
+
// we can determine whether we are in a naming container scenario by checking whether the passed view id is present in the page
|
|
101
|
+
// under or in body as identifier
|
|
101
102
|
|
|
102
|
-
|
|
103
|
-
internalContext.
|
|
103
|
+
let partialId:string = node?.id?.value;
|
|
104
|
+
internalContext.assignIf(!!partialId, NAMING_CONTAINER_ID).value = partialId; // second case mojarra
|
|
105
|
+
|
|
106
|
+
// there must be at least one container viewstate element resembling the viewroot that we know
|
|
107
|
+
// this is named
|
|
108
|
+
responseProcessor.updateNamedViewRootState();
|
|
104
109
|
|
|
105
110
|
const SEL_SUB_TAGS = [XML_TAG_ERROR, XML_TAG_REDIRECT, XML_TAG_CHANGES].join(",");
|
|
106
111
|
|
|
@@ -122,12 +127,12 @@ export module Response {
|
|
|
122
127
|
}
|
|
123
128
|
|
|
124
129
|
let processInsert = function (responseProcessor: IResponseProcessor, node: XMLQuery) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
// path1 insert after as child tags
|
|
131
|
+
if(node.querySelectorAll([XML_TAG_BEFORE, XML_TAG_AFTER].join(",")).length) {
|
|
132
|
+
responseProcessor.insertWithSubTags(node);
|
|
133
|
+
} else { // insert before after with id
|
|
134
|
+
responseProcessor.insert(node);
|
|
135
|
+
}
|
|
131
136
|
|
|
132
137
|
};
|
|
133
138
|
|
|
@@ -137,7 +142,7 @@ export module Response {
|
|
|
137
142
|
* @param node
|
|
138
143
|
* @param responseProcessor
|
|
139
144
|
*/
|
|
140
|
-
|
|
145
|
+
function processChangesTag(node: XMLQuery, responseProcessor: IResponseProcessor): boolean {
|
|
141
146
|
const ALLOWED_TAGS = [XML_TAG_UPDATE, XML_TAG_EVAL, XML_TAG_INSERT, XML_TAG_DELETE, XML_TAG_ATTRIBUTES, XML_TAG_EXTENSION].join(", ");
|
|
142
147
|
node.querySelectorAll(ALLOWED_TAGS).each(
|
|
143
148
|
(node: XMLQuery) => {
|
|
@@ -190,8 +195,8 @@ export module Response {
|
|
|
190
195
|
* @param node
|
|
191
196
|
* @param responseProcessor
|
|
192
197
|
*/
|
|
193
|
-
|
|
194
|
-
|
|
198
|
+
function processUpdateTag(node: XMLQuery, responseProcessor: IResponseProcessor) {
|
|
199
|
+
// early state storing, if no state we perform a normal update cycle
|
|
195
200
|
if (!storeState(responseProcessor, node)) {
|
|
196
201
|
handleElementUpdate(node, responseProcessor);
|
|
197
202
|
}
|
|
@@ -203,7 +208,7 @@ export module Response {
|
|
|
203
208
|
* @param node
|
|
204
209
|
* @param responseProcessor
|
|
205
210
|
*/
|
|
206
|
-
|
|
211
|
+
function handleElementUpdate(node: XMLQuery, responseProcessor: IResponseProcessor) {
|
|
207
212
|
let cdataBlock = node.cDATAAsString;
|
|
208
213
|
switch (node.id.value) {
|
|
209
214
|
case $nsp(P_VIEWROOT) :
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
P_RENDER,
|
|
51
51
|
P_RENDER_OVERRIDE,
|
|
52
52
|
P_VIEWSTATE,
|
|
53
|
-
|
|
53
|
+
NAMING_CONTAINER_ID,
|
|
54
54
|
RESPONSE_XML,
|
|
55
55
|
SEL_CLIENT_WINDOW_ELEM,
|
|
56
56
|
SEL_VIEWSTATE_ELEM,
|
|
@@ -348,8 +348,8 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
348
348
|
fixViewStates() {
|
|
349
349
|
Stream.ofAssoc<StateHolder>(this.internalContext.getIf(APPLIED_VST).orElse({}).value)
|
|
350
350
|
.each(([, value]) => {
|
|
351
|
-
const namingContainerId = this.internalContext.getIf(
|
|
352
|
-
const namedViewRoot = !!this.internalContext.getIf(
|
|
351
|
+
const namingContainerId = this.internalContext.getIf(NAMING_CONTAINER_ID);
|
|
352
|
+
const namedViewRoot = !!this.internalContext.getIf(NAMED_VIEWROOT).value
|
|
353
353
|
const affectedForms = this.getContainerForms(namingContainerId)
|
|
354
354
|
.filter(affectedForm => this.isInExecuteOrRender(affectedForm));
|
|
355
355
|
|
|
@@ -366,7 +366,7 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
366
366
|
fixClientWindow() {
|
|
367
367
|
Stream.ofAssoc<StateHolder>(this.internalContext.getIf(APPLIED_CLIENT_WINDOW).orElse({}).value)
|
|
368
368
|
.each(([, value]) => {
|
|
369
|
-
const namingContainerId = this.internalContext.getIf(
|
|
369
|
+
const namingContainerId = this.internalContext.getIf(NAMING_CONTAINER_ID);
|
|
370
370
|
const namedViewRoot = !!this.internalContext.getIf(NAMED_VIEWROOT).value;
|
|
371
371
|
const affectedForms = this.getContainerForms(namingContainerId)
|
|
372
372
|
.filter(affectedForm => this.isInExecuteOrRender(affectedForm));
|
|
@@ -375,6 +375,18 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
375
375
|
});
|
|
376
376
|
}
|
|
377
377
|
|
|
378
|
+
updateNamedViewRootState() {
|
|
379
|
+
let partialId = this.internalContext.getIf(NAMING_CONTAINER_ID);
|
|
380
|
+
let namedViewRoot = this.internalContext.getIf(NAMED_VIEWROOT);
|
|
381
|
+
if(partialId.isPresent() &&
|
|
382
|
+
(namedViewRoot.isAbsent() ||
|
|
383
|
+
!namedViewRoot.value)) {
|
|
384
|
+
const SEP = $faces().separatorchar;
|
|
385
|
+
this.internalContext.assign(NAMED_VIEWROOT).value = (!!document.getElementById(partialId.value)) || DQ$(`input[name*='${$nsp(P_VIEWSTATE)}']`)
|
|
386
|
+
.filter(node => node.attr("name").value.indexOf(partialId.value + SEP) == 0).length > 0;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
378
390
|
/**
|
|
379
391
|
* all processing done we can close the request and send the appropriate events
|
|
380
392
|
*/
|
|
@@ -14,11 +14,14 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import {ArrayCollector, Config, DQ, Lang, LazyStream, Stream} from "mona-dish";
|
|
17
|
-
import {EMPTY_STR, IDENT_ALL, IDENT_FORM, P_VIEWSTATE} from "../core/Const";
|
|
17
|
+
import {$nsp, EMPTY_STR, IDENT_ALL, IDENT_FORM, P_VIEWSTATE} from "../core/Const";
|
|
18
18
|
import isString = Lang.isString;
|
|
19
19
|
import {ExtConfig, ExtDomQuery} from "../util/ExtDomQuery";
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
type ParamsMapper<V, K> = (key: V, item: K) => [V, K];
|
|
23
|
+
const defaultParamsMapper: ParamsMapper<string, any> = (key, item) => [key, item];
|
|
24
|
+
|
|
22
25
|
/**
|
|
23
26
|
* A unified form data class
|
|
24
27
|
* which builds upon our configuration.
|
|
@@ -49,7 +52,7 @@ export class XhrFormData extends Config {
|
|
|
49
52
|
* @param executes the executes id list for the elements to being processed
|
|
50
53
|
* @param partialIds partial ids to collect, to reduce the data sent down
|
|
51
54
|
*/
|
|
52
|
-
constructor(private dataSource: DQ | string, viewState?: string, executes?: string[], private partialIds?: string[]) {
|
|
55
|
+
constructor(private dataSource: DQ | string, private paramsMapper: ParamsMapper<string, any> = defaultParamsMapper, viewState?: string, executes?: string[], private partialIds?: string[]) {
|
|
53
56
|
super({});
|
|
54
57
|
//a call to getViewState before must pass the encoded line
|
|
55
58
|
//a call from getViewState passes the form element as datasource,
|
|
@@ -109,10 +112,10 @@ export class XhrFormData extends Config {
|
|
|
109
112
|
* @param form the form holding the view state value
|
|
110
113
|
*/
|
|
111
114
|
private applyViewState(form: DQ) {
|
|
112
|
-
let viewStateElement = form.querySelectorAllDeep(`[name*='${P_VIEWSTATE}'`);
|
|
115
|
+
let viewStateElement = form.querySelectorAllDeep(`[name*='${$nsp(P_VIEWSTATE)}'`);
|
|
113
116
|
let viewState = viewStateElement.inputValue;
|
|
114
117
|
// this.appendIf(viewState.isPresent(), P_VIEWSTATE).value = viewState.value;
|
|
115
|
-
this.appendIf(viewState.isPresent(), viewStateElement.name.value).value = viewState.value;
|
|
118
|
+
this.appendIf(viewState.isPresent(), this.remapKeyForNamingContainer(viewStateElement.name.value)).value = viewState.value;
|
|
116
119
|
}
|
|
117
120
|
|
|
118
121
|
/**
|
|
@@ -143,11 +146,11 @@ export class XhrFormData extends Config {
|
|
|
143
146
|
return keyVal.length < 3 ? [keyVal?.[0] ?? [], keyVal?.[1] ?? []] : keyVal;
|
|
144
147
|
}
|
|
145
148
|
|
|
146
|
-
//TODO fix files...
|
|
147
149
|
Stream.of(...keyValueEntries)
|
|
148
150
|
.map(line => splitToKeyVal(line))
|
|
149
151
|
//special case of having keys without values
|
|
150
152
|
.map(keyVal => fixKeyWithoutVal(keyVal))
|
|
153
|
+
.map(keyVal => this.paramsMapper(keyVal[0] as string, keyVal[1]))
|
|
151
154
|
.each(keyVal => {
|
|
152
155
|
toMerge.append(keyVal[0] as string).value = keyVal?.splice(1)?.join("") ?? "";
|
|
153
156
|
});
|
|
@@ -156,6 +159,7 @@ export class XhrFormData extends Config {
|
|
|
156
159
|
}
|
|
157
160
|
|
|
158
161
|
/**
|
|
162
|
+
* @param paramsMapper ... pre encode the params if needed, default is to map them 1:1
|
|
159
163
|
* @returns a Form data representation, this is needed for file submits
|
|
160
164
|
*/
|
|
161
165
|
toFormData(): FormData {
|
|
@@ -175,17 +179,18 @@ export class XhrFormData extends Config {
|
|
|
175
179
|
*
|
|
176
180
|
* @param defaultStr optional default value if nothing is there to encode
|
|
177
181
|
*/
|
|
178
|
-
toString(defaultStr = EMPTY_STR): string {
|
|
182
|
+
toString( defaultStr = EMPTY_STR): string {
|
|
179
183
|
if (this.isAbsent()) {
|
|
180
184
|
return defaultStr;
|
|
181
185
|
}
|
|
182
186
|
let entries = LazyStream.of(...Object.keys(this.value))
|
|
183
187
|
.filter(key => this.value.hasOwnProperty(key))
|
|
184
|
-
.flatMap(key => Stream.of(...this.value[key])
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
188
|
+
.flatMap(key => Stream.of(...this.value[key])
|
|
189
|
+
.map(val => {
|
|
190
|
+
return this.paramsMapper(key, val)
|
|
191
|
+
}))
|
|
192
|
+
//we cannot encode file elements that is handled by multipart requests anyway
|
|
193
|
+
.filter(([, value]) => !(value instanceof ExtDomQuery.global().File))
|
|
189
194
|
.map(keyVal => {
|
|
190
195
|
return `${encodeURIComponent(keyVal[0])}=${encodeURIComponent(keyVal[1])}`;
|
|
191
196
|
})
|
|
@@ -222,8 +227,7 @@ export class XhrFormData extends Config {
|
|
|
222
227
|
*
|
|
223
228
|
*/
|
|
224
229
|
this.encodeSubmittableFields(this, <DQ>this.dataSource, this.partialIds);
|
|
225
|
-
|
|
226
|
-
if (this.getIf(P_VIEWSTATE).isPresent()) {
|
|
230
|
+
if (this.getIf($nsp(P_VIEWSTATE)).isPresent()) {
|
|
227
231
|
return;
|
|
228
232
|
}
|
|
229
233
|
|
|
@@ -251,13 +255,31 @@ export class XhrFormData extends Config {
|
|
|
251
255
|
}
|
|
252
256
|
|
|
253
257
|
//lets encode the form elements
|
|
254
|
-
|
|
258
|
+
let formElements = toEncode.deepElements.encodeFormElement();
|
|
259
|
+
const mapped = this.remapKeysForNamingCoontainer(formElements);
|
|
260
|
+
this.shallowMerge(mapped);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
private remapKeysForNamingCoontainer(formElements: Config): Config {
|
|
264
|
+
let ret = new Config({});
|
|
265
|
+
formElements.stream.map(([key, item]) => this.paramsMapper(key, item))
|
|
266
|
+
.each( ([key, item]) => {
|
|
267
|
+
ret.assign(key).value = item;
|
|
268
|
+
});
|
|
269
|
+
return ret;
|
|
270
|
+
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
private remapKeyForNamingContainer(key: string): string {
|
|
274
|
+
return this.paramsMapper(key, "")[0];
|
|
255
275
|
}
|
|
256
276
|
|
|
257
277
|
private appendInputs(ret: any) {
|
|
258
|
-
Stream.
|
|
259
|
-
.
|
|
260
|
-
Stream.of(...
|
|
261
|
-
|
|
278
|
+
Stream.ofAssoc(this.value)
|
|
279
|
+
.flatMap(([key, item]) =>
|
|
280
|
+
Stream.of(...(item as Array<any>)).map(item => {
|
|
281
|
+
return {key, item};
|
|
282
|
+
}))
|
|
283
|
+
.each(({key, item}) => ret.append(key, item))
|
|
262
284
|
}
|
|
263
285
|
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import {AsyncRunnable} from "../util/AsyncRunnable";
|
|
18
|
-
import {Config, DQ, Stream} from "mona-dish";
|
|
18
|
+
import {Config, DQ, DQ$, Stream} from "mona-dish";
|
|
19
19
|
import {Implementation} from "../AjaxImpl";
|
|
20
20
|
|
|
21
21
|
import {XhrFormData} from "./XhrFormData";
|
|
@@ -23,7 +23,7 @@ import {ErrorData} from "./ErrorData";
|
|
|
23
23
|
import {EventData} from "./EventData";
|
|
24
24
|
import {ExtLang} from "../util/Lang";
|
|
25
25
|
import {
|
|
26
|
-
$faces,
|
|
26
|
+
$faces, $nsp,
|
|
27
27
|
BEGIN,
|
|
28
28
|
COMPLETE,
|
|
29
29
|
CONTENT_TYPE,
|
|
@@ -31,10 +31,10 @@ import {
|
|
|
31
31
|
CTX_PARAM_REQ_PASS_THR,
|
|
32
32
|
ERROR,
|
|
33
33
|
HEAD_FACES_REQ,
|
|
34
|
-
MALFORMEDXML,
|
|
34
|
+
MALFORMEDXML, NAMED_VIEWROOT,
|
|
35
35
|
NO_TIMEOUT,
|
|
36
36
|
ON_ERROR,
|
|
37
|
-
ON_EVENT, P_EXECUTE, P_PARTIAL_SOURCE,
|
|
37
|
+
ON_EVENT, P_EXECUTE, P_PARTIAL_SOURCE, P_VIEWSTATE, NAMING_CONTAINER_ID,
|
|
38
38
|
REQ_ACCEPT,
|
|
39
39
|
REQ_TYPE_GET,
|
|
40
40
|
REQ_TYPE_POST, SOURCE,
|
|
@@ -43,9 +43,15 @@ import {
|
|
|
43
43
|
URL_ENCODED,
|
|
44
44
|
VAL_AJAX
|
|
45
45
|
} from "../core/Const";
|
|
46
|
-
import {
|
|
46
|
+
import {
|
|
47
|
+
resolveFinalUrl,
|
|
48
|
+
resolveHandlerFunc,
|
|
49
|
+
resolveViewRootId,
|
|
50
|
+
resoveNamingContainerMapper
|
|
51
|
+
} from "./RequestDataResolver";
|
|
47
52
|
import failSaveExecute = ExtLang.failSaveExecute;
|
|
48
53
|
import {ExtConfig} from "../util/ExtDomQuery";
|
|
54
|
+
import {ResponseProcessor} from "./ResponseProcessor";
|
|
49
55
|
|
|
50
56
|
/**
|
|
51
57
|
* Faces XHR Request Wrapper
|
|
@@ -115,10 +121,11 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
|
|
|
115
121
|
let executesArr = () => {
|
|
116
122
|
return this.requestContext.getIf(CTX_PARAM_REQ_PASS_THR, P_EXECUTE).get("none").value.split(/\s+/gi);
|
|
117
123
|
};
|
|
118
|
-
try {
|
|
119
124
|
|
|
125
|
+
try {
|
|
120
126
|
let formElement = this.sourceForm.getAsElem(0).value;
|
|
121
127
|
let viewState = $faces().getViewState(formElement);
|
|
128
|
+
|
|
122
129
|
// encoded we need to decode
|
|
123
130
|
// We generated a base representation of the current form
|
|
124
131
|
// in case someone has overloaded the viewState with additional decorators we merge
|
|
@@ -128,7 +135,7 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
|
|
|
128
135
|
// the partialIdsArray arr is almost deprecated legacy code where we allowed to send a separate list of partial
|
|
129
136
|
// ids for reduced load and server processing, this will be removed soon, we can handle the same via execute
|
|
130
137
|
// anyway TODO remove the partial ids array
|
|
131
|
-
let formData: XhrFormData = new XhrFormData(this.sourceForm, viewState, executesArr(), this.partialIdsArray);
|
|
138
|
+
let formData: XhrFormData = new XhrFormData(this.sourceForm, resoveNamingContainerMapper(this.internalContext), viewState, executesArr(), this.partialIdsArray);
|
|
132
139
|
|
|
133
140
|
this.contentType = formData.isMultipartRequest ? "undefined" : this.contentType;
|
|
134
141
|
|
|
@@ -178,8 +185,9 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
|
|
|
178
185
|
// setting, they accept headers automatically
|
|
179
186
|
ignoreErr(() => xhrObject.setRequestHeader(REQ_ACCEPT, STD_ACCEPT));
|
|
180
187
|
|
|
181
|
-
this.sendEvent(BEGIN);
|
|
182
188
|
|
|
189
|
+
|
|
190
|
+
this.sendEvent(BEGIN);
|
|
183
191
|
this.sendRequest(formData);
|
|
184
192
|
|
|
185
193
|
} catch (e) {
|
|
@@ -374,4 +382,5 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
|
|
|
374
382
|
Implementation.sendError(errorData, eventHandler);
|
|
375
383
|
}
|
|
376
384
|
|
|
385
|
+
|
|
377
386
|
}
|
|
@@ -174,11 +174,11 @@ describe('Namespacing tests', function () {
|
|
|
174
174
|
let resultsMap = {};
|
|
175
175
|
for (let val of arsArr) {
|
|
176
176
|
let keyVal = val.split("=");
|
|
177
|
-
resultsMap[keyVal[0]] = keyVal[1];
|
|
177
|
+
resultsMap[unescape(keyVal[0])] = unescape(keyVal[1]);
|
|
178
178
|
}
|
|
179
|
-
|
|
180
|
-
expect(resultsMap["pass1"]).to.eq("pass1");
|
|
181
|
-
expect(resultsMap["pass2"]).to.eq("pass2");
|
|
179
|
+
const NAMING_CONTAINER_PREF = "jd_0:";
|
|
180
|
+
expect(resultsMap[NAMING_CONTAINER_PREF + "pass1"]).to.eq("pass1");
|
|
181
|
+
expect(resultsMap[NAMING_CONTAINER_PREF + "pass2"]).to.eq("pass2");
|
|
182
182
|
expect(!!resultsMap["render"]).to.be.false;
|
|
183
183
|
expect(!!resultsMap["execute"]).to.be.false;
|
|
184
184
|
|
|
@@ -191,10 +191,10 @@ describe('Namespacing tests', function () {
|
|
|
191
191
|
let viewState = Stream.ofAssoc(resultsMap).filter(data => data[0].indexOf(P_VIEWSTATE) != -1).map(item => item[1]).first().value;
|
|
192
192
|
|
|
193
193
|
expect(viewState).to.eq("booga");
|
|
194
|
-
expect(resultsMap[P_PARTIAL_SOURCE]).to.eq(
|
|
195
|
-
expect(resultsMap[P_AJAX]).to.eq("true");
|
|
196
|
-
expect(resultsMap[P_RENDER]).to.eq(
|
|
197
|
-
expect(resultsMap[P_EXECUTE]).to.eq(
|
|
194
|
+
expect(resultsMap[NAMING_CONTAINER_PREF + P_PARTIAL_SOURCE]).to.eq("jd_0:input_2");
|
|
195
|
+
expect(resultsMap[NAMING_CONTAINER_PREF + P_AJAX]).to.eq("true");
|
|
196
|
+
expect(resultsMap[NAMING_CONTAINER_PREF + P_RENDER]).to.eq("jd_0:blarg jd_0:input_2");
|
|
197
|
+
expect(resultsMap[NAMING_CONTAINER_PREF + P_EXECUTE]).to.eq("jd_0:input_1 jd_0:input_2");
|
|
198
198
|
} finally {
|
|
199
199
|
send.restore();
|
|
200
200
|
}
|
|
@@ -225,7 +225,7 @@ describe('Tests of the various aspects of the response protocol functionality',
|
|
|
225
225
|
|
|
226
226
|
});
|
|
227
227
|
|
|
228
|
-
it("must have updated the viewstates properly", function () {
|
|
228
|
+
it("must have updated the viewstates properly", function (done) {
|
|
229
229
|
DQ.byId("cmd_eval").click();
|
|
230
230
|
/*js full submit form, coming from the integration tests*/
|
|
231
231
|
window.document.body.innerHTML = `<form id="j_id__v_0" name="j_id__v_0" method="post" action="/IntegrationJSTest/integrationtestsjasmine/test7-eventtest.jsf"
|
|
@@ -252,10 +252,11 @@ describe('Tests of the various aspects of the response protocol functionality',
|
|
|
252
252
|
</changes>
|
|
253
253
|
</partial-response>`);
|
|
254
254
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
255
|
+
setTimeout(() => {
|
|
256
|
+
expect(DQ$("[name*='jakarta.faces.ViewState']").isPresent()).to.be.true;
|
|
257
|
+
expect(DQ$("[name*='jakarta.faces.ViewState']").val == "RTUyRDI0NzE4QzAxM0E5RDAwMDAwMDVD").to.be.true;
|
|
258
|
+
done();
|
|
259
|
+
}, 100);
|
|
259
260
|
});
|
|
260
261
|
|
|
261
262
|
|
|
@@ -228,7 +228,7 @@ describe('Tests of the various aspects of the response protocol functionality',
|
|
|
228
228
|
|
|
229
229
|
});
|
|
230
230
|
|
|
231
|
-
it("must have updated the viewstates properly", function () {
|
|
231
|
+
it("must have updated the viewstates properly 2.3", function () {
|
|
232
232
|
DQ.byId("cmd_eval").click();
|
|
233
233
|
/*js full submit form, coming from the integration tests*/
|
|
234
234
|
window.document.body.innerHTML = `<form id="j_id__v_0" name="j_id__v_0" method="post" action="/IntegrationJSTest/integrationtestsjasmine/test7-eventtest.jsf"
|
|
@@ -263,7 +263,7 @@ describe('Tests of the various aspects of the response protocol functionality',
|
|
|
263
263
|
});
|
|
264
264
|
|
|
265
265
|
|
|
266
|
-
it("must have updated the viewstates properly with lenient update block", function () {
|
|
266
|
+
it("must have updated the viewstates properly with lenient update block 2.3", function () {
|
|
267
267
|
DQ.byId("cmd_eval").click();
|
|
268
268
|
/*js full submit form, coming from the integration tests*/
|
|
269
269
|
window.document.body.innerHTML = `<form id="j_id__v_0" name="j_id__v_0" method="post" action="/IntegrationJSTest/integrationtestsjasmine/test7-eventtest.jsf"
|