jsf.js_next_gen 4.0.1-alpha.0 → 4.0.1-beta.2

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.
Files changed (115) hide show
  1. package/README.md +0 -12
  2. package/dist/docs/assets/search.js +1 -1
  3. package/dist/docs/functions/faces.ajax.addOnError.html +4 -4
  4. package/dist/docs/functions/faces.ajax.request.html +7 -7
  5. package/dist/docs/functions/faces.ajax.response.html +0 -1
  6. package/dist/docs/functions/faces.util.chain.html +3 -3
  7. package/dist/docs/functions/myfaces.ab.html +1 -1
  8. package/dist/docs/functions/{myfaces.onDomReady.html → myfaces.onOnDomReady.html} +5 -5
  9. package/dist/docs/index.html +0 -14
  10. package/dist/docs/modules/myfaces.html +2 -2
  11. package/dist/docs/variables/myfaces.oam.html +1 -1
  12. package/dist/window/faces-development.js +1323 -1300
  13. package/dist/window/faces-development.js.br +0 -0
  14. package/dist/window/faces-development.js.gz +0 -0
  15. package/dist/window/faces-development.js.map +1 -1
  16. package/dist/window/faces.js +1 -1
  17. package/dist/window/faces.js.br +0 -0
  18. package/dist/window/faces.js.gz +0 -0
  19. package/dist/window/faces.js.map +1 -1
  20. package/dist/window/jsf-development.js +1323 -1300
  21. package/dist/window/jsf-development.js.br +0 -0
  22. package/dist/window/jsf-development.js.gz +0 -0
  23. package/dist/window/jsf-development.js.map +1 -1
  24. package/dist/window/jsf.js +1 -1
  25. package/dist/window/jsf.js.br +0 -0
  26. package/dist/window/jsf.js.gz +0 -0
  27. package/dist/window/jsf.js.map +1 -1
  28. package/package.json +3 -3
  29. package/pom.xml +1 -1
  30. package/src/main/typescript/@types/definitions/index.d.ts +5 -5
  31. package/src/main/typescript/api/_api.ts +12 -13
  32. package/src/main/typescript/impl/AjaxImpl.ts +68 -65
  33. package/src/main/typescript/impl/core/Const.ts +2 -5
  34. package/src/main/typescript/impl/util/AsyncQueue.ts +133 -0
  35. package/src/main/typescript/impl/util/AsyncRunnable.ts +6 -81
  36. package/src/main/typescript/impl/util/ExtDomQuery.ts +9 -7
  37. package/src/main/typescript/impl/util/FileUtils.ts +22 -26
  38. package/src/main/typescript/impl/util/HiddenInputBuilder.ts +3 -7
  39. package/src/main/typescript/impl/util/Lang.ts +4 -61
  40. package/src/main/typescript/impl/xhrCore/EventData.ts +3 -3
  41. package/src/main/typescript/impl/xhrCore/ResponseProcessor.ts +10 -12
  42. package/src/main/typescript/impl/xhrCore/XhrFormData.ts +19 -32
  43. package/src/main/typescript/impl/xhrCore/XhrRequest.ts +72 -51
  44. package/src/main/typescript/myfaces/OamSubmit.ts +6 -6
  45. package/src/main/typescript/test/frameworkBase/_ext/monadish/DomQueryTest.spec.ts +40 -179
  46. package/src/main/typescript/test/frameworkBase/_ext/monadish/MonadTest.spec.ts +4 -4
  47. package/src/main/typescript/test/frameworkBase/_ext/monadish/StreamTest.spec.ts +231 -0
  48. package/src/main/typescript/test/frameworkBase/_ext/shared/StandardInits.ts +4 -5
  49. package/src/main/typescript/test/queue/AsynchronousProbe.ts +5 -5
  50. package/src/main/typescript/test/queue/AsynchronousQueueTest.spec.ts +3 -4
  51. package/src/main/typescript/test/xhrCore/ClientWindow.spec.ts +78 -0
  52. package/src/main/typescript/test/xhrCore/EventTests.spec.ts +22 -28
  53. package/src/main/typescript/test/xhrCore/NamespacesRequestTest.spec.ts +4 -4
  54. package/src/main/typescript/test/xhrCore/RequestParamsTest.spec.ts +2 -2
  55. package/src/main/typescript/test/xhrCore/RequestTest.spec.ts +6 -80
  56. package/src/main/typescript/test/xhrCore/RequestTest_23.spec.ts +1 -6
  57. package/src/main/typescript/test/xhrCore/ResponseTest.spec.ts +22 -23
  58. package/src/main/typescript/test/xhrCore/TobagoFileUploadTest.spec.ts +5 -5
  59. package/target/api/_api.js +11 -12
  60. package/target/api/_api.js.map +1 -1
  61. package/target/impl/AjaxImpl.js +59 -55
  62. package/target/impl/AjaxImpl.js.map +1 -1
  63. package/target/impl/core/Const.js +5 -7
  64. package/target/impl/core/Const.js.map +1 -1
  65. package/target/impl/util/AsyncRunnable.js +0 -60
  66. package/target/impl/util/AsyncRunnable.js.map +1 -1
  67. package/target/impl/util/ExtDomQuery.js +8 -8
  68. package/target/impl/util/ExtDomQuery.js.map +1 -1
  69. package/target/impl/util/FileUtils.js +20 -21
  70. package/target/impl/util/FileUtils.js.map +1 -1
  71. package/target/impl/util/HiddenInputBuilder.js +3 -7
  72. package/target/impl/util/HiddenInputBuilder.js.map +1 -1
  73. package/target/impl/util/Lang.js +1 -52
  74. package/target/impl/util/Lang.js.map +1 -1
  75. package/target/impl/xhrCore/EventData.js +2 -2
  76. package/target/impl/xhrCore/EventData.js.map +1 -1
  77. package/target/impl/xhrCore/ResponseProcessor.js +7 -9
  78. package/target/impl/xhrCore/ResponseProcessor.js.map +1 -1
  79. package/target/impl/xhrCore/XhrFormData.js +15 -29
  80. package/target/impl/xhrCore/XhrFormData.js.map +1 -1
  81. package/target/impl/xhrCore/XhrRequest.js +64 -43
  82. package/target/impl/xhrCore/XhrRequest.js.map +1 -1
  83. package/target/myfaces/OamSubmit.js +3 -5
  84. package/target/myfaces/OamSubmit.js.map +1 -1
  85. package/target/test/frameworkBase/_ext/monadish/DomQueryTest.spec.js +37 -138
  86. package/target/test/frameworkBase/_ext/monadish/DomQueryTest.spec.js.map +1 -1
  87. package/target/test/frameworkBase/_ext/monadish/MonadTest.spec.js +4 -4
  88. package/target/test/frameworkBase/_ext/monadish/MonadTest.spec.js.map +1 -1
  89. package/target/test/frameworkBase/_ext/shared/StandardInits.js +4 -5
  90. package/target/test/frameworkBase/_ext/shared/StandardInits.js.map +1 -1
  91. package/target/test/queue/AsynchronousQueueTest.spec.js +3 -3
  92. package/target/test/queue/AsynchronousQueueTest.spec.js.map +1 -1
  93. package/target/test/xhrCore/ClientWindow.spec.js +90 -0
  94. package/target/test/xhrCore/ClientWindow.spec.js.map +1 -0
  95. package/target/test/xhrCore/EventTests.spec.js +19 -26
  96. package/target/test/xhrCore/EventTests.spec.js.map +1 -1
  97. package/target/test/xhrCore/NamespacesRequestTest.spec.js +3 -3
  98. package/target/test/xhrCore/NamespacesRequestTest.spec.js.map +1 -1
  99. package/target/test/xhrCore/RequestParamsTest.spec.js +1 -1
  100. package/target/test/xhrCore/RequestParamsTest.spec.js.map +1 -1
  101. package/target/test/xhrCore/RequestTest.spec.js +4 -73
  102. package/target/test/xhrCore/RequestTest.spec.js.map +1 -1
  103. package/target/test/xhrCore/RequestTest_23.spec.js +0 -6
  104. package/target/test/xhrCore/RequestTest_23.spec.js.map +1 -1
  105. package/target/test/xhrCore/ResponseTest.spec.js +15 -22
  106. package/target/test/xhrCore/ResponseTest.spec.js.map +1 -1
  107. package/target/test/xhrCore/TobagoFileUploadTest.spec.js +5 -5
  108. package/target/test/xhrCore/TobagoFileUploadTest.spec.js.map +1 -1
  109. package/plans for 4.0.1.txt +0 -8
  110. package/src/main/typescript/impl/util/XhrQueueController.ts +0 -112
  111. package/src/main/typescript/test/frameworkBase/_ext/monadish/fixtures/blank.css +0 -0
  112. package/src/main/typescript/test/frameworkBase/_ext/monadish/markups/tobago-with-header.ts +0 -921
  113. package/src/main/typescript/test/frameworkBase/_ext/monadish/markups/tobago-without-header.ts +0 -108
  114. package/src/main/typescript/test/frameworkBase/_ext/shared/fixtures/jakarta.faces.resource/faces.js.jsf +0 -0
  115. package/src/main/typescript/test/myfaces/OnLoadSpec.ts +0 -52
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsf.js_next_gen",
3
- "version": "4.0.1-alpha.0",
3
+ "version": "4.0.1-beta.2",
4
4
  "description": "A next generation typescript reimplementation of jsf.js",
