jsf.js_next_gen 4.0.0-RC.2 → 4.0.0-RC.21

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 (130) hide show
  1. package/dist/docs/assets/main.js +56 -52
  2. package/dist/docs/assets/style.css +23 -0
  3. package/dist/docs/functions/myfaces.ab.html +2 -2
  4. package/dist/window/faces-development.js +789 -306
  5. package/dist/window/faces-development.js.br +0 -0
  6. package/dist/window/faces-development.js.gz +0 -0
  7. package/dist/window/faces-development.js.map +1 -1
  8. package/dist/window/faces.js +1 -1
  9. package/dist/window/faces.js.LICENSE.txt +0 -2
  10. package/dist/window/faces.js.br +0 -0
  11. package/dist/window/faces.js.gz +0 -0
  12. package/dist/window/faces.js.map +1 -1
  13. package/dist/window/jsf-development.js +789 -306
  14. package/dist/window/jsf-development.js.br +0 -0
  15. package/dist/window/jsf-development.js.gz +0 -0
  16. package/dist/window/jsf-development.js.map +1 -1
  17. package/dist/window/jsf.js +1 -1
  18. package/dist/window/jsf.js.LICENSE.txt +0 -2
  19. package/dist/window/jsf.js.br +0 -0
  20. package/dist/window/jsf.js.gz +0 -0
  21. package/dist/window/jsf.js.map +1 -1
  22. package/package.json +16 -16
  23. package/src/main/test.xml +23 -0
  24. package/src/main/typescript/@types/definitions/index.d.ts +19 -2
  25. package/src/main/typescript/api/_api.ts +5 -4
  26. package/src/main/typescript/impl/AjaxImpl.ts +109 -37
  27. package/src/main/typescript/impl/core/Const.ts +48 -38
  28. package/src/main/typescript/impl/util/Assertions.ts +16 -8
  29. package/src/main/typescript/impl/util/AsyncQueue.ts +1 -1
  30. package/src/main/typescript/impl/util/ExtDomQuery.ts +12 -4
  31. package/src/main/typescript/impl/util/HiddenInputBuilder.ts +78 -0
  32. package/src/main/typescript/impl/util/Lang.ts +9 -11
  33. package/src/main/typescript/impl/xhrCore/ErrorData.ts +15 -10
  34. package/src/main/typescript/impl/xhrCore/EventData.ts +2 -2
  35. package/src/main/typescript/impl/xhrCore/IResponseProcessor.ts +8 -1
  36. package/src/main/typescript/impl/xhrCore/RequestDataResolver.ts +40 -22
  37. package/src/main/typescript/impl/xhrCore/ResonseDataResolver.ts +4 -4
  38. package/src/main/typescript/impl/xhrCore/Response.ts +25 -25
  39. package/src/main/typescript/impl/xhrCore/ResponseProcessor.ts +157 -98
  40. package/src/main/typescript/impl/xhrCore/XhrFormData.ts +4 -2
  41. package/src/main/typescript/impl/xhrCore/XhrRequest.ts +24 -14
  42. package/src/main/typescript/myfaces/OamSubmit.ts +29 -13
  43. package/src/main/typescript/test/frameworkBase/_ext/monadish/DomQueryTest.spec.ts +1 -1
  44. package/src/main/typescript/test/frameworkBase/_ext/shared/StandardInits.ts +72 -0
  45. package/src/main/typescript/test/frameworkBase/_ext/shared/XmlResponses.ts +40 -1
  46. package/src/main/typescript/test/impl/ImplTest.spec.ts +3 -3
  47. package/src/main/typescript/test/impl/ImplTest_23.spec.ts +3 -3
  48. package/src/main/typescript/test/xhrCore/EventTests.spec.ts +1 -1
  49. package/src/main/typescript/test/xhrCore/NamespacesRequestTest.spec.ts +203 -0
  50. package/src/main/typescript/test/xhrCore/OamSubmitTest.spec.ts +177 -0
  51. package/src/main/typescript/test/xhrCore/RequestParamsTest.spec.ts +116 -9
  52. package/src/main/typescript/test/xhrCore/RequestTest.spec.ts +236 -11
  53. package/src/main/typescript/test/xhrCore/RequestTest_23.spec.ts +39 -3
  54. package/src/main/typescript/test/xhrCore/ResponseTest.spec.ts +368 -31
  55. package/src/main/typescript/test/xhrCore/ResponseTest23.spec.ts +41 -7
  56. package/src/main/typescript/test.xml +6 -0
  57. package/src/main/typescript/tsconfig.json +1 -1
  58. package/src/tmp/test.html +12 -88
  59. package/target/api/_api.js +5 -4
  60. package/target/api/_api.js.map +1 -1
  61. package/target/impl/AjaxImpl.js +97 -26
  62. package/target/impl/AjaxImpl.js.map +1 -1
  63. package/target/impl/core/Const.js +48 -37
  64. package/target/impl/core/Const.js.map +1 -1
  65. package/target/impl/core/Context.js +10 -0
  66. package/target/impl/core/Context.js.map +1 -0
  67. package/target/impl/util/Assertions.js +12 -7
  68. package/target/impl/util/Assertions.js.map +1 -1
  69. package/target/impl/util/AsyncQueue.js.map +1 -1
  70. package/target/impl/util/ExtDomQuery.js +9 -2
  71. package/target/impl/util/ExtDomQuery.js.map +1 -1
  72. package/target/impl/util/HiddenElementBuilder.js +7 -0
  73. package/target/impl/util/HiddenElementBuilder.js.map +1 -0
  74. package/target/impl/util/HiddenInputBuilder.js +69 -0
  75. package/target/impl/util/HiddenInputBuilder.js.map +1 -0
  76. package/target/impl/util/Lang.js +8 -10
  77. package/target/impl/util/Lang.js.map +1 -1
  78. package/target/impl/xhrCore/ErrorData.js +10 -8
  79. package/target/impl/xhrCore/ErrorData.js.map +1 -1
  80. package/target/impl/xhrCore/EventData.js +1 -1
  81. package/target/impl/xhrCore/EventData.js.map +1 -1
  82. package/target/impl/xhrCore/RequestContext.js +11 -0
  83. package/target/impl/xhrCore/RequestContext.js.map +1 -0
  84. package/target/impl/xhrCore/RequestDataResolver.js +34 -15
  85. package/target/impl/xhrCore/RequestDataResolver.js.map +1 -1
  86. package/target/impl/xhrCore/ResonseDataResolver.js +3 -3
  87. package/target/impl/xhrCore/ResonseDataResolver.js.map +1 -1
  88. package/target/impl/xhrCore/Response.js +13 -13
  89. package/target/impl/xhrCore/Response.js.map +1 -1
  90. package/target/impl/xhrCore/ResponseProcessor.js +136 -82
  91. package/target/impl/xhrCore/ResponseProcessor.js.map +1 -1
  92. package/target/impl/xhrCore/XhrFormData.js +4 -2
  93. package/target/impl/xhrCore/XhrFormData.js.map +1 -1
  94. package/target/impl/xhrCore/XhrRequest.js +20 -11
  95. package/target/impl/xhrCore/XhrRequest.js.map +1 -1
  96. package/target/myfaces/OamSubmit.js +23 -14
  97. package/target/myfaces/OamSubmit.js.map +1 -1
  98. package/target/test/frameworkBase/_ext/monadish/DomQueryTest.spec.js +1 -1
  99. package/target/test/frameworkBase/_ext/monadish/DomQueryTest.spec.js.map +1 -1
  100. package/target/test/frameworkBase/_ext/shared/StandardInits.js +63 -0
  101. package/target/test/frameworkBase/_ext/shared/StandardInits.js.map +1 -1
  102. package/target/test/frameworkBase/_ext/shared/XmlResponses.js +37 -1
  103. package/target/test/frameworkBase/_ext/shared/XmlResponses.js.map +1 -1
  104. package/target/test/impl/ImplTest.spec.js +2 -2
  105. package/target/test/impl/ImplTest.spec.js.map +1 -1
  106. package/target/test/impl/ImplTest_23.spec.js +2 -2
  107. package/target/test/impl/ImplTest_23.spec.js.map +1 -1
  108. package/target/test/xhrCore/EventTests.spec.js +1 -1
  109. package/target/test/xhrCore/EventTests.spec.js.map +1 -1
  110. package/target/test/xhrCore/NamespacesRequestTest.spec.js +203 -0
  111. package/target/test/xhrCore/NamespacesRequestTest.spec.js.map +1 -0
  112. package/target/test/xhrCore/OamSubmitTest.spec.js +180 -0
  113. package/target/test/xhrCore/OamSubmitTest.spec.js.map +1 -0
  114. package/target/test/xhrCore/RequestParamsTest.spec.js +101 -4
  115. package/target/test/xhrCore/RequestParamsTest.spec.js.map +1 -1
  116. package/target/test/xhrCore/RequestTest.spec.js +212 -9
  117. package/target/test/xhrCore/RequestTest.spec.js.map +1 -1
  118. package/target/test/xhrCore/RequestTest_23.spec.js +34 -2
  119. package/target/test/xhrCore/RequestTest_23.spec.js.map +1 -1
  120. package/target/test/xhrCore/ResponseTest.spec.js +303 -22
  121. package/target/test/xhrCore/ResponseTest.spec.js.map +1 -1
  122. package/target/test/xhrCore/ResponseTest23.spec.js +36 -6
  123. package/target/test/xhrCore/ResponseTest23.spec.js.map +1 -1
  124. package/tmp.xml +36 -0
  125. package/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +0 -4
  126. package/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +0 -4
  127. package/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst +0 -1
  128. package/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst +0 -1
  129. package/target/surefire-reports/TEST-com.example.jsfs_js_ts.JsfsJsTsApplicationTests.xml +0 -78
  130. package/target/surefire-reports/com.example.jsfs_js_ts.JsfsJsTsApplicationTests.txt +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsf.js_next_gen",
