jsf.js_next_gen 1.0.0-beta-16 → 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 +318 -212
- 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 +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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jsf.js_next_gen",
|
|
3
|
-
"version": "1.0.0-beta-
|
|
3
|
+
"version": "1.0.0-beta-18",
|
|
4
4
|
"description": "A next generation typescript reimplementation of jsf.js",
|
|
5
5
|
"main": "dist/window/jsf.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.21.
|
|
51
|
+
"mona-dish": "0.21.17"
|
|
52
52
|
}
|
|
53
53
|
}
|
|
@@ -95,6 +95,54 @@ enum BlockFilter {
|
|
|
95
95
|
* however a dedicated api makes sense for readability reasons
|
|
96
96
|
*/
|
|
97
97
|
export module Implementation {
|
|
98
|
+
/*
|
|
99
|
+
Small internal explanation, this code is optimized for readability
|
|
100
|
+
and cuts off a ton of old legacy code.
|
|
101
|
+
Aka older browsers are not supported anymore.
|
|
102
|
+
We use a self written helper library to keep the number of exernal
|
|
103
|
+
code dependencies down.
|
|
104
|
+
The library is called mona-dish and started as a small sideproject of mine
|
|
105
|
+
it provides following
|
|
106
|
+
|
|
107
|
+
a) Monad like structures for querying because this keeps the code denser and adds abstractions
|
|
108
|
+
that always was the strong point of jquery and it still is better in this regard than what ecmascript provides
|
|
109
|
+
|
|
110
|
+
b) Streams and lazystreams like java has, a pull like construct, ecmascript does not have anything like Lazystreams.
|
|
111
|
+
Another option would have been rxjs but that would have introduced a code dependency and probably more code. We might
|
|
112
|
+
move to RXJS if the need arises however. But for now I would rather stick with my small self grown library which works
|
|
113
|
+
quite well and where I can patch quickly (I have used it in several industrial projects, so it works well
|
|
114
|
+
and is heavily fortified by unit tests (140 testcases as time of writing this))
|
|
115
|
+
|
|
116
|
+
c) A neutral json like configuration which allows assignments of arbitrary values with reduce code which then can be
|
|
117
|
+
transformed into different data representations
|
|
118
|
+
|
|
119
|
+
examples:
|
|
120
|
+
internalCtx.assign(MYPARAM, CTX_PARAM_SRC_FRM_ID).value = form.id.value;
|
|
121
|
+
passes a value into context.MYPARAM.CTX_PARAM_SRC_FRM_ID
|
|
122
|
+
|
|
123
|
+
basically an abbreviation for
|
|
124
|
+
|
|
125
|
+
internalCtxt[MYPARAM] = internalCtxt?.[MYPARAM] ? internalCtxt[MYPARAM] : {};
|
|
126
|
+
internalCtxt[MYPARAM][CTX_PARAM_SRC_FRM_ID] = internalCtxt?.[MYPARAM][CTX_PARAM_SRC_FRM_ID] ? internalCtxt[MYPARAM][CTX_PARAM_SRC_FRM_ID] : {};
|
|
127
|
+
internalCtxt[MYPARAM][CTX_PARAM_SRC_FRM_ID] = form.id.value;
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
internalCtx.assign(condition, MYPARAM, CTX_PARAM_SRC_FRM_ID).value = form.id.value;
|
|
131
|
+
passes a value into context.MYPARAM.CTX_PARAM_SRC_FRM_ID if condition === true otherwise it is ignored
|
|
132
|
+
|
|
133
|
+
abbreviates:
|
|
134
|
+
if(condition) {
|
|
135
|
+
internalCtxt[MYPARAM] = internalCtxt?.[MYPARAM] ? internalCtxt[MYPARAM] : {};
|
|
136
|
+
internalCtxt[MYPARAM][CTX_PARAM_SRC_FRM_ID] = internalCtxt?.[MYPARAM][CTX_PARAM_SRC_FRM_ID] ? internalCtxt[MYPARAM][CTX_PARAM_SRC_FRM_ID] : {};
|
|
137
|
+
internalCtxt[MYPARAM][CTX_PARAM_SRC_FRM_ID] = form.id.value;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
d) Optional constructs, while under heavy debate we only use them lightly where the api requires it from mona-dish
|
|
142
|
+
|
|
143
|
+
Note the inclusion of this library uses a reduced build which only includes the part of it, which we really use
|
|
144
|
+
|
|
145
|
+
*/
|
|
98
146
|
|
|
99
147
|
import trim = Lang.trim;
|
|
100
148
|
import getMessage = ExtLang.getMessage;
|
|
@@ -170,8 +218,9 @@ export module Implementation {
|
|
|
170
218
|
|
|
171
219
|
return LazyStream.of(...funcs)
|
|
172
220
|
.map(func => resolveAndExecute(source, event, func))
|
|
173
|
-
// we use the return false == stop as an early stop
|
|
221
|
+
// we use the return false == stop as an early stop, onElem stops at the first false
|
|
174
222
|
.onElem((opResult: boolean) => opResult)
|
|
223
|
+
//last ensures we run until the first false is returned
|
|
175
224
|
.last().value;
|
|
176
225
|
}
|
|
177
226
|
|
|
@@ -208,17 +257,27 @@ export module Implementation {
|
|
|
208
257
|
|
|
209
258
|
Assertions.assertRequestIntegrity(options, elem);
|
|
210
259
|
|
|
211
|
-
|
|
260
|
+
/**
|
|
261
|
+
* fetch the parent form
|
|
262
|
+
*
|
|
263
|
+
* note we also add an override possibility here
|
|
264
|
+
* so that people can use dummy forms and work
|
|
265
|
+
* with detached objects
|
|
266
|
+
*/
|
|
267
|
+
const form: DQ = resolveForm(requestCtx, elem, resolvedEvent);
|
|
268
|
+
const formId = form.id.value;
|
|
269
|
+
const delay: number = resolveDelay(options);
|
|
270
|
+
const timeout: number = resolveTimeout(options);
|
|
212
271
|
|
|
272
|
+
requestCtx.assignIf(!!windowId, P_WINDOW_ID).value = windowId;
|
|
213
273
|
requestCtx.assign(CTX_PARAM_PASS_THR).value = filterPassthroughValues(options.value);
|
|
214
|
-
|
|
215
274
|
requestCtx.assignIf(!!resolvedEvent, CTX_PARAM_PASS_THR, P_EVT).value = resolvedEvent?.type;
|
|
216
275
|
|
|
217
276
|
/**
|
|
218
277
|
* ajax pass through context with the source
|
|
219
|
-
*
|
|
278
|
+
* onresolved Event and onerror Event
|
|
220
279
|
*/
|
|
221
|
-
requestCtx.assign(SOURCE).value = elementId
|
|
280
|
+
requestCtx.assign(SOURCE).value = elementId;
|
|
222
281
|
|
|
223
282
|
/**
|
|
224
283
|
* on resolvedEvent and onError...
|
|
@@ -232,30 +291,17 @@ export module Implementation {
|
|
|
232
291
|
* lets drag the myfaces config params also in
|
|
233
292
|
*/
|
|
234
293
|
requestCtx.assign(MYFACES).value = options.value?.myfaces;
|
|
235
|
-
/**
|
|
236
|
-
* fetch the parent form
|
|
237
|
-
*
|
|
238
|
-
* note we also add an override possibility here
|
|
239
|
-
* so that people can use dummy forms and work
|
|
240
|
-
* with detached objects
|
|
241
|
-
*/
|
|
242
|
-
let form: DQ = resolveForm(requestCtx, elem, resolvedEvent);
|
|
243
294
|
|
|
244
295
|
/**
|
|
245
296
|
* binding contract the javax.faces.source must be set
|
|
246
297
|
*/
|
|
247
|
-
requestCtx.assign(CTX_PARAM_PASS_THR, P_PARTIAL_SOURCE).value = elementId
|
|
298
|
+
requestCtx.assign(CTX_PARAM_PASS_THR, P_PARTIAL_SOURCE).value = elementId;
|
|
248
299
|
|
|
249
300
|
/**
|
|
250
301
|
* javax.faces.partial.ajax must be set to true
|
|
251
302
|
*/
|
|
252
303
|
requestCtx.assign(CTX_PARAM_PASS_THR, P_AJAX).value = true;
|
|
253
304
|
|
|
254
|
-
/**
|
|
255
|
-
* binding contract the javax.faces.source must be set
|
|
256
|
-
*/
|
|
257
|
-
requestCtx.assign(CTX_PARAM_PASS_THR, P_PARTIAL_SOURCE).value = elementId.value;
|
|
258
|
-
|
|
259
305
|
/**
|
|
260
306
|
* if resetValues is set to true
|
|
261
307
|
* then we have to set javax.faces.resetValues as well
|
|
@@ -265,27 +311,22 @@ export module Implementation {
|
|
|
265
311
|
*/
|
|
266
312
|
requestCtx.assignIf(isResetValues, CTX_PARAM_PASS_THR, P_RESET_VALUES).value = true;
|
|
267
313
|
|
|
268
|
-
//additional meta information to speed things up, note internal non jsf
|
|
269
|
-
//pass through options are stored under _mfInternal in the context
|
|
270
|
-
internalCtx.assign(CTX_PARAM_SRC_FRM_ID).value =
|
|
271
|
-
|
|
314
|
+
// additional meta information to speed things up, note internal non jsf
|
|
315
|
+
// pass through options are stored under _mfInternal in the context
|
|
316
|
+
internalCtx.assign(CTX_PARAM_SRC_FRM_ID).value = formId;
|
|
317
|
+
|
|
318
|
+
// mojarra compatibility, mojarra is sending the form id as well
|
|
319
|
+
// this is not documented behavior but can be determined by running
|
|
320
|
+
// mojarra under blackbox conditions.
|
|
321
|
+
// I assume it does the same as our formId_submit=1 so leaving it out
|
|
322
|
+
// won't hurt but for the sake of compatibility we are going to add it
|
|
323
|
+
requestCtx.assign(CTX_PARAM_PASS_THR, formId).value = formId;
|
|
324
|
+
internalCtx.assign(CTX_PARAM_SRC_CTL_ID).value = elementId;
|
|
272
325
|
internalCtx.assign(CTX_PARAM_TR_TYPE).value = REQ_TYPE_POST;
|
|
273
326
|
|
|
274
|
-
//mojarra compatibility, mojarra is sending the form id as well
|
|
275
|
-
//this is not documented behavior but can be determined by running
|
|
276
|
-
//mojarra under blackbox conditions
|
|
277
|
-
//i assume it does the same as our formId_submit=1 so leaving it out
|
|
278
|
-
//wont hurt but for the sake of compatibility we are going to add it
|
|
279
|
-
|
|
280
|
-
requestCtx.assign(CTX_PARAM_PASS_THR, form.id.value).value = form.id.value;
|
|
281
|
-
|
|
282
327
|
assignClientWindowId(form, requestCtx);
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
assignRender(options, requestCtx, form, elementId.value);
|
|
286
|
-
|
|
287
|
-
let delay: number = resolveDelay(options);
|
|
288
|
-
let timeout: number = resolveTimeout(options);
|
|
328
|
+
assignExecute(options, requestCtx, form, elementId);
|
|
329
|
+
assignRender(options, requestCtx, form, elementId);
|
|
289
330
|
|
|
290
331
|
//now we enqueue the request as asynchronous runnable into our request
|
|
291
332
|
//queue and let the queue take over the rest
|
|
@@ -308,7 +349,6 @@ export module Implementation {
|
|
|
308
349
|
* @param errorListener the error listener handler
|
|
309
350
|
*/
|
|
310
351
|
export function addOnError(errorListener: IListener<ErrorData>) {
|
|
311
|
-
/*error handling already done in the assert of the queue*/
|
|
312
352
|
errorQueue.push(errorListener);
|
|
313
353
|
}
|
|
314
354
|
|
|
@@ -318,7 +358,6 @@ export module Implementation {
|
|
|
318
358
|
* @param eventListener the event listener handler
|
|
319
359
|
*/
|
|
320
360
|
export function addOnEvent(eventListener: IListener<EventData>) {
|
|
321
|
-
/*error handling already done in the assert of the queue*/
|
|
322
361
|
eventQueue.push(eventListener);
|
|
323
362
|
}
|
|
324
363
|
|
|
@@ -480,7 +519,7 @@ export module Implementation {
|
|
|
480
519
|
|
|
481
520
|
/**
|
|
482
521
|
* this at the first sight looks like a weird construct, but we need to do it this way
|
|
483
|
-
* for testing, we cannot proxy addRequestToQueue from the testing frameworks directly
|
|
522
|
+
* for testing, we cannot proxy addRequestToQueue from the testing frameworks directly,
|
|
484
523
|
* but we need to keep it under unit tests.
|
|
485
524
|
*/
|
|
486
525
|
export let queueHandler = {
|
|
@@ -572,15 +611,12 @@ export module Implementation {
|
|
|
572
611
|
function remapDefaultConstants(targetConfig: Config, targetKey: string, userValues: string, issuingForm: DQ, issuingElementId: string): Config {
|
|
573
612
|
//a cleaner implementation of the transform list method
|
|
574
613
|
|
|
575
|
-
let iterValues = (userValues) ? trim(userValues).split(/\s+/gi) : [];
|
|
614
|
+
let iterValues: string[] = (userValues) ? trim(userValues).split(/\s+/gi) : [];
|
|
576
615
|
let ret = [];
|
|
577
|
-
let processed = {};
|
|
616
|
+
let processed: {[key: string]: boolean} = {};
|
|
578
617
|
|
|
579
|
-
//
|
|
580
|
-
//
|
|
581
|
-
//this is more readable than the old indexed based solution
|
|
582
|
-
//and not really slower because we had to build up the index in our old solution
|
|
583
|
-
//anyway
|
|
618
|
+
// in this case we do not use lazy stream because it wont bring any code reduction
|
|
619
|
+
// or speedup
|
|
584
620
|
for (let cnt = 0; cnt < iterValues.length; cnt++) {
|
|
585
621
|
//avoid doubles
|
|
586
622
|
if (iterValues[cnt] in processed) {
|
|
@@ -649,7 +685,7 @@ export module Implementation {
|
|
|
649
685
|
return (<Function>func).call(source, event) !== false;
|
|
650
686
|
} else {
|
|
651
687
|
//either a function or a string can be passed in case of a string we have to wrap it into another function
|
|
652
|
-
//it
|
|
688
|
+
//it is not a plain executable code but a definition
|
|
653
689
|
let sourceCode = trim(<string>func);
|
|
654
690
|
if (sourceCode.indexOf("function ") == 0) {
|
|
655
691
|
sourceCode = `return ${sourceCode} (event)`;
|
|
@@ -6,7 +6,7 @@ import {AsyncRunnable} from "./AsyncRunnable";
|
|
|
6
6
|
*
|
|
7
7
|
* Every callback must be of async runnable
|
|
8
8
|
* which is sort of an extended promise which has
|
|
9
|
-
* added a
|
|
9
|
+
* added a dedicated cancel and start point
|
|
10
10
|
*
|
|
11
11
|
* This interface can be used as wrapper contract
|
|
12
12
|
* for normal promises if needed.
|
|
@@ -21,12 +21,15 @@ export class AsynchronousQueue<T extends AsyncRunnable<any>> {
|
|
|
21
21
|
constructor() {
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* simple is empty accessor, returns true if queue is empty atm
|
|
26
|
+
*/
|
|
24
27
|
get isEmpty(): boolean {
|
|
25
28
|
return !this.runnableQueue.length;
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
/**
|
|
29
|
-
*
|
|
32
|
+
* enqueues an element and starts the
|
|
30
33
|
* asynchronous work loop if not already running
|
|
31
34
|
*
|
|
32
35
|
* @param element the element to be queued and processed
|
|
@@ -46,15 +49,39 @@ export class AsynchronousQueue<T extends AsyncRunnable<any>> {
|
|
|
46
49
|
}
|
|
47
50
|
}
|
|
48
51
|
|
|
49
|
-
|
|
52
|
+
/**
|
|
53
|
+
* fetches the next element from the queue (first in first out order)
|
|
54
|
+
*/
|
|
55
|
+
dequeue(): T | undefined{
|
|
50
56
|
return this.runnableQueue.shift();
|
|
51
57
|
}
|
|
52
58
|
|
|
59
|
+
/**
|
|
60
|
+
* clears up all elements from the queue
|
|
61
|
+
*/
|
|
53
62
|
cleanup() {
|
|
54
63
|
this.currentlyRunning = null;
|
|
55
64
|
this.runnableQueue.length = 0;
|
|
56
65
|
}
|
|
57
66
|
|
|
67
|
+
/**
|
|
68
|
+
* cancels the currently running element and then cleans up the queue
|
|
69
|
+
* aka cancel the queue entirely
|
|
70
|
+
*/
|
|
71
|
+
cancel() {
|
|
72
|
+
try {
|
|
73
|
+
if (this.currentlyRunning) {
|
|
74
|
+
this.currentlyRunning.cancel();
|
|
75
|
+
}
|
|
76
|
+
} finally {
|
|
77
|
+
this.cleanup();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private callForNextElementToProcess() {
|
|
82
|
+
this.runEntry();
|
|
83
|
+
}
|
|
84
|
+
|
|
58
85
|
private appendElement(element: T) {
|
|
59
86
|
//only if the first element is added we start with a trigger
|
|
60
87
|
//otherwise a process already is running and not finished yet at that
|
|
@@ -88,18 +115,4 @@ export class AsynchronousQueue<T extends AsyncRunnable<any>> {
|
|
|
88
115
|
() => this.callForNextElementToProcess()
|
|
89
116
|
).start();
|
|
90
117
|
}
|
|
91
|
-
|
|
92
|
-
cancel() {
|
|
93
|
-
try {
|
|
94
|
-
if (this.currentlyRunning) {
|
|
95
|
-
this.currentlyRunning.cancel();
|
|
96
|
-
}
|
|
97
|
-
} finally {
|
|
98
|
-
this.cleanup();
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
private callForNextElementToProcess() {
|
|
103
|
-
this.runEntry();
|
|
104
|
-
}
|
|
105
118
|
}
|
|
@@ -19,7 +19,9 @@
|
|
|
19
19
|
* Ever object in the asynchronous queue needs to implement this interface
|
|
20
20
|
*
|
|
21
21
|
* the usage should be similar as a Promise from the outside.
|
|
22
|
-
* but with a dedicated start point
|
|
22
|
+
* but with a dedicated start point. The problem why we cannot use
|
|
23
|
+
* promises here, is mostly related to the needed cancel functionality
|
|
24
|
+
* and that the queue expects a runnable as entry.
|
|
23
25
|
*
|
|
24
26
|
* from the implementation side it is mostly registering callbacks
|
|
25
27
|
* and calling them at the appropriate time.
|
|
@@ -36,8 +38,8 @@ export interface AsyncRunnable<T> {
|
|
|
36
38
|
cancel();
|
|
37
39
|
|
|
38
40
|
/**
|
|
39
|
-
* callback for then
|
|
40
|
-
* triggered when the
|
|
41
|
+
* callback for then functionality
|
|
42
|
+
* triggered when the async run is complete
|
|
41
43
|
*
|
|
42
44
|
* the async runnable must register the passed function
|
|
43
45
|
* and then triggers all the registered thens
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {Config, IValueHolder, Optional, DomQuery, DQ} from "mona-dish";
|
|
2
|
-
import {
|
|
2
|
+
import {P_WINDOW_ID} from "../core/Const";
|
|
3
3
|
|
|
4
4
|
declare let window: any;
|
|
5
5
|
|
|
@@ -13,9 +13,9 @@ declare let window: any;
|
|
|
13
13
|
*/
|
|
14
14
|
const IS_JSF_SOURCE = (source?: string): boolean => {
|
|
15
15
|
return source && !!(source?.search(/\/javax\.faces\.resource.*\/jsf\.js.*/) != -1 ||
|
|
16
|
-
source?.search(/\/jsf
|
|
17
|
-
source?.search(/\/jsf
|
|
18
|
-
source?.search(/\/jsf[
|
|
16
|
+
source?.search(/\/jsf-development\.js.*/) != -1 ||
|
|
17
|
+
source?.search(/\/jsf-uncompressed\.js.*/) != -1 ||
|
|
18
|
+
source?.search(/\/jsf[^.]*\.js.*ln=javax.faces.*/gi) != -1);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/**
|
|
@@ -27,7 +27,7 @@ const IS_JSF_SOURCE = (source?: string): boolean => {
|
|
|
27
27
|
* @constructor
|
|
28
28
|
*/
|
|
29
29
|
const IS_INTERNAL_SOURCE = (source: string): boolean => {
|
|
30
|
-
return source.search(/\/jsf[
|
|
30
|
+
return source.search(/\/jsf[^.]*\.js.*ln=myfaces.testscripts.*/gi) != -1;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
|
|
@@ -131,7 +131,7 @@ export class ExtDomquery extends DQ {
|
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
globalEval(code: string, nonce ?: string): DQ {
|
|
134
|
-
return super.globalEval(code, nonce ?? this.nonce);
|
|
134
|
+
return new ExtDomquery(super.globalEval(code, nonce ?? this.nonce));
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
/**
|
|
@@ -150,12 +150,12 @@ export class ExtDomquery extends DQ {
|
|
|
150
150
|
* byId producer
|
|
151
151
|
*
|
|
152
152
|
* @param selector id
|
|
153
|
+
* @param deep whether the search should go into embedded shadow dom elements
|
|
153
154
|
* @return a DomQuery containing the found elements
|
|
154
155
|
*/
|
|
155
156
|
static byId(selector: string | DomQuery | Element, deep = false): DomQuery {
|
|
156
157
|
const ret = DomQuery.byId(selector, deep);
|
|
157
|
-
|
|
158
|
-
return ret;
|
|
158
|
+
return new ExtDomquery(ret);
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
|
|
@@ -17,8 +17,8 @@ export class EventData {
|
|
|
17
17
|
eventData.status = name;
|
|
18
18
|
|
|
19
19
|
let sourceId: string = context.getIf(SOURCE)
|
|
20
|
-
.
|
|
21
|
-
.
|
|
20
|
+
.orElseLazy(() => context.getIf(P_PARTIAL_SOURCE).value)
|
|
21
|
+
.orElseLazy(() => context.getIf(CTX_PARAM_PASS_THR, P_PARTIAL_SOURCE).value).value;
|
|
22
22
|
if (sourceId) {
|
|
23
23
|
eventData.source = DQ.byId(sourceId, true).first().value.value;
|
|
24
24
|
}
|
|
@@ -46,7 +46,7 @@ import {ExtDomquery} from "../util/ExtDomQuery";
|
|
|
46
46
|
*/
|
|
47
47
|
export function resolveHandlerFunc(requestContext: Config, responseContext: Config, funcName: string) {
|
|
48
48
|
return responseContext.getIf(funcName)
|
|
49
|
-
.
|
|
49
|
+
.orElseLazy(() =>requestContext.getIf(funcName).value)
|
|
50
50
|
.orElse(EMPTY_FUNC).value;
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -72,7 +72,7 @@ export function resolveFinalUrl(sourceForm: DomQuery, formData: XhrFormData, aja
|
|
|
72
72
|
* @param event
|
|
73
73
|
*/
|
|
74
74
|
export function resolveForm(requestCtx: Config, elem: DQ, event: Event): DQ {
|
|
75
|
-
const configId = requestCtx.value?.myfaces?.form ?? MF_NONE;
|
|
75
|
+
const configId = requestCtx.value?.myfaces?.form ?? MF_NONE;
|
|
76
76
|
return DQ
|
|
77
77
|
.byId(configId, true)
|
|
78
78
|
.orElseLazy(() => ExtLang.getForm(elem.getAsElem(0).value, event));
|
|
@@ -142,7 +142,7 @@ export function resolveDefaults(event: Event, opts: any = {}, el: Element | stri
|
|
|
142
142
|
const resolvedEvent = event,
|
|
143
143
|
options = new Config(opts).deepCopy,
|
|
144
144
|
elem = DQ.byId(el || <Element>resolvedEvent.target, true),
|
|
145
|
-
elementId = elem.id, requestCtx = new Config({}),
|
|
145
|
+
elementId = elem.id.value, requestCtx = new Config({}),
|
|
146
146
|
internalCtx = new Config({}), windowId = resolveWindowId(options),
|
|
147
147
|
isResetValues = true === options.value?.resetValues;
|
|
148
148
|
|
|
@@ -102,9 +102,9 @@ export function resolveSourceForm(internalContext: Config, elem: DQ): DQ {
|
|
|
102
102
|
let sourceFormId = internalContext.getIf(CTX_PARAM_SRC_FRM_ID);
|
|
103
103
|
let sourceForm = new DQ(sourceFormId.isPresent() ? document.forms[sourceFormId.value] : null);
|
|
104
104
|
|
|
105
|
-
sourceForm = sourceForm.
|
|
106
|
-
.
|
|
107
|
-
.
|
|
105
|
+
sourceForm = sourceForm.orElseLazy(() => elem.parents(TAG_FORM))
|
|
106
|
+
.orElseLazy(() => elem.querySelectorAll(TAG_FORM))
|
|
107
|
+
.orElseLazy(() => DQ.querySelectorAll(TAG_FORM));
|
|
108
108
|
|
|
109
109
|
return sourceForm;
|
|
110
110
|
}
|
|
@@ -71,9 +71,13 @@ import {ExtDomquery} from "../util/ExtDomQuery";
|
|
|
71
71
|
export class ResponseProcessor implements IResponseProcessor {
|
|
72
72
|
|
|
73
73
|
constructor(private request: Config, private externalContext: Config, private internalContext: Config) {
|
|
74
|
-
|
|
75
74
|
}
|
|
76
75
|
|
|
76
|
+
/**
|
|
77
|
+
* head replacement
|
|
78
|
+
* @param shadowDocument incoming shadow head data (aka cdata as xml reference or dom element)
|
|
79
|
+
* the data incoming must represent the html representation of the head itself one way or the other
|
|
80
|
+
*/
|
|
77
81
|
replaceHead(shadowDocument: XMLQuery | DQ) {
|
|
78
82
|
let shadowHead = shadowDocument.querySelectorAll(TAG_HEAD);
|
|
79
83
|
if (!shadowHead.isPresent()) {
|
|
@@ -85,6 +89,9 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
85
89
|
//delete all to avoid script and style overlays
|
|
86
90
|
oldHead.querySelectorAll(SEL_SCRIPTS_STYLES).delete();
|
|
87
91
|
|
|
92
|
+
// we cannot replace new elements in the head, but we can eval the elements
|
|
93
|
+
// eval means the scripts will get attached (eval script attach method)
|
|
94
|
+
// but this is done by DomQuery not in this code
|
|
88
95
|
this.storeForEval(shadowHead);
|
|
89
96
|
}
|
|
90
97
|
|
|
@@ -108,6 +115,8 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
108
115
|
let resultingBody = <DQ>DQ.querySelectorAll(TAG_BODY).html(shadowInnerHTML);
|
|
109
116
|
let updateForms = resultingBody.querySelectorAll(TAG_FORM);
|
|
110
117
|
|
|
118
|
+
// main difference, we cannot replace the body itself, but only its content
|
|
119
|
+
// we need a separate step for post processing the incoming attributes, like classes, styles etc...
|
|
111
120
|
resultingBody.copyAttrs(shadowBody);
|
|
112
121
|
|
|
113
122
|
this.storeForPostProcessing(updateForms, resultingBody);
|
|
@@ -157,10 +166,6 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
157
166
|
Implementation.sendError(errorData);
|
|
158
167
|
}
|
|
159
168
|
|
|
160
|
-
private triggerOnError(errorData: ErrorData) {
|
|
161
|
-
this.externalContext.getIf(ON_ERROR).orElse(this.internalContext.getIf(ON_ERROR).value).orElse(EMPTY_FUNC).value(errorData);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
169
|
/**
|
|
165
170
|
* process the redirect operation
|
|
166
171
|
*
|
|
@@ -182,12 +187,16 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
182
187
|
*/
|
|
183
188
|
update(node: XMLQuery, cdataBlock: string) {
|
|
184
189
|
let result = ExtDomquery.byId(node.id.value, true).outerHTML(cdataBlock, false, false);
|
|
185
|
-
let sourceForm = result?.parents(TAG_FORM).
|
|
190
|
+
let sourceForm = result?.parents(TAG_FORM).orElseLazy(() => result.byTagName(TAG_FORM, true));
|
|
186
191
|
if (sourceForm) {
|
|
187
192
|
this.storeForPostProcessing(sourceForm, result);
|
|
188
193
|
}
|
|
189
194
|
}
|
|
190
195
|
|
|
196
|
+
/**
|
|
197
|
+
* Delete handler, simply deleetes the node referenced by the xml data
|
|
198
|
+
* @param node
|
|
199
|
+
*/
|
|
191
200
|
delete(node: XMLQuery) {
|
|
192
201
|
DQ.byId(node.id.value, true).delete();
|
|
193
202
|
}
|
|
@@ -214,7 +223,7 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
214
223
|
}
|
|
215
224
|
|
|
216
225
|
/**
|
|
217
|
-
*
|
|
226
|
+
* Insert handling, either before or after
|
|
218
227
|
*
|
|
219
228
|
* @param node
|
|
220
229
|
*/
|
|
@@ -239,7 +248,7 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
239
248
|
}
|
|
240
249
|
|
|
241
250
|
/**
|
|
242
|
-
*
|
|
251
|
+
* Handler for the case <insert << before id="...
|
|
243
252
|
*
|
|
244
253
|
* @param node the node hosting the insert data
|
|
245
254
|
*/
|
|
@@ -267,7 +276,7 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
267
276
|
}
|
|
268
277
|
|
|
269
278
|
/**
|
|
270
|
-
*
|
|
279
|
+
* Process the viewState update, update the affected
|
|
271
280
|
* forms with their respective new viewstate values
|
|
272
281
|
*
|
|
273
282
|
*/
|
|
@@ -298,7 +307,10 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
298
307
|
}
|
|
299
308
|
|
|
300
309
|
/**
|
|
301
|
-
*
|
|
310
|
+
* Postprocessing view state fixing
|
|
311
|
+
* this appends basically the incoming view states to the forms.
|
|
312
|
+
* It is called from outside after all forms have been processed basically
|
|
313
|
+
* as last lifecycle step, before going into the next request.
|
|
302
314
|
*/
|
|
303
315
|
fixViewStates() {
|
|
304
316
|
Stream.ofAssoc<StateHolder>(this.internalContext.getIf(APPLIED_VST).orElse({}).value)
|
|
@@ -312,6 +324,10 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
312
324
|
});
|
|
313
325
|
}
|
|
314
326
|
|
|
327
|
+
/**
|
|
328
|
+
* same as with view states before applies the incoming client windows as last step after the rest of the processing
|
|
329
|
+
* is done.
|
|
330
|
+
*/
|
|
315
331
|
fixClientWindow() {
|
|
316
332
|
Stream.ofAssoc<StateHolder>(this.internalContext.getIf(APPLIED_CLIENT_WINDOW).orElse({}).value)
|
|
317
333
|
.each((item: Array<any>) => {
|
|
@@ -331,7 +347,7 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
331
347
|
let eventData = EventData.createFromRequest(this.request.value, this.externalContext, SUCCESS);
|
|
332
348
|
|
|
333
349
|
//because some frameworks might decorate them over the context in the response
|
|
334
|
-
let eventHandler = this.externalContext.getIf(ON_EVENT).
|
|
350
|
+
let eventHandler = this.externalContext.getIf(ON_EVENT).orElseLazy(() => this.internalContext.getIf(ON_EVENT).value).orElse(EMPTY_FUNC).value;
|
|
335
351
|
Implementation.sendEvent(eventData, eventHandler);
|
|
336
352
|
}
|
|
337
353
|
|
|
@@ -441,4 +457,8 @@ export class ResponseProcessor implements IResponseProcessor {
|
|
|
441
457
|
node?.id?.value?.indexOf([P_CLIENT_WINDOW, separatorChar].join(EMPTY_STR)) != -1);
|
|
442
458
|
}
|
|
443
459
|
|
|
460
|
+
private triggerOnError(errorData: ErrorData) {
|
|
461
|
+
this.externalContext.getIf(ON_ERROR).orElse(this.internalContext.getIf(ON_ERROR).value).orElse(EMPTY_FUNC).value(errorData);
|
|
462
|
+
}
|
|
463
|
+
|
|
444
464
|
}
|