5
5
  "main": "dist/window/faces.js",
6
6
  "scripts": {
@@ -23,7 +23,7 @@
23
23
  "@istanbuljs/nyc-config-typescript": "^1.0.2",
24
24
  "@types/chai": "^4.3.4",
25
25
  "@types/mocha": "^10.0.1",
26
- "@types/node": "^18.14.6",
26
+ "@types/node": "^18.14.2",
27
27
  "@types/sinon": "^10.0.13",
28
28
  "babel-plugin-syntax-dynamic-import": "^6.18.0",
29
29
  "chai": "^4.3.7",
@@ -49,6 +49,6 @@
49
49
  "webpack-dev-server": "^4.11.1"
50
50
  },
51
51
  "dependencies": {
52
- "mona-dish": "0.25.28"
52
+ "mona-dish": "0.26.0"
53
53
  }
54
54
  }
package/pom.xml CHANGED
@@ -10,7 +10,7 @@
10
10
  </parent>
11
11
  <groupId>com.example</groupId>
12
12
  <artifactId>jsfs_js_ts</artifactId>
13
- <version>0.0.1-SNAPSHOT</version>
13
+ <version>4.0</version>
14
14
  <name>jsfs_js_ts</name>
15
15
  <description>Demo project for Spring Boot</description>