3
- "version": "4.0.0-RC.2",
3
+ "version": "4.0.0-RC.21",
4
4
  "description": "A next generation typescript reimplementation of jsf.js",
5
5
  "main": "dist/window/faces.js",
6
6
  "scripts": {
@@ -21,33 +21,33 @@
21
21
  "license": "Apache-2.0",
22
22
  "devDependencies": {
23
23
  "@istanbuljs/nyc-config-typescript": "^1.0.2",
24
- "@types/chai": "^4.3.3",
25
- "@types/mocha": "^10.0.0",
26
- "@types/node": "^18.11.9",
24
+ "@types/chai": "^4.3.4",
25
+ "@types/mocha": "^10.0.1",
26
+ "@types/node": "^18.11.18",
27
27
  "@types/sinon": "^10.0.13",
28
28
  "babel-plugin-syntax-dynamic-import": "^6.18.0",
29
- "chai": "^4.3.6",
29
+ "chai": "^4.3.7",
30
30
  "compression-webpack-plugin": "^10.0.0",
31
31
  "html-webpack-plugin": "^5.5.0",
32
32
  "http-server": "^14.1.1",
33
- "jsdom": "^20.0.2",
33
+ "jsdom": "^21.0.0",
34
34
  "jsdom-global": "^3.0.2",
35
- "mocha": "^10.1.0",
36
- "npm-check-updates": "^16.3.16",
35
+ "mocha": "^10.2.0",
36
+ "npm-check-updates": "^16.6.2",
37
37
  "nyc": "^15.1.0",
38
38
  "replace-in-file": "^6.3.5",
39
- "rxjs": "^7.5.7",
40
- "sinon": "^14.0.1",
39
+ "rxjs": "^7.8.0",
40
+ "sinon": "^15.0.1",
41
41
  "terser-webpack-plugin": "^5.3.6",
42
- "ts-loader": "^9.4.1",
42
+ "ts-loader": "^9.4.2",
43
43
  "ts-node": "^10.9.1",
44
- "typedoc": "^0.23.20",
45
- "typescript": "^4.8.4",
46
- "webpack": "^5.74.0",
47
- "webpack-cli": "^4.10.0",
44
+ "typedoc": "^0.23.24",
45
+ "typescript": "^4.9.4",
46
+ "webpack": "^5.75.0",
47
+ "webpack-cli": "^5.0.1",
48
48
  "webpack-dev-server": "^4.11.1"
49
49
  },
50
50
  "dependencies": {
51
- "mona-dish": "0.23.5"
51
+ "mona-dish": "^0.24.3"
52
52
  }
53
53
  }
