jsf.js_next_gen 4.0.0-RC.1 → 4.0.0-RC.10
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/docs/assets/main.js +1 -1
- package/dist/docs/functions/faces.push.init.html +5 -1
- package/dist/docs/functions/myfaces.ab.html +2 -2
- package/dist/window/faces-development.js +365 -136
- 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 +376 -136
- 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 +11 -11
- package/src/main/typescript/@types/definitions/index.d.ts +17 -2
- package/src/main/typescript/api/_api.ts +4 -2
- package/src/main/typescript/api/jsf.ts +18 -0
- package/src/main/typescript/impl/AjaxImpl.ts +22 -2
- package/src/main/typescript/impl/PushImpl.ts +38 -12
- package/src/main/typescript/impl/core/Const.ts +9 -5
- package/src/main/typescript/impl/util/Assertions.ts +14 -6
- package/src/main/typescript/impl/util/AsyncQueue.ts +1 -1
- package/src/main/typescript/impl/util/ExtDomQuery.ts +4 -1
- package/src/main/typescript/impl/xhrCore/IResponseProcessor.ts +8 -1
- package/src/main/typescript/impl/xhrCore/RequestDataResolver.ts +13 -3
- package/src/main/typescript/impl/xhrCore/ResponseProcessor.ts +91 -29
- package/src/main/typescript/impl/xhrCore/XhrFormData.ts +24 -12
- package/src/main/typescript/myfaces/OamSubmit.ts +15 -10
- package/src/main/typescript/test/frameworkBase/_ext/shared/XmlResponses.ts +40 -1
- package/src/main/typescript/test/xhrCore/OamSubmitTest.spec.ts +177 -0
- package/src/main/typescript/test/xhrCore/RequestTest.spec.ts +237 -8
- package/src/main/typescript/test/xhrCore/ResponseTest.spec.ts +174 -10
- package/src/main/typescript/test/xhrCore/ResponseTest23.spec.ts +8 -6
- package/src/main/typescript/test.xml +6 -0
- package/target/api/_api.js +3 -2
- package/target/api/_api.js.map +1 -1
- package/target/api/jsf.js +11 -0
- package/target/api/jsf.js.map +1 -1
- package/target/impl/AjaxImpl.js +18 -0
- package/target/impl/AjaxImpl.js.map +1 -1
- package/target/impl/PushImpl.js +44 -14
- package/target/impl/PushImpl.js.map +1 -1
- package/target/impl/core/Const.js +10 -8
- package/target/impl/core/Const.js.map +1 -1
- package/target/impl/util/Assertions.js +11 -6
- package/target/impl/util/Assertions.js.map +1 -1
- package/target/impl/util/AsyncQueue.js.map +1 -1
- package/target/impl/util/ExtDomQuery.js +3 -0
- package/target/impl/util/ExtDomQuery.js.map +1 -1
- package/target/impl/xhrCore/RequestDataResolver.js +11 -2
- package/target/impl/xhrCore/RequestDataResolver.js.map +1 -1
- package/target/impl/xhrCore/ResponseProcessor.js +84 -23
- package/target/impl/xhrCore/ResponseProcessor.js.map +1 -1
- package/target/impl/xhrCore/XhrFormData.js +18 -7
- package/target/impl/xhrCore/XhrFormData.js.map +1 -1
- package/target/myfaces/OamSubmit.js +13 -11
- package/target/myfaces/OamSubmit.js.map +1 -1
- package/target/test/frameworkBase/_ext/shared/XmlResponses.js +37 -1
- package/target/test/frameworkBase/_ext/shared/XmlResponses.js.map +1 -1
- package/target/test/xhrCore/OamSubmitTest.spec.js +180 -0
- package/target/test/xhrCore/OamSubmitTest.spec.js.map +1 -0
- package/target/test/xhrCore/RequestTest.spec.js +214 -7
- package/target/test/xhrCore/RequestTest.spec.js.map +1 -1
- package/target/test/xhrCore/ResponseTest.spec.js +139 -8
- package/target/test/xhrCore/ResponseTest.spec.js.map +1 -1
- package/target/test/xhrCore/ResponseTest23.spec.js +5 -5
- package/target/test/xhrCore/ResponseTest23.spec.js.map +1 -1
- package/target/classes/com/example/jsfs_js_ts/DecoratedFacesJS.class +0 -0
- package/target/classes/com/example/jsfs_js_ts/DecoratingResourceHandlerWrapper.class +0 -0
- package/target/classes/com/example/jsfs_js_ts/FacesJSMapFileResourceWrapper.class +0 -0
- package/target/classes/com/example/jsfs_js_ts/FacesJSMappingDecorator.class +0 -0
- package/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +0 -4
- package/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +0 -4
- package/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst +0 -1
- package/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst +0 -1
- package/target/surefire-reports/TEST-com.example.jsfs_js_ts.JsfsJsTsApplicationTests.xml +0 -78
- package/target/surefire-reports/com.example.jsfs_js_ts.JsfsJsTsApplicationTests.txt +0 -7
- package/target/test-classes/.gz +0 -0
- package/target/test-classes/com/example/jsfs_js_ts/JsfsJsTsApplicationTests.class +0 -0
- package/target/test-classes/fileuploadtest.html +0 -24
- package/target/test-classes/jsf-development.js +0 -3559
- package/target/test-classes/jsf-development.js.br +0 -0
- package/target/test-classes/jsf-development.js.gz +0 -0
- package/target/test-classes/jsf-development.js.map +0 -1
- package/target/test-classes/jsf.js +0 -3
- package/target/test-classes/jsf.js.br +0 -0
- package/target/test-classes/jsf.js.gz +0 -0
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {Config,
|
|
17
|
+
import {Config, DomQueryCollector, DQ, DQ$, Lang, LazyStream, Stream, XMLQuery} from "mona-dish";
|
|
18
18
|
import {Implementation} from "../AjaxImpl";
|
|
19
19
|
import {Assertions} from "../util/Assertions";
|
|
20
20
|
import {IResponseProcessor} from "./IResponseProcessor";
|
|
@@ -40,7 +40,6 @@ import {
|
|
|
40
40
|
P_PARTIAL_SOURCE,
|
|
41
41
|
P_VIEWSTATE,
|
|
42
42
|
RESPONSE_XML, SEL_CLIENT_WINDOW_ELEM,
|
|
43
|
-
SEL_SCRIPTS_STYLES,
|
|
44
43
|
SEL_VIEWSTATE_ELEM,
|
|
45
44
|
SOURCE,
|
|
46
45
|
SUCCESS,
|
|
@@ -52,7 +51,7 @@ import {
|
|
|
52
51
|
TAG_HEAD,
|
|
53
52
|
UPDATE_ELEMS,
|
|
54
53
|
UPDATE_FORMS,
|
|
55
|
-
DEFERRED_HEAD_INSERTS
|
|
54
|
+
DEFERRED_HEAD_INSERTS, PARTIAL_ID, P_EXECUTE, P_RENDER, HTML_CLIENT_WINDOW
|
|
56
55
|
} from "../core/Const";
|
|
57
56
|
import trim = Lang.trim;
|
|
58
57
|
import {ExtConfig, ExtDomQuery} from "../util/ExtDomQuery";
|
|
@@ -86,27 +85,31 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
86
85
|
if (!shadowHead.isPresent()) {
|
|
87
86
|
return;
|
|
88
87
|
}
|
|
88
|
+
let head = ExtDomQuery.querySelectorAll(TAG_HEAD);
|
|
89
|
+
// full replace we delete everything
|
|
90
|
+
head.childNodes.delete();
|
|
91
|
+
this.addToHead(shadowHead);
|
|
92
|
+
}
|
|
89
93
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
+
addToHead(shadowHead: XMLQuery | DQ) {
|
|
95
|
+
const mappedHeadData = new ExtDomQuery(shadowHead);
|
|
96
|
+
const postProcessTags = ["STYLE", "LINK", "SCRIPT"];
|
|
97
|
+
const nonExecutables = mappedHeadData.filter(item => postProcessTags.indexOf(item.tagName.orElse("").value) == -1);
|
|
98
|
+
nonExecutables.runHeadInserts(true);
|
|
94
99
|
|
|
95
|
-
// we cannot replace new elements in the head, but we can eval the elements
|
|
96
|
-
// eval means the scripts will get attached (eval script attach method)
|
|
97
|
-
// but this is done by DomQuery not in this code
|
|
98
|
-
this.storeForEval(shadowHead);
|
|
99
100
|
//incoming either the outer head tag or its children
|
|
100
|
-
|
|
101
|
-
//this
|
|
101
|
+
const nodesToAdd = (shadowHead.tagName.value === "HEAD") ? shadowHead.childNodes : shadowHead;
|
|
102
|
+
// this is stored for post processing
|
|
103
|
+
// after the rest of the "pyhsical build up", head before body
|
|
104
|
+
const evalElements = nodesToAdd.stream
|
|
105
|
+
.filter(item => postProcessTags.indexOf(item.tagName.orElse("").value) != -1).collect(new DomQueryCollector());
|
|
106
|
+
this.addToHeadDeferred(evalElements);
|
|
102
107
|
}
|
|
103
108
|
|
|
104
|
-
|
|
109
|
+
addToHeadDeferred(newElements: XMLQuery | DQ) {
|
|
105
110
|
this.internalContext.assign(DEFERRED_HEAD_INSERTS).value.push(newElements);
|
|
106
111
|
}
|
|
107
112
|
|
|
108
|
-
|
|
109
|
-
|
|
110
113
|
/**
|
|
111
114
|
* replaces the body in the expected manner
|
|
112
115
|
* which means the entire body content is refreshed
|
|
@@ -335,14 +338,18 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
335
338
|
Stream.ofAssoc<StateHolder>(this.internalContext.getIf(APPLIED_VST).orElse({}).value)
|
|
336
339
|
.each((item: Array<any>) => {
|
|
337
340
|
let value: StateHolder = item[1];
|
|
338
|
-
let
|
|
339
|
-
let affectedForms
|
|
340
|
-
let affectedForms2 = nameSpace.filter(item => item.tagName.orElse(EMPTY_STR).value.toLowerCase() == TAG_FORM);
|
|
341
|
+
let namingContainerId = this.internalContext.getIf(PARTIAL_ID);
|
|
342
|
+
let affectedForms;
|
|
341
343
|
|
|
342
|
-
|
|
344
|
+
affectedForms = this.getContainerForms(namingContainerId)
|
|
345
|
+
.filter(affectedForm => this.executeOrRenderFilter(affectedForm));
|
|
346
|
+
|
|
347
|
+
this.appendViewStateToForms(affectedForms, value.value);
|
|
343
348
|
});
|
|
344
349
|
}
|
|
345
350
|
|
|
351
|
+
|
|
352
|
+
|
|
346
353
|
/**
|
|
347
354
|
* same as with view states before applies the incoming client windows as last step after the rest of the processing
|
|
348
355
|
* is done.
|
|
@@ -350,12 +357,14 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
350
357
|
fixClientWindow() {
|
|
351
358
|
Stream.ofAssoc<StateHolder>(this.internalContext.getIf(APPLIED_CLIENT_WINDOW).orElse({}).value)
|
|
352
359
|
.each((item: Array<any>) => {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
let affectedForms
|
|
356
|
-
let affectedForms2 = nameSpace.filter(item => item.tagName.orElse(EMPTY_STR).value.toLowerCase() == TAG_FORM);
|
|
360
|
+
const value: StateHolder = item[1];
|
|
361
|
+
const namingContainerId = this.internalContext.getIf(PARTIAL_ID);
|
|
362
|
+
let affectedForms;
|
|
357
363
|
|
|
358
|
-
|
|
364
|
+
affectedForms = this.getContainerForms(namingContainerId)
|
|
365
|
+
.filter(affectedForm => this.executeOrRenderFilter(affectedForm));
|
|
366
|
+
|
|
367
|
+
this.appendClientWindowToForms(affectedForms, value.value);
|
|
359
368
|
});
|
|
360
369
|
}
|
|
361
370
|
|
|
@@ -403,7 +412,11 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
403
412
|
private assignState(forms: DQ, selector: string, state: string) {
|
|
404
413
|
forms.each((form: DQ) => {
|
|
405
414
|
let stateHolders = form.querySelectorAll(selector)
|
|
406
|
-
.orElseLazy(() =>
|
|
415
|
+
.orElseLazy(() => {
|
|
416
|
+
return selector.indexOf("ViewState") != -1 ?
|
|
417
|
+
ResponseProcessor.newViewStateElement(form):
|
|
418
|
+
ResponseProcessor.newClientWindowElement(form);
|
|
419
|
+
});
|
|
407
420
|
|
|
408
421
|
stateHolders.attr("value").value = state;
|
|
409
422
|
});
|
|
@@ -416,9 +429,21 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
416
429
|
* (usually a form node)
|
|
417
430
|
*/
|
|
418
431
|
private static newViewStateElement(parent: DQ): DQ {
|
|
419
|
-
let
|
|
420
|
-
|
|
421
|
-
return
|
|
432
|
+
let newElement = DQ.fromMarkup($nsp(HTML_VIEWSTATE));
|
|
433
|
+
newElement.appendTo(parent);
|
|
434
|
+
return newElement;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Helper to Create a new JSF ViewState Element
|
|
439
|
+
*
|
|
440
|
+
* @param parent, the parent node to attach the viewState element to
|
|
441
|
+
* (usually a form node)
|
|
442
|
+
*/
|
|
443
|
+
private static newClientWindowElement(parent: DQ): DQ {
|
|
444
|
+
let newElement = DQ.fromMarkup($nsp(HTML_CLIENT_WINDOW));
|
|
445
|
+
newElement.appendTo(parent);
|
|
446
|
+
return newElement;
|
|
422
447
|
}
|
|
423
448
|
|
|
424
449
|
/**
|
|
@@ -480,5 +505,42 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
480
505
|
this.externalContext.getIf(ON_ERROR).orElse(this.internalContext.getIf(ON_ERROR).value).orElse(EMPTY_FUNC).value(errorData);
|
|
481
506
|
}
|
|
482
507
|
|
|
508
|
+
/**
|
|
509
|
+
* filters the forms according to being in the execute or render cycle
|
|
510
|
+
* @param affectedForm
|
|
511
|
+
* @private
|
|
512
|
+
*/
|
|
513
|
+
private executeOrRenderFilter(affectedForm) {
|
|
514
|
+
let executes = this.externalContext.getIf($nsp(P_EXECUTE)).orElse("@none").value.split(/\s+/gi);
|
|
515
|
+
let renders = this.externalContext.getIf($nsp(P_RENDER)).orElse("@none").value.split(/\s+/gi);
|
|
516
|
+
let executeAndRenders = executes.concat(...renders);
|
|
517
|
+
return LazyStream.of(...executeAndRenders).filter(nameOrId => {
|
|
518
|
+
if (nameOrId == "@all") {
|
|
519
|
+
return true;
|
|
520
|
+
}
|
|
521
|
+
if (nameOrId == "@none") {
|
|
522
|
+
return true;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
const nameOrIdSelector = `[id='${nameOrId}'], [name='#${nameOrId}']`;
|
|
526
|
+
//either the form directly is in execute or render or one of its children or one of its parents
|
|
527
|
+
return affectedForm.matchesSelector(nameOrIdSelector) ||
|
|
528
|
+
affectedForm.querySelectorAll(nameOrIdSelector).isPresent() ||
|
|
529
|
+
affectedForm.parents(nameOrIdSelector).isPresent();
|
|
530
|
+
}).first().isPresent();
|
|
531
|
+
}
|
|
483
532
|
|
|
533
|
+
/**
|
|
534
|
+
* gets all forms under a single naming container id
|
|
535
|
+
* @param namingContainerId
|
|
536
|
+
* @private
|
|
537
|
+
*/
|
|
538
|
+
private getContainerForms(namingContainerId: Config) {
|
|
539
|
+
if (namingContainerId.isPresent()) {
|
|
540
|
+
//naming container mode, all forms under naming container id must be processed
|
|
541
|
+
return DQ.byId(namingContainerId.value).orElse(DQ$(`form[name='${namingContainerId.value}']`)).byTagName(TAG_FORM, true);
|
|
542
|
+
} else {
|
|
543
|
+
return DQ.byTagName(TAG_FORM);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
484
546
|
}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import {ArrayCollector, Config, DQ, Lang, LazyStream, Stream} from "mona-dish";
|
|
17
17
|
import {EMPTY_STR, IDENT_ALL, IDENT_FORM, P_VIEWSTATE} from "../core/Const";
|
|
18
18
|
import isString = Lang.isString;
|
|
19
|
-
import {ExtConfig} from "../util/ExtDomQuery";
|
|
19
|
+
import {ExtConfig, ExtDomQuery} from "../util/ExtDomQuery";
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
/**
|
|
@@ -54,15 +54,20 @@ export class XhrFormData extends Config {
|
|
|
54
54
|
//a call to getViewState before must pass the encoded line
|
|
55
55
|
//a call from getViewState passes the form element as datasource,
|
|
56
56
|
//so we have two call points
|
|
57
|
+
// atm we basically encode twice, to keep the code leaner
|
|
58
|
+
// this will be later optmized, practically elements
|
|
59
|
+
// which are already covered by an external viewstate do not need
|
|
60
|
+
// the encoding a second time, because they are overwritten by the viewstate again
|
|
57
61
|
if (isString(dataSource)) {
|
|
58
62
|
this.assignEncodedString(<string>this.dataSource);
|
|
59
63
|
} else {
|
|
60
64
|
this.applyFormDataToConfig();
|
|
61
65
|
}
|
|
62
|
-
|
|
66
|
+
//now assign the external viewstate overrides
|
|
67
|
+
if ('undefined' != typeof viewState) {
|
|
63
68
|
this.assignEncodedString(viewState)
|
|
64
69
|
}
|
|
65
|
-
if(executes) {
|
|
70
|
+
if (executes) {
|
|
66
71
|
this.postInit(...executes);
|
|
67
72
|
}
|
|
68
73
|
}
|
|
@@ -73,14 +78,17 @@ export class XhrFormData extends Config {
|
|
|
73
78
|
* in our ajax request
|
|
74
79
|
*/
|
|
75
80
|
postInit(...executes: Array<string>) {
|
|
76
|
-
let
|
|
81
|
+
let fetchFileInputs = (id: string): DQ => {
|
|
82
|
+
const INPUT_FILE = "input[type='file']";
|
|
77
83
|
if (id == IDENT_ALL) {
|
|
78
|
-
return DQ.querySelectorAllDeep(
|
|
84
|
+
return DQ.querySelectorAllDeep(INPUT_FILE);
|
|
79
85
|
} else if (id == IDENT_FORM) {
|
|
80
|
-
return (<DQ>this.dataSource).
|
|
86
|
+
return (<DQ>this.dataSource).matchesSelector(INPUT_FILE) ?
|
|
87
|
+
(<DQ>this.dataSource) :
|
|
88
|
+
(<DQ>this.dataSource).querySelectorAllDeep(INPUT_FILE);
|
|
81
89
|
} else {
|
|
82
90
|
let element = DQ.byId(id, true);
|
|
83
|
-
return this.getFileInputs(element);
|
|
91
|
+
return element.matchesSelector(INPUT_FILE) ? element : this.getFileInputs(element);
|
|
84
92
|
}
|
|
85
93
|
};
|
|
86
94
|
|
|
@@ -90,7 +98,7 @@ export class XhrFormData extends Config {
|
|
|
90
98
|
|
|
91
99
|
|
|
92
100
|
this.isMultipartRequest = LazyStream.of(...executes)
|
|
93
|
-
.map(
|
|
101
|
+
.map(fetchFileInputs)
|
|
94
102
|
.filter(inputExists)
|
|
95
103
|
.first().isPresent();
|
|
96
104
|
}
|
|
@@ -113,8 +121,8 @@ export class XhrFormData extends Config {
|
|
|
113
121
|
assignEncodedString(encoded: string) {
|
|
114
122
|
// this code filters out empty strings as key value pairs
|
|
115
123
|
let keyValueEntries = decodeURIComponent(encoded).split(/&/gi)
|
|
116
|
-
|
|
117
|
-
.replace(/\s+/g,''));
|
|
124
|
+
.filter(item => !!(item || '')
|
|
125
|
+
.replace(/\s+/g, ''));
|
|
118
126
|
this.assignString(keyValueEntries);
|
|
119
127
|
}
|
|
120
128
|
|
|
@@ -133,8 +141,8 @@ export class XhrFormData extends Config {
|
|
|
133
141
|
return keyVal.length < 3 ? [keyVal?.[0] ?? [], keyVal?.[1] ?? []] : keyVal;
|
|
134
142
|
}
|
|
135
143
|
|
|
144
|
+
//TODO fix files...
|
|
136
145
|
Stream.of(...keyValueEntries)
|
|
137
|
-
//split only the first =
|
|
138
146
|
.map(line => splitToKeyVal(line))
|
|
139
147
|
//special case of having keys without values
|
|
140
148
|
.map(keyVal => fixKeyWithoutVal(keyVal))
|
|
@@ -171,7 +179,11 @@ export class XhrFormData extends Config {
|
|
|
171
179
|
}
|
|
172
180
|
let entries = LazyStream.of(...Object.keys(this.value))
|
|
173
181
|
.filter(key => this.value.hasOwnProperty(key))
|
|
174
|
-
.flatMap(key => Stream.of(...this.value[key]).map(val => [key, val])
|
|
182
|
+
.flatMap(key => Stream.of(...this.value[key]).map(val => [key, val])
|
|
183
|
+
//we cannot encode file elements that is handled by multipart requests anyway
|
|
184
|
+
.filter(([, value]) => !(value instanceof ExtDomQuery.global().File))
|
|
185
|
+
.collect(new ArrayCollector()))
|
|
186
|
+
|
|
175
187
|
.map(keyVal => {
|
|
176
188
|
return `${encodeURIComponent(keyVal[0])}=${encodeURIComponent(keyVal[1])}`;
|
|
177
189
|
})
|
|
@@ -62,18 +62,22 @@ export module oam {
|
|
|
62
62
|
DQ.byId(element).delete();
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
-
// noinspection JSUnusedGlobalSymbols
|
|
65
|
+
// noinspection JSUnusedGlobalSymbols,JSUnusedLocalSymbols
|
|
66
66
|
/**
|
|
67
67
|
* does special form submit remapping
|
|
68
68
|
* re-maps the issuing command link into something,
|
|
69
|
-
*
|
|
69
|
+
* the "decode" of the command link on the server can understand
|
|
70
70
|
*
|
|
71
71
|
* @param formName
|
|
72
72
|
* @param linkId
|
|
73
73
|
* @param target
|
|
74
74
|
* @param params
|
|
75
75
|
*/
|
|
76
|
-
export const submitForm = function (formName: string, linkId: string, target: string, params:
|
|
76
|
+
export const submitForm = function (formName: string, linkId: string | null = null, target: string |null = null, params: AssocArr<any> | Tuples<string, any> | null = {} ): boolean {
|
|
77
|
+
|
|
78
|
+
//handle a possible incoming null, not sure if this is used that way anywhere, but we allow it
|
|
79
|
+
params = (!params) ? {} : params;
|
|
80
|
+
|
|
77
81
|
let clearFn = 'clearFormHiddenParams_' + formName.replace(/-/g, '\$:').replace(/:/g, '_');
|
|
78
82
|
window?.[clearFn]?.(formName);
|
|
79
83
|
|
|
@@ -81,14 +85,14 @@ export module oam {
|
|
|
81
85
|
if (window?.myfaces?.core?.config?.autoScroll && (window as any)?.getScrolling) {
|
|
82
86
|
myfaces.oam.setHiddenInput(formName, 'autoScroll', (window as any)?.getScrolling());
|
|
83
87
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
});
|
|
88
|
+
let paramsStream: Stream<[string, any]> = Array.isArray(params) ? Stream.of(...params) : Stream.ofAssoc(params);
|
|
89
|
+
paramsStream.each(([key, data]) => myfaces.oam.setHiddenInput(formName, key, data));
|
|
87
90
|
|
|
88
91
|
//we call the namespaced function, to allow decoration, via a direct call we would
|
|
89
|
-
myfaces.oam.setHiddenInput(formName, `${formName}:_idcl`, linkId);
|
|
92
|
+
myfaces.oam.setHiddenInput(formName, `${formName}:_idcl`, linkId ?? '');
|
|
93
|
+
|
|
90
94
|
|
|
91
|
-
DQ.byId(document.forms[formName]).each(form => {
|
|
95
|
+
DQ.byId(document.forms?.[formName] ?? document.getElementById(formName)).each(form => {
|
|
92
96
|
const ATTR_TARGET = "target";
|
|
93
97
|
const formElement = form.getAsElem(0).value as HTMLFormElement;
|
|
94
98
|
const oldTarget = form.attr(ATTR_TARGET).value;
|
|
@@ -104,8 +108,9 @@ export module oam {
|
|
|
104
108
|
window?.console.error(e);
|
|
105
109
|
} finally {
|
|
106
110
|
form.attr(ATTR_TARGET).value = oldTarget;
|
|
107
|
-
|
|
108
|
-
|
|
111
|
+
// noinspection JSUnusedLocalSymbols
|
|
112
|
+
paramsStream.each(([key, data]) => {
|
|
113
|
+
myfaces.oam.clearHiddenInput(formName, key);
|
|
109
114
|
});
|
|
110
115
|
myfaces.oam.clearHiddenInput(formName, `${formName}:_idcl`);
|
|
111
116
|
}
|
|
@@ -194,7 +194,7 @@ export class XmlResponses {
|
|
|
194
194
|
<partial-response id="j_id__v_0"><changes><update id="jakarta.faces.Resource">
|
|
195
195
|
<![CDATA[
|
|
196
196
|
<script src="../../../xhrCore/fixtures/addedViewHead3.js"></script>
|
|
197
|
-
<
|
|
197
|
+
<link rel="stylesheet" href="../../../xhrCore/fixtures/addedViewHead2.css"></link>
|
|
198
198
|
<script type="text/javascript">
|
|
199
199
|
document.getElementById('resource_area_1').innerHTML = 'booga';
|
|
200
200
|
</script>
|
|
@@ -204,6 +204,45 @@ export class XmlResponses {
|
|
|
204
204
|
</partial-response>
|
|
205
205
|
`
|
|
206
206
|
|
|
207
|
+
static HEAD_REPLACE = `
|
|
208
|
+
<partial-response id="j_id__v_0"><changes><update id="jakarta.faces.ViewHead">
|
|
209
|
+
<![CDATA[
|
|
210
|
+
<head>
|
|
211
|
+
<script type="text/javascript" src="../../../xhrCore/fixtures/addedViewHead3.js"></script>
|
|
212
|
+
<link rel="stylesheet" href="../../../xhrCore/fixtures/addedViewHead2.css"></link>
|
|
213
|
+
<script type="text/javascript">
|
|
214
|
+
setTimeout(() => document.getElementById('resource_area_1').innerHTML = 'booga', 100);
|
|
215
|
+
</script>
|
|
216
|
+
</head>
|
|
217
|
+
]]>
|
|
218
|
+
</update>
|
|
219
|
+
</changes>
|
|
220
|
+
</partial-response>
|
|
221
|
+
`
|
|
222
|
+
|
|
223
|
+
static HEAD_REPLACE2 = `
|
|
224
|
+
<partial-response id="j_id__v_0"><changes><update id="jakarta.faces.ViewHead">
|
|
225
|
+
<![CDATA[
|
|
226
|
+
<head>
|
|
227
|
+
<title>After Update</title>
|
|
228
|
+
<meta charset="UTF-8">
|
|
229
|
+
<meta name="description" content="Free Web tutorials">
|
|
230
|
+
<meta name="keywords" content="HTML, CSS, JavaScript, JSF">
|
|
231
|
+
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
|
232
|
+
<meta name="author" content="Whoever">
|
|
233
|
+
<script type="text/javascript" src="../../../xhrCore/fixtures/addedViewHead3.js"></script>
|
|
234
|
+
<link rel="stylesheet" href="../../../xhrCore/fixtures/addedViewHead2.css"></link>
|
|
235
|
+
<script type="text/javascript">
|
|
236
|
+
setTimeout(() => document.getElementById('resource_area_1').innerHTML = 'booga', 100);
|
|
237
|
+
</script>
|
|
238
|
+
</head>
|
|
239
|
+
]]>
|
|
240
|
+
</update>
|
|
241
|
+
</changes>
|
|
242
|
+
</partial-response>
|
|
243
|
+
`
|
|
244
|
+
|
|
245
|
+
|
|
207
246
|
static NONCE_REPLY = `
|
|
208
247
|
<partial-response><changes><update id='nonce_result'>
|
|
209
248
|
<![CDATA[<script nonce='test12d3' type='text/javascript' src='http://foobaz/nonce_script.js'></script>]]>
|
|
@@ -0,0 +1,177 @@
|
|
|
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
|
+
|
|
17
|
+
import {describe} from "mocha";
|
|
18
|
+
import * as sinon from "sinon";
|
|
19
|
+
import {Implementation} from "../../impl/AjaxImpl";
|
|
20
|
+
import {StandardInits} from "../frameworkBase/_ext/shared/StandardInits";
|
|
21
|
+
import defaultMyFaces = StandardInits.defaultMyFaces;
|
|
22
|
+
import {DQ, DQ$} from "mona-dish";
|
|
23
|
+
import {expect} from "chai";
|
|
24
|
+
|
|
25
|
+
describe('Tests for the MyFaces specifig oam submit', function () {
|
|
26
|
+
|
|
27
|
+
beforeEach(async function () {
|
|
28
|
+
|
|
29
|
+
let waitForResult = defaultMyFaces();
|
|
30
|
+
|
|
31
|
+
return waitForResult.then((close) => {
|
|
32
|
+
|
|
33
|
+
this.xhr = sinon.useFakeXMLHttpRequest();
|
|
34
|
+
this.requests = [];
|
|
35
|
+
this.xhr.onCreate = (xhr) => {
|
|
36
|
+
this.requests.push(xhr);
|
|
37
|
+
};
|
|
38
|
+
(<any>global).XMLHttpRequest = this.xhr;
|
|
39
|
+
window.XMLHttpRequest = this.xhr;
|
|
40
|
+
|
|
41
|
+
this.jsfAjaxResponse = sinon.spy((<any>global).faces.ajax, "response");
|
|
42
|
+
|
|
43
|
+
this.closeIt = () => {
|
|
44
|
+
(<any>global).XMLHttpRequest = window.XMLHttpRequest = this.xhr.restore();
|
|
45
|
+
this.jsfAjaxResponse.restore();
|
|
46
|
+
Implementation.reset();
|
|
47
|
+
close();
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
afterEach(function () {
|
|
53
|
+
this.closeIt();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it(("must handle oam submit correctly, tuples"), (done) => {
|
|
57
|
+
|
|
58
|
+
let options = [["booga1", "value1"], ["booga2", "value2"]];
|
|
59
|
+
|
|
60
|
+
(DQ.byId("blarg")
|
|
61
|
+
.getAsElem(0).value as HTMLFormElement).onsubmit = (evt) => {
|
|
62
|
+
expect(DQ$("#blarg #booga1").inputValue.value).to.eq("value1");
|
|
63
|
+
expect(DQ$("#blarg #booga2").inputValue.value).to.eq("value2");
|
|
64
|
+
done();
|
|
65
|
+
return false;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
myfaces.oam.submitForm("blarg", null, null, options);
|
|
69
|
+
|
|
70
|
+
});
|
|
71
|
+
it(("must handle oam submit correctly, associative array"), (done) => {
|
|
72
|
+
|
|
73
|
+
let options = {"booga1": "value1", "booga2": "value2"};
|
|
74
|
+
|
|
75
|
+
(DQ.byId("blarg")
|
|
76
|
+
.getAsElem(0).value as HTMLFormElement).onsubmit = (evt) => {
|
|
77
|
+
expect(DQ$("#blarg #booga1").inputValue.value).to.eq("value1");
|
|
78
|
+
expect(DQ$("#blarg #booga2").inputValue.value).to.eq("value2");
|
|
79
|
+
done();
|
|
80
|
+
return false;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
myfaces.oam.submitForm("blarg", null, null, options);
|
|
84
|
+
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it(("all hidden inputs must be cleared post submit"), (done) => {
|
|
88
|
+
|
|
89
|
+
let options = {"booga1": "value1", "booga2": "value2"};
|
|
90
|
+
|
|
91
|
+
(DQ.byId("blarg")
|
|
92
|
+
.getAsElem(0).value as HTMLFormElement).onsubmit = (evt) => {
|
|
93
|
+
expect(DQ$("#blarg #booga1").length).to.eq(1);
|
|
94
|
+
expect(DQ$("#blarg #booga2").length).to.eq(1);
|
|
95
|
+
return false;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
myfaces.oam.submitForm("blarg", null, null, options);
|
|
99
|
+
|
|
100
|
+
expect(DQ$("#blarg #booga1").length).to.eq(0);
|
|
101
|
+
expect(DQ$("#blarg #booga2").length).to.eq(0);
|
|
102
|
+
done();
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it(("must handle linkid correctly, associative array"), (done) => {
|
|
106
|
+
|
|
107
|
+
let options = {"booga1": "value1", "booga2": "value2"};
|
|
108
|
+
|
|
109
|
+
(DQ.byId("blarg")
|
|
110
|
+
.getAsElem(0).value as HTMLFormElement).onsubmit = (evt) => {
|
|
111
|
+
expect(DQ.byId(`blarg:_idcl`).inputValue.value).to.eq("bla");
|
|
112
|
+
done();
|
|
113
|
+
return false;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
myfaces.oam.submitForm("blarg", "bla", null, options);
|
|
117
|
+
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it(("must handle target correctly, associative array"), (done) => {
|
|
121
|
+
|
|
122
|
+
let options = {"booga1": "value1", "booga2": "value2"};
|
|
123
|
+
(DQ.byId("blarg")
|
|
124
|
+
.getAsElem(0).value as HTMLFormElement).onsubmit = (evt) => {
|
|
125
|
+
expect(DQ$(`#blarg`).attr("target").value).to.eq("target1");
|
|
126
|
+
done();
|
|
127
|
+
return false;
|
|
128
|
+
};
|
|
129
|
+
myfaces.oam.submitForm("blarg", "bla", "target1", options);
|
|
130
|
+
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it(("must handle limited parameters"), (done) => {
|
|
134
|
+
|
|
135
|
+
(DQ.byId("blarg")
|
|
136
|
+
.getAsElem(0).value as HTMLFormElement).onsubmit = (evt) => {
|
|
137
|
+
expect(DQ.byId(`blarg:_idcl`).inputValue.value).to.eq("bla");
|
|
138
|
+
done();
|
|
139
|
+
return false;
|
|
140
|
+
};
|
|
141
|
+
try {
|
|
142
|
+
myfaces.oam.submitForm("blarg", "bla");
|
|
143
|
+
} catch(e) {
|
|
144
|
+
done(e);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
});
|
|
148
|
+
it(("must handle limited parameters 2"), (done) => {
|
|
149
|
+
|
|
150
|
+
(DQ.byId("blarg")
|
|
151
|
+
.getAsElem(0).value as HTMLFormElement).onsubmit = (evt) => {
|
|
152
|
+
expect(DQ.byId(`blarg:_idcl`).inputValue.value).to.eq("bla");
|
|
153
|
+
done();
|
|
154
|
+
return false;
|
|
155
|
+
};
|
|
156
|
+
try {
|
|
157
|
+
myfaces.oam.submitForm("blarg", "bla", null);
|
|
158
|
+
} catch(e) {
|
|
159
|
+
done(e);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
it(("must handle limited parameters 3"), (done) => {
|
|
163
|
+
|
|
164
|
+
(DQ.byId("blarg")
|
|
165
|
+
.getAsElem(0).value as HTMLFormElement).onsubmit = (evt) => {
|
|
166
|
+
expect(DQ.byId(`blarg:_idcl`).inputValue.value).to.eq("bla");
|
|
167
|
+
done();
|
|
168
|
+
return false;
|
|
169
|
+
};
|
|
170
|
+
try {
|
|
171
|
+
myfaces.oam.submitForm("blarg", "bla", null, null);
|
|
172
|
+
} catch(e) {
|
|
173
|
+
done(e);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
});
|