16
16
 
@@ -50,10 +50,10 @@ declare global {
50
50
  * <li> errorData.status : the error status message</li>
51
51
  * <li> errorData.serverErrorName : the server error name in case of a server error</li>
52
52
  * <li> errorData.serverErrorMessage : the server error message in case of a server error</li>
53
- * <li> errorData.source : the issuing source element which triggered the requestInternal </li>
54
- * <li> eventData.responseCode: the response code (aka http requestInternal response code, 401 etc...) </li>
55
- * <li> eventData.responseText: the requestInternal response text </li>
56
- * <li> eventData.responseXML: the requestInternal response xml </li>
53
+ * <li> errorData.source : the issuing source element which triggered the request </li>
54
+ * <li> eventData.responseCode: the response code (aka http request response code, 401 etc...) </li>
55
+ * <li> eventData.responseText: the response text </li>
56
+ * <li> eventData.responseXML: the response xml </li>
57
57
  * </ul>
58
58
  */
59
59
  interface IErrorData {
@@ -78,7 +78,7 @@ declare global {
78
78
  }
79
79
 
80
80
  interface Ajax {
81
- request(element: Element, event?: Event, options?: Context): void;
81
+ request(element: Element, event?: Event, options?: Options): void;
82
82
  response(request: XMLHttpRequest, context?: Context): void;
83
83
  }
84
84
 
@@ -117,19 +117,19 @@ export module faces {
117
117
  /**
118
118
  * this function has to send the ajax requests
119
119
  *
120
- * following requestInternal conditions must be met:
120
+ * following request conditions must be met:
121
121
  * <ul>
122
- * <li> the requestInternal must be sent asynchronously! </li>
123
- * <li> the requestInternal must be a POST!!! requestInternal </li>
124
- * <li> the requestInternal url must be the form action attribute </li>
125
- * <li> all requests must be queued with a client side requestInternal queue to ensure the requestInternal ordering!</li>
122
+ * <li> the request must be sent asynchronously! </li>
123
+ * <li> the request must be a POST!!! request </li>
124
+ * <li> the request url must be the form action attribute </li>
125
+ * <li> all requests must be queued with a client side request queue to ensure the request ordering!</li>
126
126
  * </ul>
127
127
  *
128
128
  * @param {String|Node} element: any dom element no matter being it html or jsf, from which the event is emitted
129
129
  * @param {EVENT} event: any javascript event supported by that object
130
130
  * @param {Map} options : map of options being pushed into the ajax cycle
131
131
  */
132
- export function request(element: Element, event?: Event, options?: Context): void {
132
+ export function request(element: Element, event?: Event, options?: Options): void {
133
133
  Implementation.request(element, event, options)
134
134
  }
135
135
 
@@ -138,7 +138,6 @@ export module faces {
138
138
  * @param request the request object having triggered this response
139
139
  * @param context the request context
140
140
  *
141
- * TODO add info on what can be in the context
142
141
  */
143
142
  export function response(request: XMLHttpRequest, context?: Context): void {
144
143
  Implementation.response(request, context);
@@ -153,10 +152,10 @@ export module faces {
153
152
  * <li> errorData.status : the error status message</li>
154
153
  * <li> errorData.serverErrorName : the server error name in case of a server error</li>
155
154
  * <li> errorData.serverErrorMessage : the server error message in case of a server error</li>
156
- * <li> errorData.source : the issuing source element which triggered the requestInternal </li>
157
- * <li> eventData.responseCode: the response code (aka http requestInternal response code, 401 etc...) </li>
158
- * <li> eventData.responseText: the requestInternal response text </li>
159
- * <li> eventData.responseXML: the requestInternal response xml </li>
155
+ * <li> errorData.source : the issuing source element which triggered the request </li>
156
+ * <li> eventData.responseCode: the response code (aka http request response code, 401 etc...) </li>
157
+ * <li> eventData.responseText: the request response text </li>
158
+ * <li> eventData.responseXML: the request response xml </li>
160
159
  * </ul>
161
160
  *
162
161
  * @param errorFunc error handler must be of the format <i>function errorListener(&lt;errorData&gt;)</i>
@@ -189,7 +188,7 @@ export module faces {
189
188
  * @param funcs ... arbitrary array of functions or strings
190
189
  * @returns true if the chain has succeeded false otherwise
191
190
  */
192
- export function chain(source, event, ...funcs: Array<Function | string>): boolean {
191
+ export function chain(source: HTMLElement | string, event: Event | null, ...funcs: Array<Function | string>): boolean {
193
192
  return Implementation.chain(source, event, ...(funcs as EvalFuncs));
194
193
  }
195
194
  }
@@ -278,7 +277,7 @@ export module myfaces {
278
277
  *
279
278
  * @param executionFunc the function to be executed upon ready
280
279
  */
281
- export function onDomReady(executionFunc: () => void) {
280
+ export function onOnDomReady(executionFunc: () => void) {
282
281
  if(document.readyState !== "complete") {
283
282
  onReadyChain.push(executionFunc);
284
283
  if(!readyStateListener) {
@@ -17,7 +17,8 @@
17
17
  import {IListener} from "./util/IListener";
18
18
  import {Response} from "./xhrCore/Response";
19
19
  import {XhrRequest} from "./xhrCore/XhrRequest";
20
- import {Config, DQ, Lang, Optional} from "mona-dish";
20
+ import {AsynchronousQueue} from "./util/AsyncQueue";
21
+ import {AssocArrayCollector, Config, DomQuery, DQ, DQ$, Lang, LazyStream, Optional, Stream} from "mona-dish";
21
22
  import {Assertions} from "./util/Assertions";
22
23
  import {ExtConfig, ExtDomQuery} from "./util/ExtDomQuery";
23
24
  import {ErrorData} from "./xhrCore/ErrorData";
@@ -40,7 +41,7 @@ import {
40
41
  P_CLIENT_WINDOW,
41
42
  P_EVT,
42
43
  P_EXECUTE,
43
- P_AJAX_SOURCE,
44
+ P_PARTIAL_SOURCE,
44
45
  P_RENDER,
45
46
  P_RESET_VALUES,
46
47
  P_WINDOW_ID,
@@ -51,8 +52,9 @@ import {
51
52
  VIEW_ID,
52
53
  $faces,
53
54
  EMPTY_STR,
55
+ CTX_PARAM_MF_INTERNAL,
54
56
  NAMED_VIEWROOT,
55
- NAMING_CONTAINER_ID, CTX_PARAM_PPS, MYFACES_OPTION_PPS
57
+ NAMING_CONTAINER_ID, $nsp
56
58
  } from "./core/Const";
57
59
  import {
58
60
  resolveDefaults,
@@ -61,7 +63,6 @@ import {
61
63
  resolveTimeout, resolveViewId, resolveViewRootId, resoveNamingContainerMapper
62
64
  } from "./xhrCore/RequestDataResolver";
63
65
  import {encodeFormData} from "./util/FileUtils";
64
- import {XhrQueueController} from "./util/XhrQueueController";
65
66
 
66
67
  /*
67
68
  * allowed project stages
@@ -90,8 +91,6 @@ enum BlockFilter {
90
91
  params = "params"
91
92
  }
92
93
 
93
-
94
-
95
94
  /**
96
95
  * Core Implementation
97
96
  * to distinct between api and impl
@@ -111,7 +110,17 @@ export module Implementation {
111
110
  it provides following
112
111
 
113
112
  a) Monad like structures for querying because this keeps the code denser and adds abstractions
114
- that always was the strong point of jQuery, and it still is better in this regard than what ecmascript provides
113
+ that always was the strong point of jquery and it still is better in this regard than what ecmascript provides
114
+
115
+ b) Streams and lazy streams like java has, a pull stream construct, ecmascript does not have anything like it.
116
+ (it has array filters and maps, but ES2015 does not support flatMap)
117
+ Another option would have been rxjs but that would have introduced a code dependency and probably more code. We might
118
+ move to RXJS if the need arises, however. But for now I would rather stick with my small self grown library which works
119
+ quite well and where I can patch quickly (I have used it in several industrial projects, so it works well
120
+ and is heavily fortified by unit tests (140 testcases as time of writing this))
121
+ The long term plan is to eliminate the Stream usage as soon as we can move up to ES2019 (adding the missing
122
+ functions as shims, is a no go, because we are a library, and absolutey do not Shim anything which can leak
123
+ into the global namespace!)
115
124
 
116
125
  c) A neutral json like configuration which allows assignments of arbitrary values with reduce code which then can be
117
126
  transformed into different data representations
@@ -148,14 +157,12 @@ export module Implementation {
148
157
  import getMessage = ExtLang.getMessage;
149
158
  import getGlobalConfig = ExtLang.getGlobalConfig;
150
159
  import assert = Assertions.assert;
151
- import ofAssoc = ExtLang.ofAssoc;
152
- import collectAssoc = ExtLang.collectAssoc;
153
160
 
154
161
  let projectStage: string = null;
155
162
  let separator: string = null;
156
163
  let eventQueue = [];
157
164
  let errorQueue = [];
158
- export let requestQueue: XhrQueueController<XhrRequest> = null;
165
+ export let requestQueue: AsynchronousQueue<XhrRequest> = null;
159
166
  /*error reporting threshold*/
160
167
  let threshold = "ERROR";
161
168
 
@@ -185,7 +192,7 @@ export module Implementation {
185
192
  /**
186
193
  * @return the project stage also emitted by the server:
187
194
  * it cannot be cached and must be delivered over the server
188
- * The value for it comes from the requestInternal parameter of the faces.js script called "stage".
195
+ * The value for it comes from the request parameter of the faces.js script called "stage".
189
196
  */
190
197
  export function getProjectStage(): string | null {
191
198
  return resolveGlobalConfig()?.projectStage ??
@@ -211,21 +218,17 @@ export module Implementation {
211
218
  * @param event
212
219
  * @param funcs
213
220
  */
214
- export function chain(source: any, event: Event, ...funcs: EvalFuncs): boolean {
215
- // we can use our lazy stream each functionality to run our chain here.
221
+ export function chain(source: HTMLElement | string, event: Event | null, ...funcs: EvalFuncs): boolean {
222
+ // we can use our lazy stream each functionality to run our chain here..
216
223
  // by passing a boolean as return value into the onElem call
217
224
  // we can stop early at the first false, just like the spec requests
218
225
 
219
- let ret;
220
- funcs.every(func => {
221
- let returnVal = resolveAndExecute(source, event, func);
222
- if(returnVal !== false) {
223
- ret = returnVal;
224
- }
225
- return returnVal !== false;
226
- });
227
- return ret;
228
-
226
+ return LazyStream.of(...funcs)
227
+ .map(func => resolveAndExecute(source, event, func))
228
+ // we use the return false == stop as an early stop, onElem stops at the first false
229
+ .onElem((opResult: boolean) => opResult)
230
+ //last ensures we run until the first false is returned
231
+ .last().value;
229
232
  }
230
233
 
231
234
  /**
@@ -275,7 +278,7 @@ export module Implementation {
275
278
 
276
279
  requestCtx.assignIf(!!windowId, P_WINDOW_ID).value = windowId;
277
280
 
278
- // old non - spec behavior will be removed after it is clear whether the removal breaks any code
281
+ // old non spec behavior will be removed after it is clear whether the removal breaks any code
279
282
  requestCtx.assign(CTX_PARAM_REQ_PASS_THR).value = extractLegacyParams(options.value);
280
283
 
281
284
  // spec conform behavior, all passthrough params must be under "passthrough
@@ -307,14 +310,14 @@ export module Implementation {
307
310
  requestCtx.assign(ON_ERROR).value = options.value?.onerror;
308
311
 
309
312
  /**
310
- * Fetch the myfaces config params
313
+ * lets drag the myfaces config params also in
311
314
  */
312
315
  requestCtx.assign(MYFACES).value = options.value?.myfaces;
313
316
 
314
317
  /**
315
318
  * binding contract the jakarta.faces.source must be set
316
319
  */
317
- requestCtx.assign(CTX_PARAM_REQ_PASS_THR, P_AJAX_SOURCE).value = elementId;
320
+ requestCtx.assign(CTX_PARAM_REQ_PASS_THR, P_PARTIAL_SOURCE).value = elementId;
318
321
 
319
322
  /**
320
323
  * jakarta.faces.partial.ajax must be set to true
@@ -341,9 +344,6 @@ export module Implementation {
341
344
  // won't hurt but for the sake of compatibility we are going to add it
342
345
  requestCtx.assign(CTX_PARAM_REQ_PASS_THR, formId).value = formId;
343
346
  internalCtx.assign(CTX_PARAM_SRC_CTL_ID).value = elementId;
344
- // reintroduction of PPS as per myfaces 2.3 (myfaces.pps = true, only the executes are submitted)
345
- internalCtx.assign(CTX_PARAM_PPS).value = extractMyFacesParams(options.value)?.[MYFACES_OPTION_PPS] ?? false;
346
-
347
347
 
348
348
  assignClientWindowId(form, requestCtx);
349
349
  assignExecute(options, requestCtx, form, elementId);
@@ -424,7 +424,7 @@ export module Implementation {
424
424
  }
425
425
  } finally {
426
426
  if (clearRequestQueue) {
427
- requestQueue.clear();
427
+ requestQueue.cleanup();
428
428
  }
429
429
  }
430
430
  }
@@ -467,12 +467,29 @@ export module Implementation {
467
467
  /*
468
468
  * the search root for the dom element search
469
469
  */
470
- let searchRoot = new DQ(node || document.body).querySelectorAll(`form input [name='${P_CLIENT_WINDOW}']`);
470
+
471
+
472
+ let searchRoot = ((node) ? DQ.byId(node): DQ$("form"));
473
+ let inputs = searchRoot
474
+ .filterSelector(`input[name='${$nsp(P_CLIENT_WINDOW)}']`)
475
+ .orElseLazy(() => searchRoot.querySelectorAll(`input[name='${$nsp(P_CLIENT_WINDOW)}']`))
471
476
 
472
477
  /*
473
- * lazy helper to fetch the window id from the window url
478
+ * lazy helper to fetch the window id from the included faces.js
474
479
  */
475
- let fetchWindowIdFromUrl = () => ExtDomQuery.searchJsfJsFor(/jfwid=([^&;]*)/).orElse(null).value;
480
+ let fetchWindowIdFromJSFJS = () => ExtDomQuery.searchJsfJsFor(/jfwid=([^&;]*)/).orElse(null).value;
481
+
482
+ /*
483
+ * fetch window id from the url
484
+ */
485
+ let fetchWindowIdFromURL = function () {
486
+ const href = window.location.href, windowId = "jfwid";
487
+ const regex = new RegExp("[\\?&]" + windowId + "=([^&#\\;]*)");
488
+ const results = regex.exec(href);
489
+ //initial trial over the url and a regexp
490
+ if (results != null) return results[1];
491
+ return null;
492
+ };
476
493
 
477
494
  /*
478
495
  * functional double check based on stream reduction
@@ -482,7 +499,7 @@ export module Implementation {
482
499
  * @param value1
483
500
  * @param value2
484
501
  */
485
- let differenceCheck = (value1: string, value2: string) => {
502
+ let differenceCheck = (value1: string, value2: string): string => {
486
503
  if(value1 == INIT) {
487
504
  return value2;
488
505
  } else if (value1 == ALTERED || value1 != value2) {
@@ -496,15 +513,14 @@ export module Implementation {
496
513
  *
497
514
  * @param item
498
515
  */
499
- let getValue = (item: DQ) => item.attr("value").value;
516
+ let getValue = (item: DQ): string => item.val as string;
500
517
  /*
501
518
  * fetch the window id from the forms
502
519
  * window ids must be present in all forms
503
520
  * or non-existent. If they exist all of them must be the same
504
521
  */
505
522
 
506
- let formWindowId: Optional<string> = Optional.fromNullable(searchRoot.asArray
507
- .map<string>(getValue).reduce(differenceCheck, INIT));
523
+ let formWindowId: Optional<string> = inputs.stream.map(getValue).reduce(differenceCheck, INIT);
508
524
 
509
525
 
510
526
  //if the resulting window id is set on altered then we have an unresolvable problem
@@ -513,7 +529,7 @@ export module Implementation {
513
529
  /*
514
530
  * return the window id or null
515
531
  */
516
- return formWindowId.value != INIT ? formWindowId.value : fetchWindowIdFromUrl();
532
+ return formWindowId.value != INIT ? formWindowId.value : (fetchWindowIdFromURL() || fetchWindowIdFromJSFJS());
517
533
  }
518
534
 
519
535
  /**
@@ -542,7 +558,7 @@ export module Implementation {
542
558
  let formElements = element.deepElements.encodeFormElement()
543
559
 
544
560
  // encode them! (file inputs are handled differently and are not part of the viewstate)
545
- return encodeFormData(new ExtConfig(formElements), resoveNamingContainerMapper(dummyContext));
561
+ return encodeFormData(formElements, resoveNamingContainerMapper(dummyContext));
546
562
  }
547
563
 
548
564
  /**
@@ -557,8 +573,8 @@ export module Implementation {
557
573
  * adds a new request to our queue for further processing
558
574
  */
559
575
  addRequestToQueue: function (elem: DQ, form: DQ, reqCtx: ExtConfig, respPassThr: Config, delay = 0, timeout = 0) {
560
- requestQueue = requestQueue ?? new XhrQueueController<XhrRequest>();
561
- requestQueue.enqueue(new XhrRequest(reqCtx, respPassThr, timeout), delay);
576
+ requestQueue = requestQueue ?? new AsynchronousQueue<XhrRequest>();
577
+ requestQueue.enqueue(new XhrRequest(elem, form, reqCtx, respPassThr, [], timeout), delay);
562
578
  }
563
579
  };
564
580
 
@@ -667,7 +683,7 @@ export module Implementation {
667
683
  * can deal with them either prefixed ir not
668
684
  * also resolves the absolute id case (it was assumed the server does this, but
669
685
  * apparently the RI does not, so we have to follow the RI behavior here)
670
- * @param componentIdToTransform the componentId which needs post-processing
686
+ * @param componentIdToTransform the componentId which needs post processing
671
687
  */
672
688
  const remapNamingContainer = componentIdToTransform => {
673
689
  // pattern :<anything> must be prepended by viewRoot if there is one,
@@ -681,7 +697,7 @@ export module Implementation {
681
697
  const hasLeadingSep = componentIdToTransform.indexOf(SEP) === 0;
682
698
  const isAbsolutSearchExpr = hasLeadingSep || (rootNamingContainerId.length
683
699
  && componentIdToTransform.indexOf(rootNamingContainerPrefix) == 0);
684
- let finalIdentifier: string;
700
+ let finalIdentifier = "";
685
701
  if (isAbsolutSearchExpr) {
686
702
  //we cut off the leading sep if there is one
687
703
  componentIdToTransform = hasLeadingSep ? componentIdToTransform.substring(1) : componentIdToTransform;
@@ -700,14 +716,14 @@ export module Implementation {
700
716
  [rootNamingContainerPrefix, componentIdToTransform].join(EMPTY_STR) :
701
717
  [nearestNamingContainerPrefix, componentIdToTransform].join(EMPTY_STR);
702
718
  }
703
- // We need to double-check because we have scenarios where we have a naming container
719
+ // We need to double check because we have scenarios where we have a naming container
704
720
  // and no prepend (aka tobago testcase "must handle ':' in IDs properly", scenario 3,
705
721
  // in this case we return the component id, and be happy
706
722
  // we can roll a dom check here
707
723
  return (!!document.getElementById(finalIdentifier)) ? finalIdentifier : componentIdToTransform;
708
724
  };
709
725
 
710
- // in this case we do not use lazy stream because it won´t bring any code reduction
726
+ // in this case we do not use lazy stream because it wont bring any code reduction
711
727
  // or speedup
712
728
  for (let cnt = 0; cnt < iterValues.length; cnt++) {
713
729
  //avoid doubles
@@ -749,37 +765,24 @@ export module Implementation {
749
765
  * the values required for params-through are processed in the ajax request
750
766
  *
751
767
  * Note this is a bug carried over from the old implementation
752
- * the spec conform behavior is to use params for pass - through values
768
+ * the spec conform behavior is to use params for passthrough values
753
769
  * this will be removed soon, after it is cleared up whether removing
754
770
  * it breaks any legacy code
755
771
  *
756
772
  * @param {Context} mappedOpts the options to be filtered
773
+ * @deprecated
757
774
  */
758
- function extractLegacyParams(mappedOpts: Options): {[key: string]: any} {
759
- //we now can use the full code reduction given by our stream api
760
- //to filter
761
- return ofAssoc(mappedOpts)
762
- .filter((item => !(item[0] in BlockFilter)))
763
- .reduce(collectAssoc, {});
764
- }
765
-
766
- /**
767
- * extracts the myfaces config parameters which provide extra functionality
768
- * on top of JSF
769
- * @param mappedOpts
770
- * @private
771
- */
772
- function extractMyFacesParams(mappedOpts: Options): {[key: string]: any} {
775
+ function extractLegacyParams(mappedOpts: Options): Context {
773
776
  //we now can use the full code reduction given by our stream api
774
777
  //to filter
775
- return ofAssoc(mappedOpts)
776
- .filter((item => (item[0] == "myfaces")))
777
- .reduce(collectAssoc, {})?.[MYFACES];
778
+ return Stream.ofAssoc(mappedOpts)
779
+ .filter(item => !(item[0] in BlockFilter))
780
+ .collect(new AssocArrayCollector());
778
781
  }
779
782
 
780
783
  function remapArrayToAssocArr(arrayedParams: [[string, any]] | {[key: string]: any}): {[key: string]: any} {
781
784
  if(Array.isArray(arrayedParams)) {
782
- return arrayedParams.reduce(collectAssoc, {} as any);
785
+ return Stream.of(... arrayedParams).collect(new AssocArrayCollector());
783
786
  }
784
787
  return arrayedParams;
785
788
  }
@@ -21,8 +21,8 @@
21
21
  export const XML_ATTR_NAMED_VIEWROOT = "namedViewRoot";
22
22
  export const NAMED_VIEWROOT = "namedViewRoot";
23
23
 
24
- export const P_AJAX_SOURCE = "jakarta.faces.source";
25
- export const NAMING_CONTAINER_ID = "myfaces.NamingContainerId";
24
+ export const P_PARTIAL_SOURCE = "jakarta.faces.source";
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";
@@ -108,7 +108,6 @@ export const CTX_PARAM_MF_INTERNAL = "myfaces.internal";
108
108
  export const CTX_PARAM_SRC_FRM_ID = "myfaces.source.formId";
109
109
  export const CTX_PARAM_SRC_CTL_ID = "myfaces.source.controlId";
110
110
  export const CTX_PARAM_REQ_PASS_THR = "myfaces.request.passThrough";
111
- export const CTX_PARAM_PPS = "myfaces.request.pps";
112
111
 
113
112
  export const CONTENT_TYPE = "Content-Type";
114
113
  export const HEAD_FACES_REQ = "Faces-Request";
@@ -142,8 +141,6 @@ export const PHASE_PROCESS_RESPONSE = "processResponse";
142
141
 
143
142
  export const ERR_NO_PARTIAL_RESPONSE = "Partial response not set";
144
143
 
145
- export const MYFACES_OPTION_PPS = "pps";
146
-
147
144
  export const ATTR_URL = "url";
148
145
  export const ATTR_NAME = "name";
149
146
  export const ATTR_VALUE = "value";
@@ -0,0 +1,133 @@
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
+ import {AsyncRunnable} from "./AsyncRunnable";
17
+
18
+ /**
19
+ * Asynchronous queue which starts to work
20
+ * through the callbacks until the queue is empty
21
+ *
22
+ * Every callback must be of async runnable
23
+ * which is sort of an extended promise which has
24
+ * added a dedicated cancel and start point
25
+ *
26
+ * This interface can be used as wrapper contract
27
+ * for normal promises if needed.
28
+ */
29
+ export class AsynchronousQueue<T extends AsyncRunnable<any>> {
30
+
31
+ private runnableQueue = [];
32
+ private delayTimeout: null | ReturnType<typeof setTimeout>;
33
+
34
+ currentlyRunning: AsyncRunnable<any>;
35
+
36
+ constructor() {
37
+ }
38
+
39
+ /**
40
+ * simple is empty accessor, returns true if queue is empty atm
41
+ */
42
+ get isEmpty(): boolean {
43
+ return !this.runnableQueue.length;
44
+ }
45
+
46
+ /**
47
+ * enqueues an element and starts the
48
+ * asynchronous work loop if not already running
49
+ *
50
+ * @param element the element to be queued and processed
51
+ * @param delay possible delay after our usual process or drop if something newer is incoming algorithm
52
+ */
53
+ enqueue(element: T, delay = 0) {
54
+ if (this.delayTimeout) {
55
+ clearTimeout(this.delayTimeout);
56
+ this.delayTimeout = null;
57
+ }
58
+ if (delay) {
59
+ this.delayTimeout = setTimeout(() => {
60
+ this.appendElement(element);
61
+ }) as any;
62
+ } else {
63
+ this.appendElement(element);
64
+ }
65
+ }
66
+
67
+ /**
68
+ * fetches the next element from the queue (first in first out order)
69
+ */
70
+ dequeue(): T | undefined{
71
+ return this.runnableQueue.shift();
72
+ }
73
+
74
+ /**
75
+ * clears up all elements from the queue
76
+ */
77
+ cleanup() {
78
+ this.currentlyRunning = null;
79
+ this.runnableQueue.length = 0;
80
+ }
81
+
82
+ /**
83
+ * cancels the currently running element and then cleans up the queue
84
+ * aka cancel the queue entirely
85
+ */
86
+ cancel() {
87
+ try {
88
+ if (this.currentlyRunning) {
89
+ this.currentlyRunning.cancel();
90
+ }
91
+ } finally {
92
+ this.cleanup();
93
+ }
94
+ }
95
+
96
+ private callForNextElementToProcess() {
97
+ this.runEntry();
98
+ }
99
+
100
+ private appendElement(element: T) {
101
+ //only if the first element is added we start with a trigger
102
+ //otherwise a process already is running and not finished yet at that
103
+ //time
104
+ this.runnableQueue.push(element);
105
+ if (!this.currentlyRunning) {
106
+ this.runEntry();
107
+ }
108
+ }
109
+
110
+ private runEntry() {
111
+ if (this.isEmpty) {
112
+ this.currentlyRunning = null;
113
+ return;
114
+ }
115
+ this.currentlyRunning = this.dequeue();
116
+ this.currentlyRunning
117
+ .catch((e) => {
118
+ //in case of an error we always clean up the remaining calls
119
+ //to allow a clean recovery of the application
120
+ this.cleanup();
121
+ throw e;
122
+ })
123
+ .then(
124
+ //the idea is to trigger the next over an event to reduce
125
+ //the number of recursive calls (stacks might be limited
126
+ //compared to ram)
127
+ //naturally give we have a DOM, the DOM is the natural event dispatch system
128
+ //which we can use, to decouple the calls from a recursive stack call
129
+ //(the browser engine will take care of that)
130
+ () => this.callForNextElementToProcess()
131
+ ).start();
132
+ }
133
+ }