@@ -0,0 +1,23 @@
1
+ <partial-response id="viewroot_1">
2
+ <changes>
3
+ <update id="panel2"><![CDATA[
4
+ <div id="panel2">
5
+ after update
6
+ <form id="form2" name="form2" method="post" action="booga2"
7
+ ><a href="#" id="form2:link" name="form2:link"></a>
8
+ <input type="hidden" name="form2_SUBMIT" value="1"/></form>
9
+ </div>
10
+ ]]>
11
+ </update>
12
+ <update id="panel3"><![CDATA[
13
+ <div id="panel3">
14
+ after update
15
+ <form id="form3" name="form3" method="post" action="booga3"
16
+ ><a href="#" id="form3:link" name="form3:link"></a>
17
+ </form>
18
+ </div>
19
+ ]]>
20
+ </update>
21
+ <update id="j_id__v_0:jakarta.faces.ViewState:1"><![CDATA[booga_after_update]]></update>
22
+ </changes>
23
+ </partial-response>
@@ -23,9 +23,24 @@
23
23
  declare global {
24
24
 
25
25
  type Consumer<T> = (s?: T) => void;
26
+ type Tuple<V,K> = [V, K];
27
+ type Tuples<V,K> = [Tuple<V, K>];
26
28
  type AssocArr<T> = { [key: string]: T };
27
29
  type EvalFuncs = Array<Function | string>;
28
- type Options = { [key: string]: string | Function | { [key: string]: string | Function } };
30
+
31
+
32
+ type Options = {
33
+ render ?: string,
34
+ execute ?: string, //space separated list of client ids
35
+ onevent ?: Function, // event handler callback
36
+ onerror ?: Function, // error handler callback
37
+ params ?: AssocArr<any>, // passthrough params
38
+ delay ?: number, // delay in milliseconds
39
+ resetValues ?: boolean, // if set to true jakarta.faces.partial.resetValues is sent
40
+ /* @deprecated non-spec conform fallback behavior that anything can be passed and is used as passthrough */
41
+ [key: string]: any
42
+ }
43
+
29
44
  type Context = AssocArr<any>;
30
45
  type ElemDef = Element | string;
31
46
 
@@ -106,7 +121,7 @@ declare global {
106
121
  interface OAM {
107
122
  clearHiddenInput(formName: string, name: string): void;
108
123
  setHiddenInput(formName: string, name: string, value: string): void;
109
- submitForm(formName: string, linkId: string, target: string, params: { [key: string]: any }): boolean;
124
+ submitForm(formName: string, linkId?: string |null, target?: string | null, params?: AssocArr<any> |Tuples<string, any> | null): boolean;
110
125
  }
111
126
 
112
127
  interface MyFacesAPI {
@@ -119,6 +134,8 @@ declare global {
119
134
  };
120
135
  }
121
136
 
137
+
138
+
122
139
  /*
123
140
  * Global namespaces type definitions
124
141
  */
@@ -16,7 +16,7 @@
16
16
  import {Implementation} from "../impl/AjaxImpl";
17
17
  import {PushImpl} from "../impl/PushImpl";
18
18
  import {oam as _oam} from "../myfaces/OamSubmit";
19
- import {$nsp, CTX_PARAM_EXECUTE, CTX_PARAM_RENDER, P_BEHAVIOR_EVENT} from "../impl/core/Const";
19
+ import {$nsp, CTX_OPTIONS_EXECUTE, CTX_OPTIONS_PARAMS, CTX_PARAM_RENDER, P_BEHAVIOR_EVENT} from "../impl/core/Const";
20
20
  import {ErrorData} from "../impl/xhrCore/ErrorData";
21
21
  import {EventData} from "../impl/xhrCore/EventData";
22
22
 
@@ -252,12 +252,13 @@ export module myfaces {
252
252
  * @param render
253
253
  * @param options
254
254
  */
255
- export function ab(source: Element, event: Event, eventName: string, execute: string, render: string, options: Context = {}): void {
255
+ export function ab(source: Element, event: Event, eventName: string, execute: string, render: string, options: Options = {}): void {
256
256
  if (eventName) {
257
- options[$nsp(P_BEHAVIOR_EVENT)] = eventName;
257
+ options[CTX_OPTIONS_PARAMS] = options?.[CTX_OPTIONS_PARAMS] ?? {};
258
+ options[CTX_OPTIONS_PARAMS][$nsp(P_BEHAVIOR_EVENT)] = eventName;
258
259
  }
259
260
  if (execute) {
260
- options[CTX_PARAM_EXECUTE] = execute;
261
+ options[CTX_OPTIONS_EXECUTE] = execute;
261
262
  }
262
263
  if (render) {
263
264
  options[CTX_PARAM_RENDER] = render;
@@ -21,17 +21,16 @@ import {AsynchronousQueue} from "./util/AsyncQueue";
21
21
  import {AssocArrayCollector, Config, DQ, Lang, LazyStream, Optional, Stream} from "mona-dish";
22
22
  import {Assertions} from "./util/Assertions";
23
23
  import {XhrFormData} from "./xhrCore/XhrFormData";
24
- import {ExtDomQuery} from "./util/ExtDomQuery";
24
+ import {ExtConfig, ExtDomQuery} from "./util/ExtDomQuery";
25
25
  import {ErrorData} from "./xhrCore/ErrorData";
26
26
  import {EventData} from "./xhrCore/EventData";
27
27
  import {ExtLang} from "./util/Lang";
28
28
 
29
29
  import {
30
- CTX_PARAM_EXECUTE,
31
- CTX_PARAM_PASS_THR,
30
+ CTX_OPTIONS_EXECUTE,
31
+ CTX_PARAM_REQ_PASS_THR,
32
32
  CTX_PARAM_SRC_CTL_ID,
33
33
  CTX_PARAM_SRC_FRM_ID,
34
- CTX_PARAM_TR_TYPE,
35
34
  IDENT_ALL,
36
35
  IDENT_FORM,
37
36
  IDENT_NONE,
@@ -48,15 +47,14 @@ import {
48
47
  P_RESET_VALUES,
49
48
  P_WINDOW_ID,
50
49
  CTX_PARAM_RENDER,
51
- REQ_TYPE_POST,
52
50
  SOURCE,
53
- TAG_FORM
51
+ HTML_TAG_FORM, CTX_OPTIONS_PARAMS, VIEW_ID, $faces, EMPTY_STR
54
52
  } from "./core/Const";
55
53
  import {
56
54
  resolveDefaults,
57
55
  resolveDelay,
58
56
  resolveForm,
59
- resolveTimeout
57
+ resolveTimeout, resolveViewId
60
58
  } from "./xhrCore/RequestDataResolver";
61
59
 
62
60
  /*
@@ -81,7 +79,9 @@ enum BlockFilter {
81
79
  myfaces = "myfaces",
82
80
  delay = "delay",
83
81
  timeout = "timeout",
84
- windowId = "windowId"
82
+ resetValues = "resetValues",
83
+ windowId = "windowId",
84
+ params = "params"
85
85
  }
86
86
 
87
87
  /**
@@ -241,15 +241,14 @@ export module Implementation {
241
241
  export function request(el: ElemDef, event?: Event, opts ?: Options) {
242
242
 
243
243
  const {
244
- resolvedEvent,
245
244
  options,
246
245
  elem,
247
246
  elementId,
248
- requestCtx,
249
- internalCtx,
250
247
  windowId,
251
248
  isResetValues
252
249
  } = resolveDefaults(event, opts, el);
250
+ const requestCtx = new ExtConfig({});
251
+ const internalCtx = new ExtConfig({});
253
252
 
254
253
  Assertions.assertRequestIntegrity(options, elem);
255
254
 
@@ -260,15 +259,28 @@ export module Implementation {
260
259
  * so that people can use dummy forms and work
261
260
  * with detached objects
262
261
  */
263
- const form: DQ = resolveForm(requestCtx, elem, resolvedEvent);
262
+ const form: DQ = resolveForm(elem, event);
263
+ const viewId: string = resolveViewId(form);
264
264
  const formId = form.id.value;
265
265
  const delay: number = resolveDelay(options);
266
266
  const timeout: number = resolveTimeout(options);
267
267
 
268
268
  requestCtx.assignIf(!!windowId, P_WINDOW_ID).value = windowId;
269
269
 
270
- requestCtx.assign(CTX_PARAM_PASS_THR).value = filterPassThroughValues(options.value);
271
- requestCtx.assignIf(!!resolvedEvent, CTX_PARAM_PASS_THR, P_EVT).value = resolvedEvent?.type;
270
+ // old non spec behavior will be removed after it is clear whether the removal breaks any code
271
+ requestCtx.assign(CTX_PARAM_REQ_PASS_THR).value = extractLegacyParams(options.value);
272
+
273
+ // spec conform behavior, all passthrough params must be under "passthrough
274
+ const params = remapArrayToAssocArr(options.getIf(CTX_OPTIONS_PARAMS).orElse({}).value);
275
+ //we turn off the remapping for the param merge, because we do not want to have
276
+ //any namespacing to be remapped
277
+
278
+ let ctxPassthrough = requestCtx.getIf(CTX_PARAM_REQ_PASS_THR) as ExtConfig;
279
+ ctxPassthrough.$nspEnabled = false;
280
+ ctxPassthrough.shallowMerge(new Config(params), true);
281
+ //now we turn it on again
282
+ ctxPassthrough.$nspEnabled = true;
283
+ requestCtx.assignIf(!!event, CTX_PARAM_REQ_PASS_THR, P_EVT).value = event?.type;
272
284
 
273
285
  /**
274
286
  * ajax pass through context with the source
@@ -276,6 +288,8 @@ export module Implementation {
276
288
  */
277
289
  requestCtx.assign(SOURCE).value = elementId;
278
290
 
291
+ requestCtx.assign(VIEW_ID).value = viewId;
292
+
279
293
  /**
280
294
  * on resolvedEvent and onError...
281
295
  * those values will be traversed later on
@@ -292,12 +306,12 @@ export module Implementation {
292
306
  /**
293
307
  * binding contract the jakarta.faces.source must be set
294
308
  */
295
- requestCtx.assign(CTX_PARAM_PASS_THR, P_PARTIAL_SOURCE).value = elementId;
309
+ requestCtx.assign(CTX_PARAM_REQ_PASS_THR, P_PARTIAL_SOURCE).value = elementId;
296
310
 
297
311
  /**
298
312
  * jakarta.faces.partial.ajax must be set to true
299
313
  */
300
- requestCtx.assign(CTX_PARAM_PASS_THR, P_AJAX).value = true;
314
+ requestCtx.assign(CTX_PARAM_REQ_PASS_THR, P_AJAX).value = true;
301
315
 
302
316
  /**
303
317
  * if resetValues is set to true
@@ -306,7 +320,7 @@ export module Implementation {
306
320
  * the value has to be explicitly true, according to
307
321
  * the specs jsdoc
308
322
  */
309
- requestCtx.assignIf(isResetValues, CTX_PARAM_PASS_THR, P_RESET_VALUES).value = true;
323
+ requestCtx.assignIf(isResetValues, CTX_PARAM_REQ_PASS_THR, P_RESET_VALUES).value = true;
310
324
 
311
325
  // additional meta information to speed things up, note internal non jsf
312
326
  // pass through options are stored under _mfInternal in the context
@@ -317,9 +331,8 @@ export module Implementation {
317
331
  // mojarra under blackbox conditions.
318
332
  // I assume it does the same as our formId_submit=1 so leaving it out
319
333
  // won't hurt but for the sake of compatibility we are going to add it
320
- requestCtx.assign(CTX_PARAM_PASS_THR, formId).value = formId;
334
+ requestCtx.assign(CTX_PARAM_REQ_PASS_THR, formId).value = formId;
321
335
  internalCtx.assign(CTX_PARAM_SRC_CTL_ID).value = elementId;
322
- internalCtx.assign(CTX_PARAM_TR_TYPE).value = REQ_TYPE_POST;
323
336
 
324
337
  assignClientWindowId(form, requestCtx);
325
338
  assignExecute(options, requestCtx, form, elementId);
@@ -505,7 +518,7 @@ export module Implementation {
505
518
  */
506
519
 
507
520
  let element: DQ = DQ.byId(form, true);
508
- if (!element.isTag(TAG_FORM)) {
521
+ if (!element.isTag(HTML_TAG_FORM)) {
509
522
  throw new Error(getMessage("ERR_VIEWSTATE"));
510
523
  }
511
524
 
@@ -524,7 +537,7 @@ export module Implementation {
524
537
  *
525
538
  * adds a new request to our queue for further processing
526
539
  */
527
- addRequestToQueue: function (elem: DQ, form: DQ, reqCtx: Config, respPassThr: Config, delay = 0, timeout = 0) {
540
+ addRequestToQueue: function (elem: DQ, form: DQ, reqCtx: ExtConfig, respPassThr: Config, delay = 0, timeout = 0) {
528
541
  requestQueue = requestQueue ?? new AsynchronousQueue<XhrRequest>();
529
542
  requestQueue.enqueue(new XhrRequest(elem, form, reqCtx, respPassThr, [], timeout), delay);
530
543
  }
@@ -546,7 +559,7 @@ export module Implementation {
546
559
  */
547
560
  function assignRender(requestOptions: Config, targetContext: Config, issuingForm: DQ, sourceElementId: string) {
548
561
  if (requestOptions.getIf(CTX_PARAM_RENDER).isPresent()) {
549
- remapDefaultConstants(targetContext.getIf(CTX_PARAM_PASS_THR).get({}), P_RENDER, <string>requestOptions.getIf(CTX_PARAM_RENDER).value, issuingForm, <any>sourceElementId);
562
+ remapDefaultConstants(targetContext.getIf(CTX_PARAM_REQ_PASS_THR).get({}), P_RENDER, <string>requestOptions.getIf(CTX_PARAM_RENDER).value, issuingForm, <any>sourceElementId, targetContext.getIf(VIEW_ID).value);
550
563
  }
551
564
  }
552
565
 
@@ -564,15 +577,15 @@ export module Implementation {
564
577
  */
565
578
  function assignExecute(requestOptions: Config, targetContext: Config, issuingForm: DQ, sourceElementId: string) {
566
579
 
567
- if (requestOptions.getIf(CTX_PARAM_EXECUTE).isPresent()) {
580
+ if (requestOptions.getIf(CTX_OPTIONS_EXECUTE).isPresent()) {
568
581
  /*the options must be a blank delimited list of strings*/
569
582
  /*compliance with Mojarra which automatically adds @this to an execute
570
583
  * the spec rev 2.0a however states, if none is issued nothing at all should be sent down
571
584
  */
572
- requestOptions.assign(CTX_PARAM_EXECUTE).value = [requestOptions.getIf(CTX_PARAM_EXECUTE).value, IDENT_THIS].join(" ");
573
- remapDefaultConstants(targetContext.getIf(CTX_PARAM_PASS_THR).get({}), P_EXECUTE, <string>requestOptions.getIf(CTX_PARAM_EXECUTE).value, issuingForm, <any>sourceElementId);
585
+ requestOptions.assign(CTX_OPTIONS_EXECUTE).value = [requestOptions.getIf(CTX_OPTIONS_EXECUTE).value, IDENT_THIS].join(" ");
586
+ remapDefaultConstants(targetContext.getIf(CTX_PARAM_REQ_PASS_THR).get({}), P_EXECUTE, <string>requestOptions.getIf(CTX_OPTIONS_EXECUTE).value, issuingForm, <any>sourceElementId, targetContext.getIf(VIEW_ID).value);
574
587
  } else {
575
- targetContext.assign(CTX_PARAM_PASS_THR, P_EXECUTE).value = sourceElementId;
588
+ targetContext.assign(CTX_PARAM_REQ_PASS_THR, P_EXECUTE).value = sourceElementId;
576
589
  }
577
590
  }
578
591
 
@@ -584,16 +597,16 @@ export module Implementation {
584
597
  */
585
598
  function assignClientWindowId(form: DQ, targetContext: Config) {
586
599
 
587
- let clientWindow = (window?.faces ?? window?.jsf).getClientWindow(form.getAsElem(0).value);
600
+ let clientWindow = $faces().getClientWindow(form.getAsElem(0).value);
588
601
  if (clientWindow) {
589
- targetContext.assign(CTX_PARAM_PASS_THR, P_CLIENT_WINDOW).value = clientWindow;
602
+ targetContext.assign(CTX_PARAM_REQ_PASS_THR, P_CLIENT_WINDOW).value = clientWindow;
590
603
  }
591
604
  }
592
605
 
593
606
  /**
594
607
  * transforms the user values to the expected one
595
608
  * with the proper none all form and this handling
596
- * (note we also could use a simple string replace but then
609
+ * (note we also could use a simple string replace, but then
597
610
  * we would have had double entries under some circumstances)
598
611
  *
599
612
  * there are several standardized constants which need a special treatment
@@ -604,14 +617,60 @@ export module Implementation {
604
617
  * @param userValues the passed user values (aka input string which needs to be transformed)
605
618
  * @param issuingForm the form where the issuing element originates
606
619
  * @param issuingElementId the issuing element
620
+ * @param rootNamingContainerId the naming container id ("" default if none is given)
607
621
  */
608
- function remapDefaultConstants(targetConfig: Config, targetKey: string, userValues: string, issuingForm: DQ, issuingElementId: string): Config {
622
+ function remapDefaultConstants(targetConfig: Config, targetKey: string, userValues: string, issuingForm: DQ, issuingElementId: string, rootNamingContainerId: string = ""): Config {
609
623
  //a cleaner implementation of the transform list method
610
-
624
+ const SEP = $faces().separatorchar;
611
625
  let iterValues: string[] = (userValues) ? trim(userValues).split(/\s+/gi) : [];
612
626
  let ret = [];
613
627
  let processed: {[key: string]: boolean} = {};
614
628
 
629
+ /**
630
+ * remaps the client ids for the portlet case so that the server
631
+ * can deal with them either prefixed ir not
632
+ * also resolves the absolute id case (it was assumed the server does this, but
633
+ * apparently the RI does not, so we have to follow the RI behavior here)
634
+ * @param componentIdToTransform the componentId which needs post processing
635
+ */
636
+ const remapNamingContainer = componentIdToTransform => {
637
+ // pattern :<anything> must be prepended by viewRoot if there is one,
638
+ // otherwise we are in a not namespaced then only the id has to match
639
+ const rootNamingContainerPrefix = (rootNamingContainerId.length) ? rootNamingContainerId+SEP : EMPTY_STR;
640
+ let formClientId = issuingForm.id.value;
641
+ // nearest parent naming container relative to the form
642
+ const nearestNamingContainer = formClientId.substring(0, formClientId.lastIndexOf(SEP));
643
+ const nearestNamingContainerPrefix = (nearestNamingContainer.length) ? nearestNamingContainer + SEP : EMPTY_STR;
644
+ // Absolute search expressions, always start with SEP or the name of the root naming container
645
+ const hasLeadingSep = componentIdToTransform.indexOf(SEP) === 0;
646
+ const isAbsolutSearchExpr = hasLeadingSep || (rootNamingContainerId.length
647
+ && componentIdToTransform.indexOf(rootNamingContainerPrefix) == 0);
648
+ let finalIdentifier = "";
649
+ if (isAbsolutSearchExpr) {
650
+ //we cut off the leading sep if there is one
651
+ componentIdToTransform = hasLeadingSep ? componentIdToTransform.substring(1) : componentIdToTransform;
652
+ componentIdToTransform = componentIdToTransform.indexOf(rootNamingContainerPrefix) == 0 ? componentIdToTransform.substring(rootNamingContainerPrefix.length) : componentIdToTransform;
653
+ //now we prepend either the prefix or "" from the cut-off string to get the final result
654
+ finalIdentifier = [rootNamingContainerPrefix, componentIdToTransform].join(EMPTY_STR);
655
+ } else { //relative search according to the javadoc
656
+ //we cut off the root naming container id from the form
657
+ if (formClientId.indexOf(rootNamingContainerPrefix) == 0) {
658
+ formClientId = formClientId.substring(rootNamingContainerPrefix.length);
659
+ }
660
+
661
+ //If prependId = true, the outer form id must be present in the id if same form
662
+ let hasPrependId = componentIdToTransform.indexOf(formClientId) == 0;
663
+ finalIdentifier = hasPrependId ?
664
+ [rootNamingContainerPrefix, componentIdToTransform].join(EMPTY_STR) :
665
+ [nearestNamingContainerPrefix, componentIdToTransform].join(EMPTY_STR);
666
+ }
667
+ // We need to double check because we have scenarios where we have a naming container
668
+ // and no prepend (aka tobago testcase "must handle ':' in IDs properly", scenario 3,
669
+ // in this case we return the component id, and be happy
670
+ // we can roll a dom check here
671
+ return (!!document.getElementById(finalIdentifier)) ? finalIdentifier : componentIdToTransform;
672
+ };
673
+
615
674
  // in this case we do not use lazy stream because it wont bring any code reduction
616
675
  // or speedup
617
676
  for (let cnt = 0; cnt < iterValues.length; cnt++) {
@@ -629,33 +688,39 @@ export module Implementation {
629
688
  return targetConfig;
630
689
  //@form pushes the issuing form id into our list
631
690
  case IDENT_FORM:
632
- ret.push(issuingForm.id.value);
691
+ ret.push(remapNamingContainer(issuingForm.id.value));
633
692
  processed[issuingForm.id.value] = true;
634
693
  break;
635
694
  //@this is replaced with the current issuing element id
636
695
  case IDENT_THIS:
637
696
  if (!(issuingElementId in processed)) {
638
- ret.push(issuingElementId);
697
+ ret.push(remapNamingContainer(issuingElementId));
639
698
  processed[issuingElementId] = true;
640
699
  }
641
700
  break;
642
701
  default:
643
- ret.push(iterValues[cnt]);
702
+ ret.push(remapNamingContainer(iterValues[cnt]));
644
703
  processed[iterValues[cnt]] = true;
645
704
  }
646
705
  }
647
- //We now add the target as joined list
706
+
648
707
  targetConfig.assign(targetKey).value = ret.join(" ");
649
708
  return targetConfig;
650
709
  }
651
710
 
652
711
  /**
653
712
  * Filter the options given with a blacklist, so that only
654
- * the values required for pass-through are processed in the ajax request
713
+ * the values required for params-through are processed in the ajax request
714
+ *
715
+ * Note this is a bug carried over from the old implementation
716
+ * the spec conform behavior is to use params for passthrough values
717
+ * this will be removed soon, after it is cleared up whether removing
718
+ * it breaks any legacy code
655
719
  *
656
720
  * @param {Context} mappedOpts the options to be filtered
721
+ * @deprecated
657
722
  */
658
- function filterPassThroughValues(mappedOpts: Context): Context {
723
+ function extractLegacyParams(mappedOpts: Options): Context {
659
724
  //we now can use the full code reduction given by our stream api
660
725
  //to filter
661
726
  return Stream.ofAssoc(mappedOpts)
@@ -663,6 +728,13 @@ export module Implementation {
663
728
  .collect(new AssocArrayCollector());
664
729
  }
665
730
 
731
+ function remapArrayToAssocArr(arrayedParams: [[string, any]] | {[key: string]: any}): {[key: string]: any} {
732
+ if(Array.isArray(arrayedParams)) {
733
+ return Stream.of(... arrayedParams).collect(new AssocArrayCollector());
734
+ }
735
+ return arrayedParams;
736
+ }
737
+
666
738
  function resolveGlobalConfig(): any {
667
739
  return window?.[MYFACES]?.config ?? {};
668
740
  }
@@ -17,9 +17,13 @@
17
17
  /*
18
18
  * [export const] constants
19
19
  */
20
+
21
+
20
22
  export const P_PARTIAL_SOURCE = "jakarta.faces.source";
21
23
  export const PARTIAL_ID = "partialId";
24
+ export const VIEW_ID = "myfaves.viewId";
22
25
  export const P_VIEWSTATE = "jakarta.faces.ViewState";
26
+ export const P_CLIENT_WINDOW = "jakarta.faces.ClientWindow";
23
27
  export const P_VIEWROOT = "jakarta.faces.ViewRoot";
24
28
  export const P_VIEWHEAD = "jakarta.faces.ViewHead";
25
29
  export const P_VIEWBODY = "jakarta.faces.ViewBody";
@@ -33,7 +37,8 @@ export const EMPTY_FUNC = Object.freeze(() => {
33
37
  export const EMPTY_STR = "";
34
38
  export const EMPTY_MAP = Object.freeze({});
35
39
 
36
- export const HTML_VIEWSTATE = ["<input type='hidden'", "id='", P_VIEWSTATE, "' name='", P_VIEWSTATE, "' value='' />"].join(EMPTY_STR);
40
+ export const HTML_VIEWSTATE = ["<input type='hidden'", "name='", P_VIEWSTATE, "' value='' />"].join(EMPTY_STR);
41
+ export const HTML_CLIENT_WINDOW = ["<input type='hidden'", "' name='", P_CLIENT_WINDOW, "' value='' />"].join(EMPTY_STR);
37
42
 
38
43
 
39
44
  /*internal identifiers for options*/
@@ -46,8 +51,10 @@ export const IDENT_FORM = "@form";
46
51
  export const P_AJAX = "jakarta.faces.partial.ajax";
47
52
  export const P_EXECUTE = "jakarta.faces.partial.execute";
48
53
  export const P_RENDER = "jakarta.faces.partial.render";
54
+ /*render override for viewbody or viewroot, in both cases an all is performed*/
55
+ export const P_RENDER_OVERRIDE = "_myfaces.rendeOverride";
49
56
  export const P_EVT = "jakarta.faces.partial.event";
50
- export const P_CLIENT_WINDOW = "jakarta.faces.ClientWindow";
57
+
51
58
  export const P_RESET_VALUES = "jakarta.faces.partial.resetValues";
52
59
  export const P_WINDOW_ID = "jakarta.faces.windowId";
53
60
 
@@ -87,19 +94,17 @@ export const SERVER_ERROR = "serverError";
87
94
  export const CLIENT_ERROR = "clientError";
88
95
  export const TIMEOUT_EVENT = "timeout";
89
96
 
90
- export const CTX_PARAM_MF_INTERNAL = "_mfInternal";
91
-
92
- export const CTX_PARAM_SRC_FRM_ID = "_mfSourceFormId";
93
- export const CTX_PARAM_SRC_CTL_ID = "_mfSourceControlId";
94
- export const CTX_PARAM_TR_TYPE = "_mfTransportType";
95
- export const CTX_PARAM_PASS_THR = "passThrgh";
96
- export const CTX_PARAM_DELAY = "delay";
97
- export const CTX_PARAM_TIMEOUT = "timeout";
98
- export const CTX_PARAM_RST = "resetValues";
99
- export const CTX_PARAM_EXECUTE = "execute";
100
-
101
- export const STAGE_DEVELOPMENT = "Development";
97
+ export const CTX_OPTIONS_PARAMS = "params";
98
+ export const CTX_OPTIONS_DELAY = "delay";
99
+ export const DELAY_NONE = 'none';
100
+ export const CTX_OPTIONS_TIMEOUT = "timeout";
101
+ export const CTX_OPTIONS_RESET = "resetValues";
102
+ export const CTX_OPTIONS_EXECUTE = "execute";
102
103
 
104
+ export const CTX_PARAM_MF_INTERNAL = "myfaces.internal";
105
+ export const CTX_PARAM_SRC_FRM_ID = "myfaces.source.formId";
106
+ export const CTX_PARAM_SRC_CTL_ID = "myfaces.source.controlId";
107
+ export const CTX_PARAM_REQ_PASS_THR = "myfaces.request.passThrough";
103
108
 
104
109
  export const CONTENT_TYPE = "Content-Type";
105
110
  export const HEAD_FACES_REQ = "Faces-Request";
@@ -116,13 +121,12 @@ export const MULTIPART = "multipart/form-data";
116
121
  export const NO_TIMEOUT = 0;
117
122
  export const STD_ACCEPT = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
118
123
 
119
- export const TAG_HEAD = "head";
120
- export const TAG_FORM = "form";
121
- export const TAG_BODY = "body";
122
- export const TAG_BEFORE = "before";
123
- export const TAG_AFTER = "after";
124
-
125
- export const TAG_ATTR = "attribute";
124
+ export const HTML_TAG_HEAD = "HEAD";
125
+ export const HTML_TAG_FORM = "FORM";
126
+ export const HTML_TAG_BODY = "BODY";
127
+ export const HTML_TAG_LINK = "LINK";
128
+ export const HTML_TAG_SCRIPT = "SCRIPT";
129
+ export const HTML_TAG_STYLE = "STYLE";
126
130
 
127
131
 
128
132
  export const SEL_VIEWSTATE_ELEM = "[name='" + P_VIEWSTATE + "']";
@@ -140,38 +144,40 @@ export const ATTR_VALUE = "value";
140
144
  export const ATTR_ID = "id";
141
145
 
142
146
  /*partial response types*/
143
- export const RESP_PARTIAL = "partial-response";
147
+ export const XML_TAG_PARTIAL_RESP = "partial-response";
144
148
 
145
149
  /*partial commands*/
146
- export const CMD_CHANGES = "changes";
147
- export const CMD_UPDATE = "update";
148
- export const CMD_DELETE = "delete";
149
- export const CMD_INSERT = "insert";
150
- export const CMD_EVAL = "eval";
151
- export const CMD_ERROR = "error";
152
- export const CMD_ATTRIBUTES = "attributes";
153
- export const CMD_EXTENSION = "extension";
154
- export const CMD_REDIRECT = "redirect";
150
+ export const XML_TAG_CHANGES = "changes";
151
+ export const XML_TAG_UPDATE = "update";
152
+ export const XML_TAG_DELETE = "delete";
153
+ export const XML_TAG_INSERT = "insert";
154
+ export const XML_TAG_EVAL = "eval";
155
+ export const XML_TAG_ERROR = "error";
156
+ export const XML_TAG_ATTRIBUTES = "attributes";
157
+ export const XML_TAG_EXTENSION = "extension";
158
+ export const XML_TAG_REDIRECT = "redirect";
159
+ export const XML_TAG_BEFORE = "before";
160
+ export const XML_TAG_AFTER = "after";
161
+ export const XML_TAG_ATTR = "attribute";
162
+
155
163
 
156
164
  /*other constants*/
157
165
 
158
- export const UPDATE_FORMS = "_updateForms";
159
- export const UPDATE_ELEMS = "_updateElems";
166
+ export const UPDATE_FORMS = "myfaces.updateForms";
167
+ export const UPDATE_ELEMS = "myfaces.updateElems";
160
168
 
161
169
  //we want the head elements to be processed before we process the body
162
170
  //but after the inner html is done
163
- export const DEFERRED_HEAD_INSERTS = "_headElems";
171
+ export const DEFERRED_HEAD_INSERTS = "myfaces.headElems";
164
172
 
165
173
  export const MYFACES = "myfaces";
166
174
 
167
- export const SEL_SCRIPTS_STYLES = "script, style, link";
168
-
169
175
  export const MF_NONE = "__mf_none__";
170
176
 
171
177
  export const REASON_EXPIRED = "Expired";
172
178
 
173
- export const APPLIED_VST = "appliedViewState";
174
- export const APPLIED_CLIENT_WINDOW = "appliedClientWindow";
179
+ export const APPLIED_VST = "myfaces.appliedViewState";
180
+ export const APPLIED_CLIENT_WINDOW = "myfaces.appliedClientWindow";
175
181
 
176
182
  export const RECONNECT_INTERVAL = 500;
177
183
  export const MAX_RECONNECT_ATTEMPTS = 25;
@@ -186,6 +192,10 @@ export const UNKNOWN = "UNKNOWN";
186
192
  * changed to a simple value passthrough
187
193
  */
188
194
 
195
+ export function $faces(): FacesAPI {
196
+ return (window?.faces ?? window?.jsf) as FacesAPI;
197
+ }
198
+
189
199
  export function $nsp(inputNamespace?: any): any {
190
200
  if((!inputNamespace) || !inputNamespace?.replace) {
191
201
  return inputNamespace;