jsf.js_next_gen 1.0.0-beta-17 → 1.0.0-beta-18
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/jsf-development.js +274 -193
- 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 +1 -1
- package/src/main/typescript/impl/AjaxImpl.ts +84 -48
- package/src/main/typescript/impl/util/AsyncQueue.ts +30 -17
- package/src/main/typescript/impl/util/AsyncRunnable.ts +5 -3
- package/src/main/typescript/impl/util/ExtDomQuery.ts +8 -8
- package/src/main/typescript/impl/xhrCore/EventData.ts +2 -2
- package/src/main/typescript/impl/xhrCore/RequestDataResolver.ts +3 -3
- package/src/main/typescript/impl/xhrCore/ResonseDataResolver.ts +3 -3
- package/src/main/typescript/impl/xhrCore/ResponseProcessor.ts +31 -11
- package/src/main/typescript/impl/xhrCore/XhrFormData.ts +86 -90
- package/src/main/typescript/impl/xhrCore/XhrRequest.ts +34 -28
- package/target/impl/AjaxImpl.js +80 -39
- package/target/impl/AjaxImpl.js.map +1 -1
- package/target/impl/util/AsyncQueue.js +28 -15
- package/target/impl/util/AsyncQueue.js.map +1 -1
- package/target/impl/util/ExtDomQuery.js +7 -7
- package/target/impl/util/ExtDomQuery.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/RequestDataResolver.js +3 -3
- package/target/impl/xhrCore/RequestDataResolver.js.map +1 -1
- package/target/impl/xhrCore/ResonseDataResolver.js +3 -3
- package/target/impl/xhrCore/ResonseDataResolver.js.map +1 -1
- package/target/impl/xhrCore/ResponseProcessor.js +31 -9
- package/target/impl/xhrCore/ResponseProcessor.js.map +1 -1
- package/target/impl/xhrCore/XhrFormData.js +86 -88
- package/target/impl/xhrCore/XhrFormData.js.map +1 -1
- package/target/impl/xhrCore/XhrRequest.js +32 -27
- package/target/impl/xhrCore/XhrRequest.js.map +1 -1
|
@@ -13,11 +13,9 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import {ArrayCollector, Config,
|
|
17
|
-
|
|
18
|
-
import {Stream, DQ} from "mona-dish";
|
|
16
|
+
import {ArrayCollector, Config, DQ, Lang, LazyStream, Stream} from "mona-dish";
|
|
17
|
+
import {EMPTY_STR, IDENT_ALL, IDENT_FORM, P_VIEWSTATE} from "../core/Const";
|
|
19
18
|
import isString = Lang.isString;
|
|
20
|
-
import {EMPTY_STR, P_VIEWSTATE} from "../core/Const";
|
|
21
19
|
|
|
22
20
|
|
|
23
21
|
/**
|
|
@@ -28,43 +26,55 @@ import {EMPTY_STR, P_VIEWSTATE} from "../core/Const";
|
|
|
28
26
|
* due to api constraints on the HTML Form object in IE11
|
|
29
27
|
* and due to the url encoding constraint given by the jsf.js spec
|
|
30
28
|
*
|
|
31
|
-
* TODO not ideal. too many encoding calls
|
|
32
29
|
* probably only one needed and one overlay!
|
|
33
|
-
* the entire
|
|
34
|
-
* that
|
|
30
|
+
* the entire file input storing probably is redundant now
|
|
31
|
+
* that dom query has been fixed //TODO check this
|
|
35
32
|
*/
|
|
36
33
|
export class XhrFormData extends Config {
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Checks if the given datasource is a multipart request source
|
|
36
|
+
* multipart is only needed if one of the executes is a file input
|
|
37
|
+
* since file inputs are stateless, they fall out of the view state
|
|
38
|
+
* and need special handling. With file submits we have to send a formData object
|
|
39
|
+
* instead of an encoded string files cannot be sent that way
|
|
40
|
+
*/
|
|
41
|
+
isMultipartRequest: boolean = false;
|
|
39
42
|
|
|
40
43
|
/**
|
|
41
44
|
* data collector from a given form
|
|
42
45
|
*
|
|
43
46
|
* @param dataSource either a form as DomQuery object or an encoded url string
|
|
44
|
-
* @param
|
|
47
|
+
* @param viewState the form view state or an external viewstate coming in as string
|
|
48
|
+
* @param executes the executes id list for the elements to being processed
|
|
49
|
+
* @param partialIds partial ids to collect, to reduce the data sent down
|
|
45
50
|
*/
|
|
46
|
-
constructor(private dataSource: DQ | string, private
|
|
51
|
+
constructor(private dataSource: DQ | string, viewState?: string, executes?: string[], private partialIds?: string[]) {
|
|
47
52
|
super({});
|
|
48
53
|
//a call to getViewState before must pass the encoded line
|
|
49
|
-
//a call from getViewState passes the form element as datasource
|
|
54
|
+
//a call from getViewState passes the form element as datasource,
|
|
50
55
|
//so we have two call points
|
|
51
56
|
if (isString(dataSource)) {
|
|
52
57
|
this.assignEncodedString(<string>this.dataSource);
|
|
53
58
|
} else {
|
|
54
|
-
this.
|
|
59
|
+
this.applyFormDataToConfig();
|
|
60
|
+
}
|
|
61
|
+
if('undefined' != typeof viewState) {
|
|
62
|
+
this.assignEncodedString(viewState)
|
|
63
|
+
}
|
|
64
|
+
if(executes) {
|
|
65
|
+
this.postInit(...executes);
|
|
55
66
|
}
|
|
56
67
|
}
|
|
57
68
|
|
|
58
69
|
/**
|
|
59
|
-
* generic
|
|
70
|
+
* generic post init code, for now, this peforms some post assign data post processing
|
|
60
71
|
* @param executes
|
|
61
72
|
*/
|
|
62
|
-
|
|
63
|
-
|
|
73
|
+
postInit(...executes: Array<string>) {
|
|
64
74
|
let fetchInput = (id: string): DQ => {
|
|
65
|
-
if (id ==
|
|
75
|
+
if (id == IDENT_ALL) {
|
|
66
76
|
return DQ.querySelectorAllDeep("input[type='file']");
|
|
67
|
-
} else if (id ==
|
|
77
|
+
} else if (id == IDENT_FORM) {
|
|
68
78
|
return (<DQ>this.dataSource).querySelectorAllDeep("input[type='file']");
|
|
69
79
|
} else {
|
|
70
80
|
let element = DQ.byId(id, true);
|
|
@@ -76,48 +86,17 @@ export class XhrFormData extends Config {
|
|
|
76
86
|
return item.isPresent();
|
|
77
87
|
};
|
|
78
88
|
|
|
79
|
-
let applyInput = (item: DQ) => {
|
|
80
|
-
this.fileInputs[this.resolveSubmitIdentifier(<HTMLInputElement>item.getAsElem(0).value)] = true;
|
|
81
|
-
};
|
|
82
89
|
|
|
83
|
-
LazyStream.of(...executes)
|
|
90
|
+
this.isMultipartRequest = LazyStream.of(...executes)
|
|
84
91
|
.map(fetchInput)
|
|
85
92
|
.filter(inputExists)
|
|
86
|
-
.
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
private getFileInputs(rootElment: DQ): DQ {
|
|
90
|
-
const rootFileInputs = rootElment
|
|
91
|
-
.filter(elem => elem.matchesSelector("input[type='file']"))
|
|
92
|
-
const childFileInputs = rootElment
|
|
93
|
-
.querySelectorAll("input[type='file']");
|
|
94
|
-
|
|
95
|
-
let ret = rootFileInputs.concat(childFileInputs);
|
|
96
|
-
return ret;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
private handleFormSource() {
|
|
100
|
-
//encode and append the issuing item if not a partial ids array of ids is passed
|
|
101
|
-
/*
|
|
102
|
-
* Spec. 13.3.1
|
|
103
|
-
* Collect and encode input elements.
|
|
104
|
-
* Additionally the hidden element javax.faces.ViewState
|
|
105
|
-
* Enhancement partial page submit
|
|
106
|
-
*
|
|
107
|
-
*/
|
|
108
|
-
this.encodeSubmittableFields(this, <DQ>this.dataSource, this.partialIdsArray);
|
|
109
|
-
|
|
110
|
-
if (this.getIf(P_VIEWSTATE).isPresent()) {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
this.applyViewState(<DQ>this.dataSource);
|
|
93
|
+
.first().isPresent();
|
|
115
94
|
}
|
|
116
95
|
|
|
117
96
|
/**
|
|
118
|
-
* special case
|
|
97
|
+
* special case view state handling
|
|
119
98
|
*
|
|
120
|
-
* @param form the form holding the
|
|
99
|
+
* @param form the form holding the view state value
|
|
121
100
|
*/
|
|
122
101
|
private applyViewState(form: DQ) {
|
|
123
102
|
let viewState = form.byId(P_VIEWSTATE, true).inputValue;
|
|
@@ -125,19 +104,22 @@ export class XhrFormData extends Config {
|
|
|
125
104
|
}
|
|
126
105
|
|
|
127
106
|
/**
|
|
128
|
-
*
|
|
107
|
+
* assigns an url encoded string to this xhrFormData object
|
|
129
108
|
* as key value entry
|
|
130
109
|
* @param encoded
|
|
131
110
|
*/
|
|
132
111
|
assignEncodedString(encoded: string) {
|
|
133
|
-
//
|
|
134
|
-
//this code filters out empty strings as key value pairs
|
|
112
|
+
// this code filters out empty strings as key value pairs
|
|
135
113
|
let keyValueEntries = decodeURIComponent(encoded).split(/&/gi)
|
|
136
114
|
.filter(item => !!(item || '')
|
|
137
115
|
.replace(/\s+/g,''));
|
|
138
116
|
this.assignString(keyValueEntries);
|
|
139
117
|
}
|
|
140
118
|
|
|
119
|
+
/**
|
|
120
|
+
* assign a set of key value pairs passed as array ['key=val1', 'key2=val2']
|
|
121
|
+
* @param keyValueEntries
|
|
122
|
+
*/
|
|
141
123
|
assignString(keyValueEntries: string[]) {
|
|
142
124
|
let toMerge = new Config({});
|
|
143
125
|
|
|
@@ -161,29 +143,12 @@ export class XhrFormData extends Config {
|
|
|
161
143
|
this.shallowMerge(toMerge);
|
|
162
144
|
}
|
|
163
145
|
|
|
164
|
-
// noinspection JSUnusedGlobalSymbols
|
|
165
146
|
/**
|
|
166
|
-
* @returns a Form data representation
|
|
147
|
+
* @returns a Form data representation, this is needed for file submits
|
|
167
148
|
*/
|
|
168
149
|
toFormData(): FormData {
|
|
169
150
|
let ret: any = new FormData();
|
|
170
|
-
|
|
171
|
-
LazyStream.of(...Object.keys(this.value))
|
|
172
|
-
.filter(key => !(key in this.fileInputs))
|
|
173
|
-
.each(key => {
|
|
174
|
-
Stream.of(...this.value[key]).each(item => ret.append(key, item));
|
|
175
|
-
});
|
|
176
|
-
Stream.of<string>(...Object.keys(this.fileInputs)).each((key: string) => {
|
|
177
|
-
DQ.querySelectorAllDeep(`[name='${key}'], [id="${key}"]`).eachElem((elem: HTMLInputElement) => {
|
|
178
|
-
let identifier = this.resolveSubmitIdentifier(elem);
|
|
179
|
-
if (!elem?.files?.length) {
|
|
180
|
-
ret.append(identifier, elem.value);
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
ret.append(identifier, elem.files[0]);
|
|
185
|
-
})
|
|
186
|
-
});
|
|
151
|
+
this.appendInputs(ret);
|
|
187
152
|
return ret;
|
|
188
153
|
}
|
|
189
154
|
|
|
@@ -213,6 +178,42 @@ export class XhrFormData extends Config {
|
|
|
213
178
|
return entries.join("&")
|
|
214
179
|
}
|
|
215
180
|
|
|
181
|
+
/**
|
|
182
|
+
* helper to fetch all file inputs from as given root element
|
|
183
|
+
* @param rootElement
|
|
184
|
+
* @private
|
|
185
|
+
*/
|
|
186
|
+
private getFileInputs(rootElement: DQ): DQ {
|
|
187
|
+
const rootFileInputs = rootElement
|
|
188
|
+
.filter(elem => elem.matchesSelector("input[type='file']"))
|
|
189
|
+
const childFileInputs = rootElement
|
|
190
|
+
.querySelectorAll("input[type='file']");
|
|
191
|
+
|
|
192
|
+
return rootFileInputs.concat(childFileInputs);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* encode the given fields and apply the view state
|
|
197
|
+
* @private
|
|
198
|
+
*/
|
|
199
|
+
private applyFormDataToConfig() {
|
|
200
|
+
//encode and append the issuing item if not a partial ids array of ids is passed
|
|
201
|
+
/*
|
|
202
|
+
* Spec. 13.3.1
|
|
203
|
+
* Collect and encode input elements.
|
|
204
|
+
* Additionally the hidden element javax.faces.ViewState
|
|
205
|
+
* Enhancement partial page submit
|
|
206
|
+
*
|
|
207
|
+
*/
|
|
208
|
+
this.encodeSubmittableFields(this, <DQ>this.dataSource, this.partialIds);
|
|
209
|
+
|
|
210
|
+
if (this.getIf(P_VIEWSTATE).isPresent()) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
this.applyViewState(<DQ>this.dataSource);
|
|
215
|
+
}
|
|
216
|
+
|
|
216
217
|
/**
|
|
217
218
|
* determines fields to submit
|
|
218
219
|
* @param {Object} targetBuf - the target form buffer receiving the data
|
|
@@ -222,30 +223,25 @@ export class XhrFormData extends Config {
|
|
|
222
223
|
private encodeSubmittableFields(targetBuf: Config,
|
|
223
224
|
parentItem: DQ, partialIds ?: string[]) {
|
|
224
225
|
let toEncode = null;
|
|
225
|
-
if (this.
|
|
226
|
-
//in case of our myfaces reduced ppr we
|
|
227
|
-
//only submit the partials
|
|
226
|
+
if (this.partialIds && this.partialIds.length) {
|
|
227
|
+
// in case of our myfaces reduced ppr we
|
|
228
|
+
// only submit the partials
|
|
228
229
|
this._value = {};
|
|
229
|
-
toEncode = new DQ(...this.
|
|
230
|
+
toEncode = new DQ(...this.partialIds);
|
|
230
231
|
|
|
231
232
|
} else {
|
|
232
|
-
if (parentItem.isAbsent()) throw
|
|
233
|
+
if (parentItem.isAbsent()) throw 'NO_PAR_ITEM';
|
|
233
234
|
toEncode = parentItem;
|
|
234
235
|
}
|
|
235
236
|
|
|
236
237
|
//lets encode the form elements
|
|
237
|
-
|
|
238
238
|
this.shallowMerge(toEncode.deepElements.encodeFormElement());
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
*/
|
|
247
|
-
get isMultipartRequest(): boolean {
|
|
248
|
-
return !!Object.keys(this.fileInputs).length;
|
|
241
|
+
private appendInputs(ret: any) {
|
|
242
|
+
Stream.of(...Object.keys(this.value))
|
|
243
|
+
.each(key => {
|
|
244
|
+
Stream.of(...this.value[key]).each(item => ret.append(key, item));
|
|
245
|
+
});
|
|
249
246
|
}
|
|
250
|
-
|
|
251
247
|
}
|
|
@@ -78,6 +78,7 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
|
|
|
78
78
|
*
|
|
79
79
|
* Optional Parameters
|
|
80
80
|
*
|
|
81
|
+
* @param internalContext internal context with internal info which is passed through, not used by the user
|
|
81
82
|
* @param partialIdsArray an optional restricting partial ids array for encoding
|
|
82
83
|
* @param timeout optional xhr timeout
|
|
83
84
|
* @param ajaxType optional request type, default "POST"
|
|
@@ -120,19 +121,24 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
|
|
|
120
121
|
let viewState = jsf.getViewState(formElement);
|
|
121
122
|
//encoded we need to decode
|
|
122
123
|
//We generated a base representation of the current form
|
|
123
|
-
let formData: XhrFormData = new XhrFormData(this.sourceForm);
|
|
124
124
|
//in case someone has overloaded the viewstate with addtional decorators we merge
|
|
125
125
|
//that in, there is no way around it, the spec allows it and getViewState
|
|
126
126
|
//must be called, so whatever getViewState delivers has higher priority then
|
|
127
127
|
//whatever the formData object delivers
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
//the partialIdsArray arr is almost deprecated legacy code where we allowed to send a separate list of partial
|
|
129
|
+
//ids for reduced load and server processing, this will be removed soon, we can handle the same via execute
|
|
130
|
+
//anyway TODO remove the partial ids array
|
|
131
|
+
let formData: XhrFormData = new XhrFormData(this.sourceForm, viewState, executesArr(), this.partialIdsArray);
|
|
130
132
|
|
|
131
133
|
this.contentType = formData.isMultipartRequest ? "undefined" : this.contentType;
|
|
132
134
|
|
|
133
135
|
//next step the pass through parameters are merged in for post params
|
|
134
136
|
let requestContext = this.requestContext;
|
|
135
137
|
let passThroughParams = requestContext.getIf(CTX_PARAM_PASS_THR);
|
|
138
|
+
|
|
139
|
+
// this is an extension where we allow pass through parameters to be sent down additionally
|
|
140
|
+
// this can be used and is used in the impl to enrich the post request parameters with additional
|
|
141
|
+
// information
|
|
136
142
|
formData.shallowMerge(passThroughParams, true, true);
|
|
137
143
|
|
|
138
144
|
this.responseContext = passThroughParams.deepCopy;
|
|
@@ -162,7 +168,7 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
|
|
|
162
168
|
|
|
163
169
|
//probably not needed anymore, will test this
|
|
164
170
|
//some webkit based mobile browsers do not follow the w3c spec of
|
|
165
|
-
// setting
|
|
171
|
+
// setting, they accept headers automatically
|
|
166
172
|
ignoreErr(() => xhrObject.setRequestHeader(REQ_ACCEPT, STD_ACCEPT));
|
|
167
173
|
|
|
168
174
|
this.sendEvent(BEGIN);
|
|
@@ -223,23 +229,23 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
|
|
|
223
229
|
* @param resolve
|
|
224
230
|
* @param reject
|
|
225
231
|
*/
|
|
226
|
-
|
|
232
|
+
private registerXhrCallbacks(resolve: Consumer<any>, reject: Consumer<any>) {
|
|
227
233
|
let xhrObject = this.xhrObject;
|
|
228
234
|
|
|
229
235
|
xhrObject.onabort = () => {
|
|
230
|
-
this.onAbort(
|
|
236
|
+
this.onAbort(reject);
|
|
231
237
|
};
|
|
232
238
|
xhrObject.ontimeout = () => {
|
|
233
|
-
this.onTimeout(
|
|
239
|
+
this.onTimeout(reject);
|
|
234
240
|
};
|
|
235
241
|
xhrObject.onload = () => {
|
|
236
|
-
this.onSuccess(
|
|
242
|
+
this.onSuccess(resolve)
|
|
237
243
|
};
|
|
238
244
|
xhrObject.onloadend = () => {
|
|
239
|
-
this.onDone(this.xhrObject, resolve
|
|
245
|
+
this.onDone(this.xhrObject, resolve);
|
|
240
246
|
};
|
|
241
247
|
xhrObject.onerror = (errorData: any) => {
|
|
242
|
-
this.onError(errorData,
|
|
248
|
+
this.onError(errorData, reject);
|
|
243
249
|
};
|
|
244
250
|
}
|
|
245
251
|
|
|
@@ -250,29 +256,29 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
|
|
|
250
256
|
* the xhr object depending on its own state
|
|
251
257
|
*/
|
|
252
258
|
|
|
253
|
-
|
|
259
|
+
private onAbort(reject: Consumer<any>) {
|
|
254
260
|
reject();
|
|
255
261
|
}
|
|
256
262
|
|
|
257
|
-
|
|
263
|
+
private onTimeout(reject: Consumer<any>) {
|
|
258
264
|
this.sendEvent(STATE_EVT_TIMEOUT);
|
|
259
265
|
reject();
|
|
260
266
|
}
|
|
261
267
|
|
|
262
|
-
|
|
268
|
+
private onSuccess(resolve: Consumer<any>) {
|
|
263
269
|
|
|
264
270
|
this.sendEvent(COMPLETE);
|
|
265
271
|
|
|
266
272
|
//malforms always result in empty response xml
|
|
267
273
|
if (!this?.xhrObject?.responseXML) {
|
|
268
|
-
this.handleMalFormedXML(resolve
|
|
274
|
+
this.handleMalFormedXML(resolve);
|
|
269
275
|
return;
|
|
270
276
|
}
|
|
271
277
|
|
|
272
278
|
jsf.ajax.response(this.xhrObject, this.responseContext.value ?? {});
|
|
273
279
|
}
|
|
274
280
|
|
|
275
|
-
private handleMalFormedXML(resolve: Function
|
|
281
|
+
private handleMalFormedXML(resolve: Function) {
|
|
276
282
|
this.stopProgress = true;
|
|
277
283
|
let errorData = {
|
|
278
284
|
type: ERROR,
|
|
@@ -293,18 +299,29 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
|
|
|
293
299
|
//non blocking non clearing
|
|
294
300
|
}
|
|
295
301
|
|
|
296
|
-
|
|
302
|
+
private onDone(data: any, resolve: Consumer<any>) {
|
|
297
303
|
if (this.stopProgress) {
|
|
298
304
|
return;
|
|
299
305
|
}
|
|
300
306
|
resolve(data);
|
|
301
307
|
}
|
|
302
308
|
|
|
303
|
-
|
|
309
|
+
private onError(errorData: any, reject: Consumer<any>) {
|
|
304
310
|
this.handleError(errorData);
|
|
305
311
|
reject();
|
|
306
312
|
}
|
|
307
313
|
|
|
314
|
+
private sendRequest(formData: XhrFormData) {
|
|
315
|
+
let isPost = this.ajaxType != REQ_TYPE_GET;
|
|
316
|
+
if (formData.isMultipartRequest) {
|
|
317
|
+
//in case of a multipart request we send in a formData object as body
|
|
318
|
+
this.xhrObject.send((isPost) ? formData.toFormData() : null);
|
|
319
|
+
} else {
|
|
320
|
+
//in case of a normal request we send it normally
|
|
321
|
+
this.xhrObject.send((isPost) ? formData.toString() : null);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
308
325
|
/*
|
|
309
326
|
* other helpers
|
|
310
327
|
*/
|
|
@@ -331,15 +348,4 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
|
|
|
331
348
|
Implementation.sendError(errorData, eventHandler);
|
|
332
349
|
}
|
|
333
350
|
|
|
334
|
-
protected sendRequest(formData: XhrFormData) {
|
|
335
|
-
let isPost = this.ajaxType != REQ_TYPE_GET;
|
|
336
|
-
if (formData.isMultipartRequest) {
|
|
337
|
-
//in case of a multipart request we send in a formData object as body
|
|
338
|
-
this.xhrObject.send((isPost) ? formData.toFormData() : null);
|
|
339
|
-
} else {
|
|
340
|
-
//in case of a normal request we send it normally
|
|
341
|
-
this.xhrObject.send((isPost) ? formData.toString() : null);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
|
|
345
351
|
}
|
package/target/impl/AjaxImpl.js
CHANGED
|
@@ -62,6 +62,54 @@ var BlockFilter;
|
|
|
62
62
|
*/
|
|
63
63
|
var Implementation;
|
|
64
64
|
(function (Implementation) {
|
|
65
|
+
/*
|
|
66
|
+
Small internal explanation, this code is optimized for readability
|
|
67
|
+
and cuts off a ton of old legacy code.
|
|
68
|
+
Aka older browsers are not supported anymore.
|
|
69
|
+
We use a self written helper library to keep the number of exernal
|
|
70
|
+
code dependencies down.
|
|
71
|
+
The library is called mona-dish and started as a small sideproject of mine
|
|
72
|
+
it provides following
|
|
73
|
+
|
|
74
|
+
a) Monad like structures for querying because this keeps the code denser and adds abstractions
|
|
75
|
+
that always was the strong point of jquery and it still is better in this regard than what ecmascript provides
|
|
76
|
+
|
|
77
|
+
b) Streams and lazystreams like java has, a pull like construct, ecmascript does not have anything like Lazystreams.
|
|
78
|
+
Another option would have been rxjs but that would have introduced a code dependency and probably more code. We might
|
|
79
|
+
move to RXJS if the need arises however. But for now I would rather stick with my small self grown library which works
|
|
80
|
+
quite well and where I can patch quickly (I have used it in several industrial projects, so it works well
|
|
81
|
+
and is heavily fortified by unit tests (140 testcases as time of writing this))
|
|
82
|
+
|
|
83
|
+
c) A neutral json like configuration which allows assignments of arbitrary values with reduce code which then can be
|
|
84
|
+
transformed into different data representations
|
|
85
|
+
|
|
86
|
+
examples:
|
|
87
|
+
internalCtx.assign(MYPARAM, CTX_PARAM_SRC_FRM_ID).value = form.id.value;
|
|
88
|
+
passes a value into context.MYPARAM.CTX_PARAM_SRC_FRM_ID
|
|
89
|
+
|
|
90
|
+
basically an abbreviation for
|
|
91
|
+
|
|
92
|
+
internalCtxt[MYPARAM] = internalCtxt?.[MYPARAM] ? internalCtxt[MYPARAM] : {};
|
|
93
|
+
internalCtxt[MYPARAM][CTX_PARAM_SRC_FRM_ID] = internalCtxt?.[MYPARAM][CTX_PARAM_SRC_FRM_ID] ? internalCtxt[MYPARAM][CTX_PARAM_SRC_FRM_ID] : {};
|
|
94
|
+
internalCtxt[MYPARAM][CTX_PARAM_SRC_FRM_ID] = form.id.value;
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
internalCtx.assign(condition, MYPARAM, CTX_PARAM_SRC_FRM_ID).value = form.id.value;
|
|
98
|
+
passes a value into context.MYPARAM.CTX_PARAM_SRC_FRM_ID if condition === true otherwise it is ignored
|
|
99
|
+
|
|
100
|
+
abbreviates:
|
|
101
|
+
if(condition) {
|
|
102
|
+
internalCtxt[MYPARAM] = internalCtxt?.[MYPARAM] ? internalCtxt[MYPARAM] : {};
|
|
103
|
+
internalCtxt[MYPARAM][CTX_PARAM_SRC_FRM_ID] = internalCtxt?.[MYPARAM][CTX_PARAM_SRC_FRM_ID] ? internalCtxt[MYPARAM][CTX_PARAM_SRC_FRM_ID] : {};
|
|
104
|
+
internalCtxt[MYPARAM][CTX_PARAM_SRC_FRM_ID] = form.id.value;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
d) Optional constructs, while under heavy debate we only use them lightly where the api requires it from mona-dish
|
|
109
|
+
|
|
110
|
+
Note the inclusion of this library uses a reduced build which only includes the part of it, which we really use
|
|
111
|
+
|
|
112
|
+
*/
|
|
65
113
|
var trim = mona_dish_1.Lang.trim;
|
|
66
114
|
var getMessage = Lang_1.ExtLang.getMessage;
|
|
67
115
|
var getGlobalConfig = Lang_1.ExtLang.getGlobalConfig;
|
|
@@ -131,8 +179,9 @@ var Implementation;
|
|
|
131
179
|
funcs[_i - 2] = arguments[_i];
|
|
132
180
|
}
|
|
133
181
|
return mona_dish_1.LazyStream.of.apply(mona_dish_1.LazyStream, funcs).map(function (func) { return resolveAndExecute(source, event, func); })
|
|
134
|
-
// we use the return false == stop as an early stop
|
|
182
|
+
// we use the return false == stop as an early stop, onElem stops at the first false
|
|
135
183
|
.onElem(function (opResult) { return opResult; })
|
|
184
|
+
//last ensures we run until the first false is returned
|
|
136
185
|
.last().value;
|
|
137
186
|
}
|
|
138
187
|
Implementation.chain = chain;
|
|
@@ -158,14 +207,25 @@ var Implementation;
|
|
|
158
207
|
var _a, _b, _c;
|
|
159
208
|
var _d = (0, RequestDataResolver_1.resolveDefaults)(event, opts, el), resolvedEvent = _d.resolvedEvent, options = _d.options, elem = _d.elem, elementId = _d.elementId, requestCtx = _d.requestCtx, internalCtx = _d.internalCtx, windowId = _d.windowId, isResetValues = _d.isResetValues;
|
|
160
209
|
Assertions_1.Assertions.assertRequestIntegrity(options, elem);
|
|
210
|
+
/**
|
|
211
|
+
* fetch the parent form
|
|
212
|
+
*
|
|
213
|
+
* note we also add an override possibility here
|
|
214
|
+
* so that people can use dummy forms and work
|
|
215
|
+
* with detached objects
|
|
216
|
+
*/
|
|
217
|
+
var form = (0, RequestDataResolver_1.resolveForm)(requestCtx, elem, resolvedEvent);
|
|
218
|
+
var formId = form.id.value;
|
|
219
|
+
var delay = (0, RequestDataResolver_1.resolveDelay)(options);
|
|
220
|
+
var timeout = (0, RequestDataResolver_1.resolveTimeout)(options);
|
|
161
221
|
requestCtx.assignIf(!!windowId, Const_1.P_WINDOW_ID).value = windowId;
|
|
162
222
|
requestCtx.assign(Const_1.CTX_PARAM_PASS_THR).value = filterPassthroughValues(options.value);
|
|
163
223
|
requestCtx.assignIf(!!resolvedEvent, Const_1.CTX_PARAM_PASS_THR, Const_1.P_EVT).value = resolvedEvent === null || resolvedEvent === void 0 ? void 0 : resolvedEvent.type;
|
|
164
224
|
/**
|
|
165
225
|
* ajax pass through context with the source
|
|
166
|
-
*
|
|
226
|
+
* onresolved Event and onerror Event
|
|
167
227
|
*/
|
|
168
|
-
requestCtx.assign(Const_1.SOURCE).value = elementId
|
|
228
|
+
requestCtx.assign(Const_1.SOURCE).value = elementId;
|
|
169
229
|
/**
|
|
170
230
|
* on resolvedEvent and onError...
|
|
171
231
|
* those values will be traversed later on
|
|
@@ -177,26 +237,14 @@ var Implementation;
|
|
|
177
237
|
* lets drag the myfaces config params also in
|
|
178
238
|
*/
|
|
179
239
|
requestCtx.assign(Const_1.MYFACES).value = (_c = options.value) === null || _c === void 0 ? void 0 : _c.myfaces;
|
|
180
|
-
/**
|
|
181
|
-
* fetch the parent form
|
|
182
|
-
*
|
|
183
|
-
* note we also add an override possibility here
|
|
184
|
-
* so that people can use dummy forms and work
|
|
185
|
-
* with detached objects
|
|
186
|
-
*/
|
|
187
|
-
var form = (0, RequestDataResolver_1.resolveForm)(requestCtx, elem, resolvedEvent);
|
|
188
240
|
/**
|
|
189
241
|
* binding contract the javax.faces.source must be set
|
|
190
242
|
*/
|
|
191
|
-
requestCtx.assign(Const_1.CTX_PARAM_PASS_THR, Const_1.P_PARTIAL_SOURCE).value = elementId
|
|
243
|
+
requestCtx.assign(Const_1.CTX_PARAM_PASS_THR, Const_1.P_PARTIAL_SOURCE).value = elementId;
|
|
192
244
|
/**
|
|
193
245
|
* javax.faces.partial.ajax must be set to true
|
|
194
246
|
*/
|
|
195
247
|
requestCtx.assign(Const_1.CTX_PARAM_PASS_THR, Const_1.P_AJAX).value = true;
|
|
196
|
-
/**
|
|
197
|
-
* binding contract the javax.faces.source must be set
|
|
198
|
-
*/
|
|
199
|
-
requestCtx.assign(Const_1.CTX_PARAM_PASS_THR, Const_1.P_PARTIAL_SOURCE).value = elementId.value;
|
|
200
248
|
/**
|
|
201
249
|
* if resetValues is set to true
|
|
202
250
|
* then we have to set javax.faces.resetValues as well
|
|
@@ -205,22 +253,20 @@ var Implementation;
|
|
|
205
253
|
* the specs jsdoc
|
|
206
254
|
*/
|
|
207
255
|
requestCtx.assignIf(isResetValues, Const_1.CTX_PARAM_PASS_THR, Const_1.P_RESET_VALUES).value = true;
|
|
208
|
-
//additional meta information to speed things up, note internal non jsf
|
|
209
|
-
//pass through options are stored under _mfInternal in the context
|
|
210
|
-
internalCtx.assign(Const_1.CTX_PARAM_SRC_FRM_ID).value =
|
|
211
|
-
|
|
256
|
+
// additional meta information to speed things up, note internal non jsf
|
|
257
|
+
// pass through options are stored under _mfInternal in the context
|
|
258
|
+
internalCtx.assign(Const_1.CTX_PARAM_SRC_FRM_ID).value = formId;
|
|
259
|
+
// mojarra compatibility, mojarra is sending the form id as well
|
|
260
|
+
// this is not documented behavior but can be determined by running
|
|
261
|
+
// mojarra under blackbox conditions.
|
|
262
|
+
// I assume it does the same as our formId_submit=1 so leaving it out
|
|
263
|
+
// won't hurt but for the sake of compatibility we are going to add it
|
|
264
|
+
requestCtx.assign(Const_1.CTX_PARAM_PASS_THR, formId).value = formId;
|
|
265
|
+
internalCtx.assign(Const_1.CTX_PARAM_SRC_CTL_ID).value = elementId;
|
|
212
266
|
internalCtx.assign(Const_1.CTX_PARAM_TR_TYPE).value = Const_1.REQ_TYPE_POST;
|
|
213
|
-
//mojarra compatibility, mojarra is sending the form id as well
|
|
214
|
-
//this is not documented behavior but can be determined by running
|
|
215
|
-
//mojarra under blackbox conditions
|
|
216
|
-
//i assume it does the same as our formId_submit=1 so leaving it out
|
|
217
|
-
//wont hurt but for the sake of compatibility we are going to add it
|
|
218
|
-
requestCtx.assign(Const_1.CTX_PARAM_PASS_THR, form.id.value).value = form.id.value;
|
|
219
267
|
assignClientWindowId(form, requestCtx);
|
|
220
|
-
assignExecute(options, requestCtx, form, elementId
|
|
221
|
-
assignRender(options, requestCtx, form, elementId
|
|
222
|
-
var delay = (0, RequestDataResolver_1.resolveDelay)(options);
|
|
223
|
-
var timeout = (0, RequestDataResolver_1.resolveTimeout)(options);
|
|
268
|
+
assignExecute(options, requestCtx, form, elementId);
|
|
269
|
+
assignRender(options, requestCtx, form, elementId);
|
|
224
270
|
//now we enqueue the request as asynchronous runnable into our request
|
|
225
271
|
//queue and let the queue take over the rest
|
|
226
272
|
Implementation.queueHandler.addRequestToQueue(elem, form, requestCtx, internalCtx, delay, timeout);
|
|
@@ -242,7 +288,6 @@ var Implementation;
|
|
|
242
288
|
* @param errorListener the error listener handler
|
|
243
289
|
*/
|
|
244
290
|
function addOnError(errorListener) {
|
|
245
|
-
/*error handling already done in the assert of the queue*/
|
|
246
291
|
errorQueue.push(errorListener);
|
|
247
292
|
}
|
|
248
293
|
Implementation.addOnError = addOnError;
|
|
@@ -252,7 +297,6 @@ var Implementation;
|
|
|
252
297
|
* @param eventListener the event listener handler
|
|
253
298
|
*/
|
|
254
299
|
function addOnEvent(eventListener) {
|
|
255
|
-
/*error handling already done in the assert of the queue*/
|
|
256
300
|
eventQueue.push(eventListener);
|
|
257
301
|
}
|
|
258
302
|
Implementation.addOnEvent = addOnEvent;
|
|
@@ -405,7 +449,7 @@ var Implementation;
|
|
|
405
449
|
Implementation.getViewState = getViewState;
|
|
406
450
|
/**
|
|
407
451
|
* this at the first sight looks like a weird construct, but we need to do it this way
|
|
408
|
-
* for testing, we cannot proxy addRequestToQueue from the testing frameworks directly
|
|
452
|
+
* for testing, we cannot proxy addRequestToQueue from the testing frameworks directly,
|
|
409
453
|
* but we need to keep it under unit tests.
|
|
410
454
|
*/
|
|
411
455
|
Implementation.queueHandler = {
|
|
@@ -496,11 +540,8 @@ var Implementation;
|
|
|
496
540
|
var iterValues = (userValues) ? trim(userValues).split(/\s+/gi) : [];
|
|
497
541
|
var ret = [];
|
|
498
542
|
var processed = {};
|
|
499
|
-
//
|
|
500
|
-
//
|
|
501
|
-
//this is more readable than the old indexed based solution
|
|
502
|
-
//and not really slower because we had to build up the index in our old solution
|
|
503
|
-
//anyway
|
|
543
|
+
// in this case we do not use lazy stream because it wont bring any code reduction
|
|
544
|
+
// or speedup
|
|
504
545
|
for (var cnt = 0; cnt < iterValues.length; cnt++) {
|
|
505
546
|
//avoid doubles
|
|
506
547
|
if (iterValues[cnt] in processed) {
|
|
@@ -568,7 +609,7 @@ var Implementation;
|
|
|
568
609
|
}
|
|
569
610
|
else {
|
|
570
611
|
//either a function or a string can be passed in case of a string we have to wrap it into another function
|
|
571
|
-
//it
|
|
612
|
+
//it is not a plain executable code but a definition
|
|
572
613
|
var sourceCode = trim(func);
|
|
573
614
|
if (sourceCode.indexOf("function ") == 0) {
|
|
574
615
|
sourceCode = "return ".concat(sourceCode, " (event)");
|