jsf.js_next_gen 4.0.0-RC.1 → 4.0.0-RC.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/dist/docs/assets/main.js +1 -1
  2. package/dist/docs/functions/faces.push.init.html +5 -1
  3. package/dist/docs/functions/myfaces.ab.html +2 -2
  4. package/dist/window/faces-development.js +365 -136
  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.br +0 -0
  10. package/dist/window/faces.js.gz +0 -0
  11. package/dist/window/faces.js.map +1 -1
  12. package/dist/window/jsf-development.js +376 -136
  13. package/dist/window/jsf-development.js.br +0 -0
  14. package/dist/window/jsf-development.js.gz +0 -0
  15. package/dist/window/jsf-development.js.map +1 -1
  16. package/dist/window/jsf.js +1 -1
  17. package/dist/window/jsf.js.br +0 -0
  18. package/dist/window/jsf.js.gz +0 -0
  19. package/dist/window/jsf.js.map +1 -1
  20. package/package.json +11 -11
  21. package/src/main/typescript/@types/definitions/index.d.ts +17 -2
  22. package/src/main/typescript/api/_api.ts +4 -2
  23. package/src/main/typescript/api/jsf.ts +18 -0
  24. package/src/main/typescript/impl/AjaxImpl.ts +22 -2
  25. package/src/main/typescript/impl/PushImpl.ts +38 -12
  26. package/src/main/typescript/impl/core/Const.ts +9 -5
  27. package/src/main/typescript/impl/util/Assertions.ts +14 -6
  28. package/src/main/typescript/impl/util/AsyncQueue.ts +1 -1
  29. package/src/main/typescript/impl/util/ExtDomQuery.ts +4 -1
  30. package/src/main/typescript/impl/xhrCore/IResponseProcessor.ts +8 -1
  31. package/src/main/typescript/impl/xhrCore/RequestDataResolver.ts +13 -3
  32. package/src/main/typescript/impl/xhrCore/ResponseProcessor.ts +91 -29
  33. package/src/main/typescript/impl/xhrCore/XhrFormData.ts +24 -12
  34. package/src/main/typescript/myfaces/OamSubmit.ts +15 -10
  35. package/src/main/typescript/test/frameworkBase/_ext/shared/XmlResponses.ts +40 -1
  36. package/src/main/typescript/test/xhrCore/OamSubmitTest.spec.ts +177 -0
  37. package/src/main/typescript/test/xhrCore/RequestTest.spec.ts +237 -8
  38. package/src/main/typescript/test/xhrCore/ResponseTest.spec.ts +174 -10
  39. package/src/main/typescript/test/xhrCore/ResponseTest23.spec.ts +8 -6
  40. package/src/main/typescript/test.xml +6 -0
  41. package/target/api/_api.js +3 -2
  42. package/target/api/_api.js.map +1 -1
  43. package/target/api/jsf.js +11 -0
  44. package/target/api/jsf.js.map +1 -1
  45. package/target/impl/AjaxImpl.js +18 -0
  46. package/target/impl/AjaxImpl.js.map +1 -1
  47. package/target/impl/PushImpl.js +44 -14
  48. package/target/impl/PushImpl.js.map +1 -1
  49. package/target/impl/core/Const.js +10 -8
  50. package/target/impl/core/Const.js.map +1 -1
  51. package/target/impl/util/Assertions.js +11 -6
  52. package/target/impl/util/Assertions.js.map +1 -1
  53. package/target/impl/util/AsyncQueue.js.map +1 -1
  54. package/target/impl/util/ExtDomQuery.js +3 -0
  55. package/target/impl/util/ExtDomQuery.js.map +1 -1
  56. package/target/impl/xhrCore/RequestDataResolver.js +11 -2
  57. package/target/impl/xhrCore/RequestDataResolver.js.map +1 -1
  58. package/target/impl/xhrCore/ResponseProcessor.js +84 -23
  59. package/target/impl/xhrCore/ResponseProcessor.js.map +1 -1
  60. package/target/impl/xhrCore/XhrFormData.js +18 -7
  61. package/target/impl/xhrCore/XhrFormData.js.map +1 -1
  62. package/target/myfaces/OamSubmit.js +13 -11
  63. package/target/myfaces/OamSubmit.js.map +1 -1
  64. package/target/test/frameworkBase/_ext/shared/XmlResponses.js +37 -1
  65. package/target/test/frameworkBase/_ext/shared/XmlResponses.js.map +1 -1
  66. package/target/test/xhrCore/OamSubmitTest.spec.js +180 -0
  67. package/target/test/xhrCore/OamSubmitTest.spec.js.map +1 -0
  68. package/target/test/xhrCore/RequestTest.spec.js +214 -7
  69. package/target/test/xhrCore/RequestTest.spec.js.map +1 -1
  70. package/target/test/xhrCore/ResponseTest.spec.js +139 -8
  71. package/target/test/xhrCore/ResponseTest.spec.js.map +1 -1
  72. package/target/test/xhrCore/ResponseTest23.spec.js +5 -5
  73. package/target/test/xhrCore/ResponseTest23.spec.js.map +1 -1
  74. package/target/classes/com/example/jsfs_js_ts/DecoratedFacesJS.class +0 -0
  75. package/target/classes/com/example/jsfs_js_ts/DecoratingResourceHandlerWrapper.class +0 -0
  76. package/target/classes/com/example/jsfs_js_ts/FacesJSMapFileResourceWrapper.class +0 -0
  77. package/target/classes/com/example/jsfs_js_ts/FacesJSMappingDecorator.class +0 -0
  78. package/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +0 -4
  79. package/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +0 -4
  80. package/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst +0 -1
  81. package/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst +0 -1
  82. package/target/surefire-reports/TEST-com.example.jsfs_js_ts.JsfsJsTsApplicationTests.xml +0 -78
  83. package/target/surefire-reports/com.example.jsfs_js_ts.JsfsJsTsApplicationTests.txt +0 -7
  84. package/target/test-classes/.gz +0 -0
  85. package/target/test-classes/com/example/jsfs_js_ts/JsfsJsTsApplicationTests.class +0 -0
  86. package/target/test-classes/fileuploadtest.html +0 -24
  87. package/target/test-classes/jsf-development.js +0 -3559
  88. package/target/test-classes/jsf-development.js.br +0 -0
  89. package/target/test-classes/jsf-development.js.gz +0 -0
  90. package/target/test-classes/jsf-development.js.map +0 -1
  91. package/target/test-classes/jsf.js +0 -3
  92. package/target/test-classes/jsf.js.br +0 -0
  93. package/target/test-classes/jsf.js.gz +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsf.js_next_gen",
3
- "version": "4.0.0-RC.1",
3
+ "version": "4.0.0-RC.10",
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",
24
+ "@types/chai": "^4.3.4",
25
25
  "@types/mocha": "^10.0.0",
26
26
  "@types/node": "^18.11.9",
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": "^20.0.3",
34
34
  "jsdom-global": "^3.0.2",
35
35
  "mocha": "^10.1.0",
36
- "npm-check-updates": "^16.3.16",
36
+ "npm-check-updates": "^16.4.3",
37
37
  "nyc": "^15.1.0",
38
38
  "replace-in-file": "^6.3.5",
39
39
  "rxjs": "^7.5.7",
40
- "sinon": "^14.0.1",
40
+ "sinon": "^14.0.2",
41
41
  "terser-webpack-plugin": "^5.3.6",
42
42
  "ts-loader": "^9.4.1",
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.21",
45
+ "typescript": "^4.9.3",
46
+ "webpack": "^5.75.0",
47
+ "webpack-cli": "^5.0.0",
48
48
  "webpack-dev-server": "^4.11.1"
49
49
  },
50
50
  "dependencies": {
51
- "mona-dish": "0.23.5"
51
+ "mona-dish": "^0.23.8"
52
52
  }
53
53
  }
@@ -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 {
@@ -201,6 +201,7 @@ export module faces {
201
201
  * @param channel the channel name/id
202
202
  * @param onopen The function to be invoked when the web socket is opened.
203
203
  * @param onmessage The function to be invoked when a message is received.
204
+ * @param onerror The function to be invoked when an error occurs.
204
205
  * @param onclose The function to be invoked when the web socket is closed.
205
206
  * @param behaviors functions which are invoked whenever a message is received
206
207
  * @param autoConnect Whether or not to automatically open the socket. Defaults to <code>false</code>.
@@ -210,10 +211,11 @@ export module faces {
210
211
  channel: string,
211
212
  onopen: Function,
212
213
  onmessage: Function,
214
+ onerror: Function,
213
215
  onclose: Function,
214
216
  behaviors: any,
215
217
  autoConnect: boolean): void {
216
- PushImpl.init(socketClientId, url, channel, onopen, onmessage, onclose, behaviors, autoConnect);
218
+ PushImpl.init(socketClientId, url, channel, onopen, onmessage, onerror, onclose, behaviors, autoConnect);
217
219
  }
218
220
 
219
221
  /**
@@ -250,7 +252,7 @@ export module myfaces {
250
252
  * @param render
251
253
  * @param options
252
254
  */
253
- 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 {
254
256
  if (eventName) {
255
257
  options[$nsp(P_BEHAVIOR_EVENT)] = eventName;
256
258
  }
@@ -26,6 +26,24 @@ if(!window?.jsf) {
26
26
  (window as any)['jsf'] = window?.jsf ?? faces;
27
27
  window.jsf.specversion = 230000;
28
28
  delete window.jsf.contextpath;
29
+
30
+ let faces4Init = faces.push.init;
31
+ /*
32
+ * we shim back the breaking api change from 3.0 to 4.0
33
+ * onerror is gone
34
+ */
35
+ faces.push.init = (socketClientId: string,
36
+ url: string,
37
+ channel: string,
38
+ onopen: Function,
39
+ onmessage: Function,
40
+ // no on error api change for 4.0
41
+ //onerror: Function,
42
+ onclose: Function,
43
+ behaviors: any,
44
+ autoConnect: boolean) => {
45
+ faces4Init(socketClientId, url, channel, onopen, onmessage, null, onclose, behaviors, autoConnect);
46
+ }
29
47
  }
30
48
  if(!window?.myfaces?.ab) {
31
49
  const myfaces = require("./_api").myfaces;
@@ -50,7 +50,7 @@ import {
50
50
  CTX_PARAM_RENDER,
51
51
  REQ_TYPE_POST,
52
52
  SOURCE,
53
- TAG_FORM
53
+ TAG_FORM, CTX_PARAM_SPEC_PARAMS
54
54
  } from "./core/Const";
55
55
  import {
56
56
  resolveDefaults,
@@ -81,7 +81,9 @@ enum BlockFilter {
81
81
  myfaces = "myfaces",
82
82
  delay = "delay",
83
83
  timeout = "timeout",
84
- windowId = "windowId"
84
+ resetValues = "resetValues",
85
+ windowId = "windowId",
86
+ params = "params"
85
87
  }
86
88
 
87
89
  /**
@@ -267,7 +269,12 @@ export module Implementation {
267
269
 
268
270
  requestCtx.assignIf(!!windowId, P_WINDOW_ID).value = windowId;
269
271
 
272
+ // old non spec behavior will be removed after it is clear whether the removal breaks any code
270
273
  requestCtx.assign(CTX_PARAM_PASS_THR).value = filterPassThroughValues(options.value);
274
+
275
+ // spec conform behavior, all passthrough params must be under "passthrough
276
+ const params = remapArrayToAssocArr(options.getIf(CTX_PARAM_SPEC_PARAMS).orElse({}).value);
277
+ requestCtx.getIf(CTX_PARAM_PASS_THR).shallowMerge(new Config(params), true);
271
278
  requestCtx.assignIf(!!resolvedEvent, CTX_PARAM_PASS_THR, P_EVT).value = resolvedEvent?.type;
272
279
 
273
280
  /**
@@ -653,7 +660,13 @@ export module Implementation {
653
660
  * Filter the options given with a blacklist, so that only
654
661
  * the values required for pass-through are processed in the ajax request
655
662
  *
663
+ * Note this is a bug carried over from the old implementation
664
+ * the spec conform behavior is to use params for passthrough values
665
+ * this will be removed soon, after it is cleared up wheter removing
666
+ * it breaks any legacy code
667
+ *
656
668
  * @param {Context} mappedOpts the options to be filtered
669
+ * @deprecated
657
670
  */
658
671
  function filterPassThroughValues(mappedOpts: Context): Context {
659
672
  //we now can use the full code reduction given by our stream api
@@ -663,6 +676,13 @@ export module Implementation {
663
676
  .collect(new AssocArrayCollector());
664
677
  }
665
678
 
679
+ function remapArrayToAssocArr(arrayedParams: [[string, any]] | {[key: string]: any}): {[key: string]: any} {
680
+ if(Array.isArray(arrayedParams)) {
681
+ return Stream.of(... arrayedParams).collect(new AssocArrayCollector());
682
+ }
683
+ return arrayedParams;
684
+ }
685
+
666
686
  function resolveGlobalConfig(): any {
667
687
  return window?.[MYFACES]?.config ?? {};
668
688
  }
@@ -18,13 +18,14 @@
18
18
  * Typescript port of the faces\.push part in the myfaces implementation
19
19
  */
20
20
  import {MAX_RECONNECT_ATTEMPTS, REASON_EXPIRED, RECONNECT_INTERVAL} from "./core/Const";
21
+ import {DQ} from "mona-dish";
21
22
 
22
23
  /**
23
24
  * Implementation class for the push functionality
24
25
  */
25
26
  export module PushImpl {
26
27
 
27
- const URL_PROTOCOL = window.location.protocol.replace("http", "ws") + "//";
28
+ const URL_PROTOCOL = DQ.global().location.protocol.replace("http", "ws") + "//";
28
29
 
29
30
 
30
31
  // we expose the member variables for testing purposes
@@ -55,6 +56,7 @@ export module PushImpl {
55
56
  * @param channel the channel name/id
56
57
  * @param onopen The function to be invoked when the web socket is opened.
57
58
  * @param onmessage The function to be invoked when a message is received.
59
+ * @param onerror The function to be invoked when an error occurs.
58
60
  * @param onclose The function to be invoked when the web socket is closed.
59
61
  * @param behaviors functions which are invoked whenever a message is received
60
62
  * @param autoConnect Whether or not to automatically open the socket. Defaults to <code>false</code>.
@@ -64,12 +66,13 @@ export module PushImpl {
64
66
  channel: string,
65
67
  onopen: Function,
66
68
  onmessage: Function,
69
+ onerror: Function,
67
70
  onclose: Function,
68
71
  behaviors: any,
69
72
  autoConnect: boolean) {
70
73
  onclose = resolveFunction(onclose);
71
74
 
72
- if (!window.WebSocket) { // IE6-9.
75
+ if (!DQ.global().WebSocket) { // IE6-9.
73
76
  onclose(-1, channel);
74
77
  return;
75
78
  }
@@ -81,6 +84,7 @@ export module PushImpl {
81
84
  'channelToken': channelToken,
82
85
  'onopen': resolveFunction(onopen),
83
86
  'onmessage' : resolveFunction(onmessage),
87
+ 'onerror' : resolveFunction(onerror),
84
88
  'onclose': onclose,
85
89
  'behaviors': behaviors,
86
90
  'autoconnect': autoConnect};
@@ -95,16 +99,16 @@ export module PushImpl {
95
99
  }
96
100
 
97
101
  if (autoConnect) {
98
- (window?.faces ?? window?.jsf).push.open(socketClientId);
102
+ (DQ.global()?.faces ?? DQ.global()?.jsf).push.open(socketClientId);
99
103
  }
100
104
  }
101
105
 
102
106
  export function open(socketClientId: string) {
103
- getSocket(components?.[socketClientId]?.channelToken).open();
107
+ getSocket(components[socketClientId]?.channelToken).open();
104
108
  }
105
109
 
106
110
  export function close(socketClientId: string) {
107
- getSocket(components?.[socketClientId].channelToken).close();
111
+ getSocket(components[socketClientId].channelToken).close();
108
112
  }
109
113
 
110
114
  // Private helper classes
@@ -142,24 +146,45 @@ export module PushImpl {
142
146
  let clientIds = clientIdsByTokens[this.channelToken];
143
147
  for (let i = clientIds.length - 1; i >= 0; i--) {
144
148
  let socketClientId = clientIds[i];
145
- components[socketClientId]['onopen'](this.channel);
149
+ components[socketClientId]?.['onopen']?.(this.channel);
146
150
  }
147
151
  }
148
152
  this.reconnectAttempts = 0;
149
153
  }
150
154
 
155
+ onerror(event: any) {
156
+ let message = JSON.parse(event.data);
157
+ //TODO replace this with a more readable Stream code
158
+ for (let i = clientIdsByTokens[this.channelToken].length - 1; i >= 0; i--) {
159
+ let socketClientId = clientIdsByTokens[this.channelToken][i];
160
+ if (document.getElementById(socketClientId)) {
161
+ try {
162
+ components[socketClientId]?.['onerror']?.(message, this.channel, event);
163
+ } catch (e) {
164
+ //Ignore
165
+ }
166
+ } else {
167
+ clientIdsByTokens[this.channelToken].splice(i, 1);
168
+ }
169
+ }
170
+ if (clientIdsByTokens[this.channelToken].length == 0) {
171
+ // tag disappeared
172
+ this.close();
173
+ }
174
+ }
175
+
151
176
  onmmessage(event: any) {
152
177
  let message = JSON.parse(event.data);
153
178
  for (let i = clientIdsByTokens[this.channelToken].length - 1; i >= 0; i--) {
154
179
  let socketClientId = clientIdsByTokens[this.channelToken][i];
155
180
  if (document.getElementById(socketClientId)) {
156
181
  try {
157
- components[socketClientId]['onmessage'](message, this.channel, event);
182
+ components[socketClientId]?.['onmessage']?.(message, this.channel, event);
158
183
  } catch (e) {
159
184
  //Ignore
160
185
  }
161
- let behaviors = components[socketClientId]['behaviors'];
162
- let functions = behaviors[message];
186
+ let behaviors = components?.[socketClientId]?.['behaviors'];
187
+ let functions = behaviors?.[message];
163
188
  if (functions && functions.length) {
164
189
  for (let j = 0; j < functions.length; j++) {
165
190
  try {
@@ -188,7 +213,7 @@ export module PushImpl {
188
213
  let clientIds = clientIdsByTokens[this.channelToken];
189
214
  for (let i = clientIds.length - 1; i >= 0; i--) {
190
215
  let socketClientId = clientIds[i];
191
- components[socketClientId]['onclose'](event?.code, this?.channel, event);
216
+ components?.[socketClientId]?.['onclose']?.(event?.code, this?.channel, event);
192
217
  }
193
218
  } else {
194
219
  setTimeout(this.open, RECONNECT_INTERVAL * this.reconnectAttempts++);
@@ -210,6 +235,7 @@ export module PushImpl {
210
235
  this.socket.onopen = (event: Event) => this.onopen(event);
211
236
  this.socket.onmessage = (event: Event) => this.onmmessage(event);
212
237
  this.socket.onclose = (event: Event) => this.onclose(event);
238
+ this.socket.onerror = (event: Event) => this.onerror(event);
213
239
  }
214
240
  }
215
241
 
@@ -217,7 +243,7 @@ export module PushImpl {
217
243
 
218
244
  function getBaseURL(url: string) {
219
245
  if (url.indexOf("://") < 0) {
220
- let base = window.location.hostname + ":" + window.location.port;
246
+ let base = DQ.global().location.hostname + ":" + DQ.global().location.port;
221
247
  return URL_PROTOCOL + base + url;
222
248
  } else {
223
249
  return url;
@@ -242,7 +268,7 @@ export module PushImpl {
242
268
 
243
269
  function resolveFunction(fn: Function | string = () => {
244
270
  }): Function {
245
- return <Function>((typeof fn !== "function") && (fn = window[fn]), fn);
271
+ return <Function>((typeof fn !== "function") && (fn = DQ.global()[fn]), fn);
246
272
  }
247
273
 
248
274
  }
@@ -20,6 +20,7 @@
20
20
  export const P_PARTIAL_SOURCE = "jakarta.faces.source";
21
21
  export const PARTIAL_ID = "partialId";
22
22
  export const P_VIEWSTATE = "jakarta.faces.ViewState";
23
+ export const P_CLIENT_WINDOW = "jakarta.faces.ClientWindow";
23
24
  export const P_VIEWROOT = "jakarta.faces.ViewRoot";
24
25
  export const P_VIEWHEAD = "jakarta.faces.ViewHead";
25
26
  export const P_VIEWBODY = "jakarta.faces.ViewBody";
@@ -33,7 +34,8 @@ export const EMPTY_FUNC = Object.freeze(() => {
33
34
  export const EMPTY_STR = "";
34
35
  export const EMPTY_MAP = Object.freeze({});
35
36
 
36
- export const HTML_VIEWSTATE = ["<input type='hidden'", "id='", P_VIEWSTATE, "' name='", P_VIEWSTATE, "' value='' />"].join(EMPTY_STR);
37
+ export const HTML_VIEWSTATE = ["<input type='hidden'", "name='", P_VIEWSTATE, "' value='' />"].join(EMPTY_STR);
38
+ export const HTML_CLIENT_WINDOW = ["<input type='hidden'", "' name='", P_CLIENT_WINDOW, "' value='' />"].join(EMPTY_STR);
37
39
 
38
40
 
39
41
  /*internal identifiers for options*/
@@ -47,7 +49,7 @@ export const P_AJAX = "jakarta.faces.partial.ajax";
47
49
  export const P_EXECUTE = "jakarta.faces.partial.execute";
48
50
  export const P_RENDER = "jakarta.faces.partial.render";
49
51
  export const P_EVT = "jakarta.faces.partial.event";
50
- export const P_CLIENT_WINDOW = "jakarta.faces.ClientWindow";
52
+
51
53
  export const P_RESET_VALUES = "jakarta.faces.partial.resetValues";
52
54
  export const P_WINDOW_ID = "jakarta.faces.windowId";
53
55
 
@@ -93,6 +95,8 @@ export const CTX_PARAM_SRC_FRM_ID = "_mfSourceFormId";
93
95
  export const CTX_PARAM_SRC_CTL_ID = "_mfSourceControlId";
94
96
  export const CTX_PARAM_TR_TYPE = "_mfTransportType";
95
97
  export const CTX_PARAM_PASS_THR = "passThrgh";
98
+ export const CTX_PARAM_SPEC_PARAMS = "params";
99
+
96
100
  export const CTX_PARAM_DELAY = "delay";
97
101
  export const CTX_PARAM_TIMEOUT = "timeout";
98
102
  export const CTX_PARAM_RST = "resetValues";
@@ -116,9 +120,9 @@ export const MULTIPART = "multipart/form-data";
116
120
  export const NO_TIMEOUT = 0;
117
121
  export const STD_ACCEPT = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
118
122
 
119
- export const TAG_HEAD = "head";
120
- export const TAG_FORM = "form";
121
- export const TAG_BODY = "body";
123
+ export const TAG_HEAD = "HEAD";
124
+ export const TAG_FORM = "FORM";
125
+ export const TAG_BODY = "BODY";
122
126
  export const TAG_BEFORE = "before";
123
127
  export const TAG_AFTER = "after";
124
128
 
@@ -16,9 +16,6 @@
16
16
  import {Config, Lang, XMLQuery} from "mona-dish";
17
17
 
18
18
  import {DQ} from "mona-dish";
19
- import {ExtLang} from "./Lang";
20
- import getMessage = ExtLang.getMessage;
21
- import makeException = ExtLang.makeException;
22
19
  import {
23
20
  ATTR_URL,
24
21
  EMPTY_RESPONSE,
@@ -28,6 +25,8 @@ import {
28
25
  PHASE_PROCESS_RESPONSE,
29
26
  RESP_PARTIAL
30
27
  } from "../core/Const";
28
+ import {ExtLang} from "./Lang";
29
+
31
30
 
32
31
  /**
33
32
  * a set of internal code assertions
@@ -36,6 +35,8 @@ import {
36
35
  */
37
36
  export module Assertions {
38
37
 
38
+
39
+
39
40
  export function assertRequestIntegrity(options: Config, elem: DQ): void | never {
40
41
  /*assert if the onerror is set and once if it is set it must be of type function*/
41
42
  assertFunction(options.getIf(ON_ERROR).value);
@@ -43,12 +44,12 @@ export module Assertions {
43
44
  assertFunction(options.getIf(ON_EVENT).value);
44
45
  //improve the error messages if an empty elem is passed
45
46
  //Assertions.assertElementExists(elem);
46
- assert(elem.isPresent(), getMessage("ERR_MUST_BE_PROVIDED1", "{0}: source must be provided or exist", "source element id"), "faces.ajax.request", "ArgNotSet", )
47
+ assert(elem.isPresent(), ExtLang.getMessage("ERR_MUST_BE_PROVIDED1", "{0}: source must be provided or exist", "source element id"), "faces.ajax.request", "ArgNotSet", )
47
48
  }
48
49
 
49
50
  export function assertUrlExists(node: XMLQuery): void | never {
50
51
  if (node.attr(ATTR_URL).isAbsent()) {
51
- throw Assertions.raiseError(new Error(), getMessage("ERR_RED_URL", null, "processRedirect"), "processRedirect");
52
+ throw Assertions.raiseError(new Error(), ExtLang.getMessage("ERR_RED_URL", null, "processRedirect"), "processRedirect");
52
53
  }
53
54
  }
54
55
 
@@ -79,7 +80,7 @@ export module Assertions {
79
80
  let finalMessage = message ?? EMPTY_STR;
80
81
 
81
82
  //TODO clean up the messy makeException, this is a perfect case for encapsulation and sane defaults
82
- return makeException(error, finalTitle, finalName, "Response", caller || (((<any>arguments).caller) ? (<any>arguments).caller.toString() : "_raiseError"), finalMessage);
83
+ return ExtLang.makeException(error, finalTitle, finalName, "Response", caller || (((<any>arguments).caller) ? (<any>arguments).caller.toString() : "_raiseError"), finalMessage);
83
84
  }
84
85
 
85
86
  /*
@@ -103,6 +104,13 @@ export module Assertions {
103
104
  export function assertFunction(value: any, msg = EMPTY_STR, caller=EMPTY_STR, title="Assertion Error"): asserts value is Function {
104
105
  assertType(value, "function", msg, caller, title);
105
106
  }
107
+
108
+ export function assertDelay(value: any) {
109
+ if(!(value >= 0)) { // >= 0 abbreviation which covers all cases of non positive values,
110
+ // including NaN and non numeric strings, no type equality is deliberate here,
111
+ throw new Error("Invalid delay value: " + value);
112
+ }
113
+ }
106
114
  }
107
115
 
108
116
 
@@ -58,7 +58,7 @@ export class AsynchronousQueue<T extends AsyncRunnable<any>> {
58
58
  if (delay) {
59
59
  this.delayTimeout = setTimeout(() => {
60
60
  this.appendElement(element);
61
- });
61
+ }) as any;
62
62
  } else {
63
63
  this.appendElement(element);
64
64
  }
@@ -235,7 +235,7 @@ export class ExtDomQuery extends DQ {
235
235
  * @param deep whether the search should go into embedded shadow dom elements
236
236
  * @return a DomQuery containing the found elements
237
237
  */
238
- static byId(selector: string | DomQuery | Element, deep = false): DomQuery {
238
+ static byId(selector: string | DomQuery | Element, deep = false): ExtDomQuery {
239
239
  const ret = DomQuery.byId(selector, deep);
240
240
  return new ExtDomQuery(ret);
241
241
  }
@@ -244,6 +244,9 @@ export class ExtDomQuery extends DQ {
244
244
  return (curScript.getAsElem(0).value as HTMLElement)?.nonce ?? curScript.attr("nonce").value;
245
245
  }
246
246
 
247
+ filter(func: (item: DomQuery) => boolean): ExtDomQuery {
248
+ return new ExtDomQuery(super.filter(func));
249
+ }
247
250
  }
248
251
 
249
252
  export const ExtDQ = ExtDomQuery;
@@ -32,7 +32,6 @@ export interface IResponseProcessor {
32
32
  */
33
33
  replaceHead(shadowHead: XMLQuery | DQ): void;
34
34
 
35
-
36
35
  /**
37
36
  * adds new elements to the head
38
37
  *
@@ -40,6 +39,14 @@ export interface IResponseProcessor {
40
39
  */
41
40
  addToHead(newElements: XMLQuery | DQ): void;
42
41
 
42
+
43
+ /**
44
+ * adds new elements to the head in a deferred manner
45
+ *
46
+ * @param newElements the elements which need addition
47
+ */
48
+ addToHeadDeferred(newElements: XMLQuery | DQ): void;
49
+
43
50
  /**
44
51
  * replace the body
45
52
  *
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import {Config, DomQuery, DQ} from "mona-dish";
17
+ import {AssocArrayCollector, Config, DomQuery, DQ, Stream} from "mona-dish";
18
18
  import {
19
19
  CTX_PARAM_DELAY,
20
20
  CTX_PARAM_TIMEOUT,
@@ -28,6 +28,8 @@ import {
28
28
  import {XhrFormData} from "./XhrFormData";
29
29
  import {ExtLang} from "../util/Lang";
30
30
  import {ExtConfig, ExtDomQuery} from "../util/ExtDomQuery";
31
+ import {Assertions} from "../util/Assertions";
32
+
31
33
 
32
34
  /**
33
35
  * Resolver functions for various aspects of the request data
@@ -91,7 +93,15 @@ export function resolveTimeout(options: Config): number {
91
93
  export function resolveDelay(options: Config): number {
92
94
  let getCfg = ExtLang.getLocalOrGlobalConfig;
93
95
 
94
- return options.getIf(CTX_PARAM_DELAY).value ?? getCfg(options.value, CTX_PARAM_DELAY, 0);
96
+ // null or non undefined will automatically be mapped to 0 aka no delay
97
+ let ret = options.getIf(CTX_PARAM_DELAY).value ?? getCfg(options.value, CTX_PARAM_DELAY, 0);
98
+ // if delay === none, no delay must be used, aka delay 0
99
+ if('none' === ret) {
100
+ ret = 0;
101
+ }
102
+ // negative, or invalid values will automatically get a js exception
103
+ Assertions.assertDelay(ret);
104
+ return ret;
95
105
  }
96
106
 
97
107
  /**
@@ -138,7 +148,7 @@ export function getEventTarget(evt: Event): Element {
138
148
  * @param opts
139
149
  * @param el
140
150
  */
141
- export function resolveDefaults(event: Event, opts: any = {}, el: Element | string = null) {
151
+ export function resolveDefaults(event: Event, opts: Options | [[string, any]] , el: Element | string = null) {
142
152
  //deep copy the options, so that further transformations to not backfire into the callers
143
153
  const resolvedEvent = event,
144
154
  options = new ExtConfig(opts).deepCopy,