jsf.js_next_gen 4.0.0-beta-23 → 4.0.0

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 (200) hide show
  1. package/.nyc_output/09ca9ebc-2305-4357-8db9-48ddfc7dfde2.json +1 -0
  2. package/.nyc_output/7c496a14-166e-4aa5-85b9-47b22b055ad8.json +1 -0
  3. package/.nyc_output/processinfo/09ca9ebc-2305-4357-8db9-48ddfc7dfde2.json +1 -0
  4. package/.nyc_output/processinfo/7c496a14-166e-4aa5-85b9-47b22b055ad8.json +1 -0
  5. package/.nyc_output/processinfo/index.json +1 -1
  6. package/README.md +7 -22
  7. package/dist/docs/assets/main.js +56 -52
  8. package/dist/docs/assets/search.js +1 -1
  9. package/dist/docs/assets/style.css +23 -0
  10. package/dist/docs/functions/faces.ajax.addOnError.html +6 -4
  11. package/dist/docs/functions/faces.ajax.addOnEvent.html +2 -0
  12. package/dist/docs/functions/faces.ajax.request.html +7 -7
  13. package/dist/docs/functions/faces.ajax.response.html +0 -1
  14. package/dist/docs/functions/faces.push.close.html +4 -2
  15. package/dist/docs/functions/faces.push.init.html +19 -7
  16. package/dist/docs/functions/faces.push.open.html +4 -2
  17. package/dist/docs/functions/faces.util.chain.html +3 -3
  18. package/dist/docs/functions/myfaces.ab.html +9 -4
  19. package/dist/docs/functions/myfaces.onOnDomReady.html +72 -0
  20. package/dist/docs/index.html +7 -18
  21. package/dist/docs/modules/myfaces.html +3 -1
  22. package/dist/docs/variables/myfaces.oam.html +2 -1
  23. package/dist/window/faces-development.js +2147 -1779
  24. package/dist/window/faces-development.js.br +0 -0
  25. package/dist/window/faces-development.js.gz +0 -0
  26. package/dist/window/faces-development.js.map +1 -1
  27. package/dist/window/faces.js +1 -1
  28. package/dist/window/faces.js.LICENSE.txt +17 -2
  29. package/dist/window/faces.js.br +0 -0
  30. package/dist/window/faces.js.gz +0 -0
  31. package/dist/window/faces.js.map +1 -1
  32. package/dist/window/jsf-development.js +2156 -1777
  33. package/dist/window/jsf-development.js.br +0 -0
  34. package/dist/window/jsf-development.js.gz +0 -0
  35. package/dist/window/jsf-development.js.map +1 -1
  36. package/dist/window/jsf.js +1 -1
  37. package/dist/window/jsf.js.LICENSE.txt +17 -2
  38. package/dist/window/jsf.js.br +0 -0
  39. package/dist/window/jsf.js.gz +0 -0
  40. package/dist/window/jsf.js.map +1 -1
  41. package/package.json +19 -18
  42. package/pom.xml +1 -1
  43. package/src/main/test.xml +23 -0
  44. package/src/main/typescript/@types/definitions/index.d.ts +24 -7
  45. package/src/main/typescript/api/_api.ts +79 -37
  46. package/src/main/typescript/api/jsf.ts +18 -0
  47. package/src/main/typescript/impl/AjaxImpl.ts +168 -78
  48. package/src/main/typescript/impl/PushImpl.ts +63 -38
  49. package/src/main/typescript/impl/core/Const.ts +52 -39
  50. package/src/main/typescript/impl/util/Assertions.ts +16 -8
  51. package/src/main/typescript/impl/util/AsyncQueue.ts +1 -1
  52. package/src/main/typescript/impl/util/AsyncRunnable.ts +4 -4
  53. package/src/main/typescript/impl/util/ExtDomQuery.ts +58 -45
  54. package/src/main/typescript/impl/util/FileUtils.ts +104 -0
  55. package/src/main/typescript/impl/util/HiddenInputBuilder.ts +89 -0
  56. package/src/main/typescript/impl/util/Lang.ts +30 -31
  57. package/src/main/typescript/impl/xhrCore/ErrorData.ts +15 -10
  58. package/src/main/typescript/impl/xhrCore/EventData.ts +2 -2
  59. package/src/main/typescript/impl/xhrCore/IResponseProcessor.ts +25 -11
  60. package/src/main/typescript/impl/xhrCore/RequestDataResolver.ts +78 -32
  61. package/src/main/typescript/impl/xhrCore/ResonseDataResolver.ts +10 -10
  62. package/src/main/typescript/impl/xhrCore/Response.ts +66 -49
  63. package/src/main/typescript/impl/xhrCore/ResponseProcessor.ts +202 -131
  64. package/src/main/typescript/impl/xhrCore/XhrFormData.ts +79 -166
  65. package/src/main/typescript/impl/xhrCore/XhrRequest.ts +80 -68
  66. package/src/main/typescript/myfaces/OamSubmit.ts +29 -13
  67. package/src/main/typescript/test/frameworkBase/_ext/monadish/DomQueryTest.spec.ts +19 -22
  68. package/src/main/typescript/test/frameworkBase/_ext/shared/StandardInits.ts +108 -1
  69. package/src/main/typescript/test/frameworkBase/_ext/shared/XmlResponses.ts +40 -1
  70. package/src/main/typescript/test/impl/ImplTest.spec.ts +3 -3
  71. package/src/main/typescript/test/impl/ImplTest_23.spec.ts +3 -7
  72. package/src/main/typescript/test/xhrCore/EventTests.spec.ts +1 -1
  73. package/src/main/typescript/test/xhrCore/FileUploadTest.spec.ts +5 -2
  74. package/src/main/typescript/test/xhrCore/NamespacesRequestTest.spec.ts +203 -0
  75. package/src/main/typescript/test/xhrCore/OamSubmitTest.spec.ts +177 -0
  76. package/src/main/typescript/test/xhrCore/RequestParamsTest.spec.ts +158 -17
  77. package/src/main/typescript/test/xhrCore/RequestTest.spec.ts +242 -11
  78. package/src/main/typescript/test/xhrCore/RequestTest_23.spec.ts +39 -3
  79. package/src/main/typescript/test/xhrCore/ResponseTest.spec.ts +373 -35
  80. package/src/main/typescript/test/xhrCore/ResponseTest23.spec.ts +43 -9
  81. package/src/main/typescript/test/xhrCore/TobagoFileUploadTest.spec.ts +109 -0
  82. package/src/main/typescript/test/xhrCore/XhrFormDataTest.spec.ts +67 -49
  83. package/src/main/typescript/test.xml +6 -0
  84. package/src/main/typescript/tsconfig.json +1 -1
  85. package/src/test/resources/jsf-development.js +1 -1
  86. package/src/tmp/test.html +12 -88
  87. package/target/api/_api.js +72 -31
  88. package/target/api/_api.js.map +1 -1
  89. package/target/api/jsf.js +11 -0
  90. package/target/api/jsf.js.map +1 -1
  91. package/target/classes/com/example/jsfs_js_ts/DecoratedFacesJS.class +0 -0
  92. package/target/classes/com/example/jsfs_js_ts/DecoratingResourceHandlerWrapper.class +0 -0
  93. package/target/classes/com/example/jsfs_js_ts/FacesJSMapFileResourceWrapper.class +0 -0
  94. package/target/classes/com/example/jsfs_js_ts/FacesJSMappingDecorator.class +0 -0
  95. package/target/impl/AjaxImpl.js +144 -59
  96. package/target/impl/AjaxImpl.js.map +1 -1
  97. package/target/impl/PushImpl.js +66 -35
  98. package/target/impl/PushImpl.js.map +1 -1
  99. package/target/impl/core/Const.js +51 -38
  100. package/target/impl/core/Const.js.map +1 -1
  101. package/target/impl/core/Context.js +10 -0
  102. package/target/impl/core/Context.js.map +1 -0
  103. package/target/impl/util/Assertions.js +12 -7
  104. package/target/impl/util/Assertions.js.map +1 -1
  105. package/target/impl/util/AsyncQueue.js.map +1 -1
  106. package/target/impl/util/ExtDomQuery.js +58 -40
  107. package/target/impl/util/ExtDomQuery.js.map +1 -1
  108. package/target/impl/util/FileUtils.js +96 -0
  109. package/target/impl/util/FileUtils.js.map +1 -0
  110. package/target/impl/util/HiddenElementBuilder.js +7 -0
  111. package/target/impl/util/HiddenElementBuilder.js.map +1 -0
  112. package/target/impl/util/HiddenInputBuilder.js +79 -0
  113. package/target/impl/util/HiddenInputBuilder.js.map +1 -0
  114. package/target/impl/util/Lang.js +29 -30
  115. package/target/impl/util/Lang.js.map +1 -1
  116. package/target/impl/util/URLCodec.js +77 -0
  117. package/target/impl/util/URLCodec.js.map +1 -0
  118. package/target/impl/util/XhrQueueController.js +82 -0
  119. package/target/impl/util/XhrQueueController.js.map +1 -0
  120. package/target/impl/xhrCore/ErrorData.js +10 -8
  121. package/target/impl/xhrCore/ErrorData.js.map +1 -1
  122. package/target/impl/xhrCore/EventData.js +1 -1
  123. package/target/impl/xhrCore/EventData.js.map +1 -1
  124. package/target/impl/xhrCore/RequestContext.js +11 -0
  125. package/target/impl/xhrCore/RequestContext.js.map +1 -0
  126. package/target/impl/xhrCore/RequestDataResolver.js +70 -23
  127. package/target/impl/xhrCore/RequestDataResolver.js.map +1 -1
  128. package/target/impl/xhrCore/ResonseDataResolver.js +9 -9
  129. package/target/impl/xhrCore/ResonseDataResolver.js.map +1 -1
  130. package/target/impl/xhrCore/Response.js +44 -29
  131. package/target/impl/xhrCore/Response.js.map +1 -1
  132. package/target/impl/xhrCore/ResponseProcessor.js +182 -116
  133. package/target/impl/xhrCore/ResponseProcessor.js.map +1 -1
  134. package/target/impl/xhrCore/XhrFormData.js +68 -156
  135. package/target/impl/xhrCore/XhrFormData.js.map +1 -1
  136. package/target/impl/xhrCore/XhrQueHandler.js +11 -0
  137. package/target/impl/xhrCore/XhrQueHandler.js.map +1 -0
  138. package/target/impl/xhrCore/XhrQueueController.js +62 -0
  139. package/target/impl/xhrCore/XhrQueueController.js.map +1 -0
  140. package/target/impl/xhrCore/XhrRequest.js +68 -59
  141. package/target/impl/xhrCore/XhrRequest.js.map +1 -1
  142. package/target/myfaces/OamSubmit.js +23 -14
  143. package/target/myfaces/OamSubmit.js.map +1 -1
  144. package/target/test/frameworkBase/_ext/monadish/DomQueryTest.spec.js +16 -16
  145. package/target/test/frameworkBase/_ext/monadish/DomQueryTest.spec.js.map +1 -1
  146. package/target/test/frameworkBase/_ext/monadish/ExtendedArrayTest.spec.js +76 -0
  147. package/target/test/frameworkBase/_ext/monadish/ExtendedArrayTest.spec.js.map +1 -0
  148. package/target/test/frameworkBase/_ext/monadish/markups/tobago-with-header.js +925 -0
  149. package/target/test/frameworkBase/_ext/monadish/markups/tobago-with-header.js.map +1 -0
  150. package/target/test/frameworkBase/_ext/monadish/markups/tobago-without-header.js +112 -0
  151. package/target/test/frameworkBase/_ext/monadish/markups/tobago-without-header.js.map +1 -0
  152. package/target/test/frameworkBase/_ext/shared/StandardInits.js +100 -1
  153. package/target/test/frameworkBase/_ext/shared/StandardInits.js.map +1 -1
  154. package/target/test/frameworkBase/_ext/shared/XmlResponses.js +37 -1
  155. package/target/test/frameworkBase/_ext/shared/XmlResponses.js.map +1 -1
  156. package/target/test/impl/ImplTest.spec.js +2 -2
  157. package/target/test/impl/ImplTest.spec.js.map +1 -1
  158. package/target/test/impl/ImplTest_23.spec.js +2 -2
  159. package/target/test/impl/ImplTest_23.spec.js.map +1 -1
  160. package/target/test/myfaces/OnLoadSpec.js +57 -0
  161. package/target/test/myfaces/OnLoadSpec.js.map +1 -0
  162. package/target/test/xhrCore/EventTests.spec.js +1 -1
  163. package/target/test/xhrCore/EventTests.spec.js.map +1 -1
  164. package/target/test/xhrCore/FileUploadTest.spec.js +2 -1
  165. package/target/test/xhrCore/FileUploadTest.spec.js.map +1 -1
  166. package/target/test/xhrCore/NamespacesRequestTest.spec.js +204 -0
  167. package/target/test/xhrCore/NamespacesRequestTest.spec.js.map +1 -0
  168. package/target/test/xhrCore/OamSubmitTest.spec.js +180 -0
  169. package/target/test/xhrCore/OamSubmitTest.spec.js.map +1 -0
  170. package/target/test/xhrCore/RequestParamsTest.spec.js +142 -10
  171. package/target/test/xhrCore/RequestParamsTest.spec.js.map +1 -1
  172. package/target/test/xhrCore/RequestTest.spec.js +217 -9
  173. package/target/test/xhrCore/RequestTest.spec.js.map +1 -1
  174. package/target/test/xhrCore/RequestTest_23.spec.js +34 -2
  175. package/target/test/xhrCore/RequestTest_23.spec.js.map +1 -1
  176. package/target/test/xhrCore/ResponseTest.spec.js +308 -24
  177. package/target/test/xhrCore/ResponseTest.spec.js.map +1 -1
  178. package/target/test/xhrCore/ResponseTest23.spec.js +38 -8
  179. package/target/test/xhrCore/ResponseTest23.spec.js.map +1 -1
  180. package/target/test/xhrCore/TobagoFileUploadTest.spec.js +128 -0
  181. package/target/test/xhrCore/TobagoFileUploadTest.spec.js.map +1 -0
  182. package/target/test/xhrCore/XhrFormDataTest.spec.js +57 -34
  183. package/target/test/xhrCore/XhrFormDataTest.spec.js.map +1 -1
  184. package/target/test-classes/.gz +0 -0
  185. package/target/test-classes/com/example/jsfs_js_ts/JsfsJsTsApplicationTests.class +0 -0
  186. package/target/test-classes/fileuploadtest.html +24 -0
  187. package/target/test-classes/jsf-development.js +3559 -0
  188. package/target/test-classes/jsf-development.js.br +0 -0
  189. package/target/test-classes/jsf-development.js.gz +0 -0
  190. package/target/test-classes/jsf-development.js.map +1 -0
  191. package/target/test-classes/jsf.js +3 -0
  192. package/target/test-classes/jsf.js.br +0 -0
  193. package/target/test-classes/jsf.js.gz +0 -0
  194. package/tmp.xml +36 -0
  195. package/.nyc_output/2303b649-59d9-485c-9228-73b0ec8787a7.json +0 -1
  196. package/.nyc_output/756f2f03-c85b-4cdb-9b92-5799eb45ef1e.json +0 -1
  197. package/.nyc_output/processinfo/2303b649-59d9-485c-9228-73b0ec8787a7.json +0 -1
  198. package/.nyc_output/processinfo/756f2f03-c85b-4cdb-9b92-5799eb45ef1e.json +0 -1
  199. package/target/types/index.js +0 -18
  200. package/target/types/index.js.map +0 -1
@@ -13,10 +13,17 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import {ArrayCollector, Config, DQ, Lang, LazyStream, Stream} from "mona-dish";
17
- import {EMPTY_STR, IDENT_ALL, IDENT_FORM, P_VIEWSTATE} from "../core/Const";
18
- import isString = Lang.isString;
19
- import {ExtConfig} from "../util/ExtDomQuery";
16
+ import {Config, DQ, FormDataCollector, Stream} from "mona-dish";
17
+ import {$nsp, EMPTY_STR, IDENT_NONE, P_VIEWSTATE} from "../core/Const";
18
+
19
+ import {
20
+ encodeFormData,
21
+ fixEmmptyParameters, getFormInputsAsStream
22
+ } from "../util/FileUtils";
23
+
24
+
25
+ type ParamsMapper<V, K> = (key: V, item: K) => [V, K];
26
+ const defaultParamsMapper: ParamsMapper<string, any> = (key, item) => [key, item];
20
27
 
21
28
 
22
29
  /**
@@ -27,9 +34,10 @@ import {ExtConfig} from "../util/ExtDomQuery";
27
34
  * due to api constraints on the HTML Form object in IE11
28
35
  * and due to the url encoding constraint given by the faces.js spec
29
36
  *
30
- * probably only one needed and one overlay!
31
- * the entire file input storing probably is redundant now
32
- * that dom query has been fixed //TODO check this
37
+ *
38
+ * internal storage format
39
+ * every value is stored as an array
40
+ * even scalar ones!
33
41
  */
34
42
  export class XhrFormData extends Config {
35
43
  /**
@@ -45,118 +53,53 @@ export class XhrFormData extends Config {
45
53
  * data collector from a given form
46
54
  *
47
55
  * @param dataSource either a form as DomQuery object or an encoded url string
48
- * @param viewState the form view state or an external viewstate coming in as string
56
+ * @param paramsMapper a remapper for the params keys and values
49
57
  * @param executes the executes id list for the elements to being processed
50
58
  * @param partialIds partial ids to collect, to reduce the data sent down
51
59
  */
52
- constructor(private dataSource: DQ | string, viewState?: string, executes?: string[], private partialIds?: string[]) {
60
+ constructor(private dataSource: DQ, private paramsMapper: ParamsMapper<string, any> = defaultParamsMapper, executes?: string[], private partialIds?: string[]) {
53
61
  super({});
54
- //a call to getViewState before must pass the encoded line
55
- //a call from getViewState passes the form element as datasource,
56
- //so we have two call points
57
- if (isString(dataSource)) {
58
- this.assignEncodedString(<string>this.dataSource);
59
- } else {
60
- this.applyFormDataToConfig();
61
- }
62
- if('undefined' != typeof viewState) {
63
- this.assignEncodedString(viewState)
64
- }
65
- if(executes) {
66
- this.postInit(...executes);
67
- }
68
- }
69
-
70
- /**
71
- * generic post init code, for now, this peforms some post assign data post processing
72
- * @param executes
73
- */
74
- postInit(...executes: Array<string>) {
75
- let fetchInput = (id: string): DQ => {
76
- if (id == IDENT_ALL) {
77
- return DQ.querySelectorAllDeep("input[type='file']");
78
- } else if (id == IDENT_FORM) {
79
- return (<DQ>this.dataSource).querySelectorAllDeep("input[type='file']");
80
- } else {
81
- let element = DQ.byId(id, true);
82
- return this.getFileInputs(element);
83
- }
84
- };
85
-
86
- let inputExists = (item: DQ) => {
87
- return item.isPresent();
88
- };
89
-
90
-
91
- this.isMultipartRequest = LazyStream.of(...executes)
92
- .map(fetchInput)
93
- .filter(inputExists)
94
- .first().isPresent();
95
- }
96
-
97
- /**
98
- * special case view state handling
99
- *
100
- * @param form the form holding the view state value
101
- */
102
- private applyViewState(form: DQ) {
103
- let viewState = form.byId(P_VIEWSTATE, true).inputValue;
104
- this.appendIf(viewState.isPresent(), P_VIEWSTATE).value = viewState.value;
105
- }
106
-
107
- /**
108
- * assigns an url encoded string to this xhrFormData object
109
- * as key value entry
110
- * @param encoded
111
- */
112
- assignEncodedString(encoded: string) {
113
- // this code filters out empty strings as key value pairs
114
- let keyValueEntries = decodeURIComponent(encoded).split(/&/gi)
115
- .filter(item => !!(item || '')
116
- .replace(/\s+/g,''));
117
- this.assignString(keyValueEntries);
118
- }
119
-
120
- /**
121
- * assign a set of key value pairs passed as array ['key=val1', 'key2=val2']
122
- * @param keyValueEntries
123
- */
124
- assignString(keyValueEntries: string[]) {
125
- let toMerge = new ExtConfig({});
126
-
127
- function splitToKeyVal(line: string) {
128
- return line.split(/=(.*)/gi);
129
- }
130
-
131
- function fixKeyWithoutVal(keyVal: string[]) {
132
- return keyVal.length < 3 ? [keyVal?.[0] ?? [], keyVal?.[1] ?? []] : keyVal;
133
- }
134
-
135
- Stream.of(...keyValueEntries)
136
- //split only the first =
137
- .map(line => splitToKeyVal(line))
138
- //special case of having keys without values
139
- .map(keyVal => fixKeyWithoutVal(keyVal))
140
- .each(keyVal => {
141
- toMerge.append(keyVal[0] as string).value = keyVal?.splice(1)?.join("") ?? "";
142
- });
143
- //merge with overwrite but no append! (aka no double entries are allowed)
144
- this.shallowMerge(toMerge);
62
+ //encode and append the issuing item if not a partial ids array of ids is passed
63
+ /*
64
+ * Spec. 13.3.1
65
+ * Collect and encode input elements.
66
+ * Additionally the hidden element jakarta.faces.ViewState
67
+ * Enhancement partial page submit
68
+ */
69
+ this.resolveRequestType(this.dataSource, executes);
70
+ this.encodeSubmittableFields(this.dataSource, this.partialIds);
71
+ this.applyViewState(this.dataSource);
145
72
  }
146
73
 
147
74
  /**
148
75
  * @returns a Form data representation, this is needed for file submits
149
76
  */
150
77
  toFormData(): FormData {
151
- let ret: any = new FormData();
152
- this.appendInputs(ret);
153
- return ret;
154
- }
78
+ /*
79
+ * expands key: [item1, item2]
80
+ * to: [{key: key, value: item1}, {key: key, value: item2}]
81
+ */
82
+ let expandAssocArray = ([key, item]) =>
83
+ Stream.of(...(item as Array<any>)).map(value => {
84
+ return {key, value};
85
+ });
86
+
87
+ /*
88
+ * remaps the incoming {key, value} tuples
89
+ * to naming container prefixed keys and values
90
+ */
91
+ let remapForNamingContainer = ({key, value}) => {
92
+ key = this.remapKeyForNamingContainer(key);
93
+ return {key, value}
94
+ };
155
95
 
156
- resolveSubmitIdentifier(elem: HTMLInputElement) {
157
- let identifier = elem.name;
158
- identifier = ((elem?.name ?? "").replace(/s+/gi, "") == "") ? elem.id : identifier;
159
- return identifier;
96
+ /*
97
+ * collects everything into a FormData object
98
+ */
99
+ return Stream.ofAssoc(this.value)
100
+ .flatMap(expandAssocArray)
101
+ .map(remapForNamingContainer)
102
+ .collect(new FormDataCollector() as any);
160
103
  }
161
104
 
162
105
  /**
@@ -165,54 +108,33 @@ export class XhrFormData extends Config {
165
108
  * @param defaultStr optional default value if nothing is there to encode
166
109
  */
167
110
  toString(defaultStr = EMPTY_STR): string {
168
- if (this.isAbsent()) {
169
- return defaultStr;
170
- }
171
- let entries = LazyStream.of(...Object.keys(this.value))
172
- .filter(key => this.value.hasOwnProperty(key))
173
- .flatMap(key => Stream.of(...this.value[key]).map(val => [key, val]).collect(new ArrayCollector()))
174
- .map(keyVal => {
175
- return `${encodeURIComponent(keyVal[0])}=${encodeURIComponent(keyVal[1])}`;
176
- })
177
- .collect(new ArrayCollector());
178
-
179
- return entries.join("&")
111
+ return encodeFormData(this, this.paramsMapper, defaultStr);
180
112
  }
181
113
 
182
114
  /**
183
- * helper to fetch all file inputs from as given root element
184
- * @param rootElement
185
- * @private
115
+ * generic post init code, for now, this performs some post assign data post-processing
116
+ * @param executes the executable dom nodes which need to be processed into the form data, which we can send
117
+ * in our ajax request
186
118
  */
187
- private getFileInputs(rootElement: DQ): DQ {
188
- const rootFileInputs = rootElement
189
- .filter(elem => elem.matchesSelector("input[type='file']"))
190
- const childFileInputs = rootElement
191
- .querySelectorAll("input[type='file']");
192
-
193
- return rootFileInputs.concat(childFileInputs);
119
+ private resolveRequestType(rootElement: DQ, executes?: Array<string>) {
120
+ if (!executes || executes.indexOf(IDENT_NONE) != -1) {
121
+ return;
122
+ }
123
+ this.isMultipartRequest = rootElement.isMultipartCandidate(true);
194
124
  }
195
125
 
196
126
  /**
197
- * encode the given fields and apply the view state
198
- * @private
127
+ * special case view state handling
128
+ *
129
+ * @param form the form holding the view state value
199
130
  */
200
- private applyFormDataToConfig() {
201
- //encode and append the issuing item if not a partial ids array of ids is passed
202
- /*
203
- * Spec. 13.3.1
204
- * Collect and encode input elements.
205
- * Additionally the hidden element jakarta.faces.ViewState
206
- * Enhancement partial page submit
207
- *
208
- */
209
- this.encodeSubmittableFields(this, <DQ>this.dataSource, this.partialIds);
210
-
211
- if (this.getIf(P_VIEWSTATE).isPresent()) {
131
+ private applyViewState(form: DQ) {
132
+ if (this.getIf($nsp(P_VIEWSTATE)).isPresent()) {
212
133
  return;
213
134
  }
214
-
215
- this.applyViewState(<DQ>this.dataSource);
135
+ let viewStateElement = form.querySelectorAllDeep(`[name*='${$nsp(P_VIEWSTATE)}'`);
136
+ let viewState = viewStateElement.inputValue;
137
+ this.appendIf(viewState.isPresent(), this.remapKeyForNamingContainer(viewStateElement.name.value)).value = viewState.value;
216
138
  }
217
139
 
218
140
  /**
@@ -221,28 +143,19 @@ export class XhrFormData extends Config {
221
143
  * @param {Node} parentItem - form element item is nested in
222
144
  * @param {Array} partialIds - ids fo PPS
223
145
  */
224
- private encodeSubmittableFields(targetBuf: Config,
225
- parentItem: DQ, partialIds ?: string[]) {
226
- let toEncode = null;
227
- if (this.partialIds && this.partialIds.length) {
228
- // in case of our myfaces reduced ppr we
229
- // only submit the partials
230
- this._value = {};
231
- toEncode = new DQ(...this.partialIds);
232
-
233
- } else {
234
- if (parentItem.isAbsent()) throw 'NO_PAR_ITEM';
235
- toEncode = parentItem;
236
- }
146
+ private encodeSubmittableFields(parentItem: DQ, partialIds ?: string[]) {
237
147
 
238
- //lets encode the form elements
239
- this.shallowMerge(toEncode.deepElements.encodeFormElement());
148
+ const formInputs = getFormInputsAsStream(parentItem);
149
+ const mergeIntoThis = ([key, value]) => this.append(key).value = value;
150
+ const namingContainerRemap = ([key, value]) => this.paramsMapper(key as string, value);
151
+
152
+ formInputs
153
+ .map(fixEmmptyParameters)
154
+ .map(namingContainerRemap)
155
+ .each(mergeIntoThis);
240
156
  }
241
157
 
242
- private appendInputs(ret: any) {
243
- Stream.of(...Object.keys(this.value))
244
- .each(key => {
245
- Stream.of(...this.value[key]).each(item => ret.append(key, item));
246
- });
158
+ private remapKeyForNamingContainer(key: string): string {
159
+ return this.paramsMapper(key, "")[0];
247
160
  }
248
161
  }
@@ -15,7 +15,7 @@
15
15
  */
16
16
 
17
17
  import {AsyncRunnable} from "../util/AsyncRunnable";
18
- import {Config, DQ, Stream} from "mona-dish";
18
+ import {Config, DQ, DQ$, Stream} from "mona-dish";
19
19
  import {Implementation} from "../AjaxImpl";
20
20
 
21
21
  import {XhrFormData} from "./XhrFormData";
@@ -23,11 +23,12 @@ import {ErrorData} from "./ErrorData";
23
23
  import {EventData} from "./EventData";
24
24
  import {ExtLang} from "../util/Lang";
25
25
  import {
26
+ $faces,
26
27
  BEGIN,
27
28
  COMPLETE,
28
29
  CONTENT_TYPE,
29
30
  CTX_PARAM_MF_INTERNAL,
30
- CTX_PARAM_PASS_THR,
31
+ CTX_PARAM_REQ_PASS_THR,
31
32
  ERROR,
32
33
  HEAD_FACES_REQ,
33
34
  MALFORMEDXML,
@@ -36,23 +37,29 @@ import {
36
37
  ON_EVENT, P_EXECUTE,
37
38
  REQ_ACCEPT,
38
39
  REQ_TYPE_GET,
39
- REQ_TYPE_POST,
40
+ REQ_TYPE_POST, SOURCE,
40
41
  STATE_EVT_TIMEOUT,
41
42
  STD_ACCEPT,
42
43
  URL_ENCODED,
43
- VAL_AJAX
44
+ VAL_AJAX, IDENT_NONE
44
45
  } from "../core/Const";
45
- import {resolveFinalUrl, resolveHandlerFunc} from "./RequestDataResolver";
46
+ import {
47
+ resolveFinalUrl,
48
+ resolveHandlerFunc,
49
+ resoveNamingContainerMapper
50
+ } from "./RequestDataResolver";
46
51
  import failSaveExecute = ExtLang.failSaveExecute;
52
+ import {ExtConfig} from "../util/ExtDomQuery";
47
53
 
48
54
  /**
49
55
  * Faces XHR Request Wrapper
50
- * as Asyncrunnable for our Asynchronous queue
56
+ * as AsyncRunnable for our Asynchronous queue
51
57
  *
52
58
  * The idea is that we basically just enqueue
53
59
  * a single ajax request into our queue
54
60
  * and let the queue do the processing.
55
61
  *
62
+ *
56
63
  */
57
64
 
58
65
  export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
@@ -64,15 +71,15 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
64
71
  /**
65
72
  * helper support so that we do not have to drag in Promise shims
66
73
  */
67
- private catchFuncs: Array<Function> = [];
68
- private thenFunc: Array<Function> = [];
74
+ private catchFunctions: Array<Function> = [];
75
+ private thenFunctions: Array<Function> = [];
69
76
 
70
77
  /**
71
- * Reqired Parameters
78
+ * Required Parameters
72
79
  *
73
80
  * @param source the issuing element
74
81
  * @param sourceForm the form which is related to the issuing element
75
- * @param requestContext the request context with allö pass through values
82
+ * @param requestContext the request context with all pass through values
76
83
  *
77
84
  * Optional Parameters
78
85
  *
@@ -81,12 +88,12 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
81
88
  * @param timeout optional xhr timeout
82
89
  * @param ajaxType optional request type, default "POST"
83
90
  * @param contentType optional content type, default "application/x-www-form-urlencoded"
84
- * @param xhrObject optional xhr object which must fullfill the XMLHTTPRequest api, default XMLHttpRequest
91
+ * @param xhrObject optional xhr object which must fulfill the XMLHTTPRequest api, default XMLHttpRequest
85
92
  */
86
93
  constructor(
87
94
  private source: DQ,
88
95
  private sourceForm: DQ,
89
- private requestContext: Config,
96
+ private requestContext: ExtConfig,
90
97
  private internalContext: Config,
91
98
  private partialIdsArray = [],
92
99
  private timeout = NO_TIMEOUT,
@@ -94,10 +101,10 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
94
101
  private contentType = URL_ENCODED,
95
102
  private xhrObject = new XMLHttpRequest()
96
103
  ) {
97
- /*
98
- * we omit promises here
99
- * some browsers do not support it and we do not need shim code
100
- */
104
+
105
+ // we omit promises here because we have to deal with cancel functionality,
106
+ // and promises to not provide that (yet) instead we have our async queue
107
+ // which uses an api internally, which is very close to promises
101
108
  this.registerXhrCallbacks((data: any) => {
102
109
  this.resolve(data)
103
110
  }, (data: any) => {
@@ -111,70 +118,75 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
111
118
  let xhrObject = this.xhrObject;
112
119
 
113
120
  let executesArr = () => {
114
- return this.requestContext.getIf(CTX_PARAM_PASS_THR, P_EXECUTE).get("none").value.split(/\s+/gi);
121
+ return this.requestContext.getIf(CTX_PARAM_REQ_PASS_THR, P_EXECUTE).get(IDENT_NONE).value.split(/\s+/gi);
115
122
  };
116
- try {
117
123
 
118
- let formElement = this.sourceForm.getAsElem(0).value;
119
- let viewState = (window?.faces ?? window?.jsf).getViewState(formElement);
120
- //encoded we need to decode
121
- //We generated a base representation of the current form
122
- //in case someone has overloaded the viewstate with addtional decorators we merge
123
- //that in, there is no way around it, the spec allows it and getViewState
124
- //must be called, so whatever getViewState delivers has higher priority then
125
- //whatever the formData object delivers
126
- //the partialIdsArray arr is almost deprecated legacy code where we allowed to send a separate list of partial
127
- //ids for reduced load and server processing, this will be removed soon, we can handle the same via execute
128
- //anyway TODO remove the partial ids array
129
- let formData: XhrFormData = new XhrFormData(this.sourceForm, viewState, executesArr(), this.partialIdsArray);
124
+ try {
125
+ // encoded we need to decode
126
+ // We generated a base representation of the current form
127
+ // in case someone has overloaded the viewState with additional decorators we merge
128
+ // that in, there is no way around it, the spec allows it and getViewState
129
+ // must be called, so whatever getViewState delivers has higher priority then
130
+ // whatever the formData object delivers
131
+ // the partialIdsArray arr is almost deprecated legacy code where we allowed to send a separate list of partial
132
+ // ids for reduced load and server processing, this will be removed soon, we can handle the same via execute
133
+ // anyway TODO reimplement the partial ids array, we still do not have it in jsf the way we need it
134
+ let formData: XhrFormData = new XhrFormData(this.sourceForm, resoveNamingContainerMapper(this.internalContext), executesArr(), this.partialIdsArray);
130
135
 
131
136
  this.contentType = formData.isMultipartRequest ? "undefined" : this.contentType;
132
137
 
133
- //next step the pass through parameters are merged in for post params
138
+ // next step the pass through parameters are merged in for post params
139
+ this.requestContext.$nspEnabled = false;
134
140
  let requestContext = this.requestContext;
135
- let passThroughParams = requestContext.getIf(CTX_PARAM_PASS_THR);
141
+ let requestPassThroughParams = requestContext.getIf(CTX_PARAM_REQ_PASS_THR) as ExtConfig;
136
142
 
143
+ // we are turning off here the jsf, faces remapping because we are now dealing with
144
+ // pass-through parameters
145
+ requestPassThroughParams.$nspEnabled = false;
137
146
  // this is an extension where we allow pass through parameters to be sent down additionally
138
147
  // this can be used and is used in the impl to enrich the post request parameters with additional
139
148
  // information
140
- formData.shallowMerge(passThroughParams, true, true);
149
+ try {
150
+ formData.shallowMerge(requestPassThroughParams, true, true);
151
+ } finally {
152
+ this.requestContext.$nspEnabled = true;
153
+ requestPassThroughParams.$nspEnabled = true;
154
+ }
141
155
 
142
- this.responseContext = passThroughParams.deepCopy;
156
+ this.responseContext = requestPassThroughParams.deepCopy;
143
157
 
144
- //we have to shift the internal passthroughs around to build up our response context
158
+ // we have to shift the internal passthroughs around to build up our response context
145
159
  let responseContext = this.responseContext;
146
160
 
147
161
  responseContext.assign(CTX_PARAM_MF_INTERNAL).value = this.internalContext.value;
148
162
 
149
- //per spec the onevent and onerrors must be passed through to the response
163
+ // per spec the onevent and onerror handlers must be passed through to the response
150
164
  responseContext.assign(ON_EVENT).value = requestContext.getIf(ON_EVENT).value;
151
165
  responseContext.assign(ON_ERROR).value = requestContext.getIf(ON_ERROR).value;
152
166
 
153
167
  xhrObject.open(this.ajaxType, resolveFinalUrl(this.sourceForm, formData, this.ajaxType), true);
154
168
 
155
- //adding timeout
169
+ // adding timeout
156
170
  this.timeout ? xhrObject.timeout = this.timeout : null;
157
171
 
158
- //a bug in the xhr stub library prevents the setRequestHeader to be properly executed on fake xhr objects
159
- //normal browsers should resolve this
160
- //tests can quietly fail on this one
172
+ // a bug in the xhr stub library prevents the setRequestHeader to be properly executed on fake xhr objects
173
+ // normal browsers should resolve this
174
+ // tests can quietly fail on this one
161
175
  if(this.contentType != "undefined") {
162
176
  ignoreErr(() => xhrObject.setRequestHeader(CONTENT_TYPE, `${this.contentType}; charset=utf-8`));
163
177
  }
164
178
 
165
179
  ignoreErr(() => xhrObject.setRequestHeader(HEAD_FACES_REQ, VAL_AJAX));
166
180
 
167
- //probably not needed anymore, will test this
168
- //some webkit based mobile browsers do not follow the w3c spec of
181
+ // probably not needed anymore, will test this
182
+ // some webkit based mobile browsers do not follow the w3c spec of
169
183
  // setting, they accept headers automatically
170
184
  ignoreErr(() => xhrObject.setRequestHeader(REQ_ACCEPT, STD_ACCEPT));
171
185
 
172
186
  this.sendEvent(BEGIN);
173
-
174
187
  this.sendRequest(formData);
175
-
176
188
  } catch (e) {
177
- //_onError//_onError
189
+ // _onError
178
190
  this.handleError(e);
179
191
  }
180
192
  return this;
@@ -189,32 +201,31 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
189
201
  }
190
202
 
191
203
  resolve(data: any) {
192
- Stream.of(...this.thenFunc).reduce((inputVal: any, thenFunc: any) => {
204
+ Stream.of(...this.thenFunctions).reduce((inputVal: any, thenFunc: any) => {
193
205
  return thenFunc(inputVal);
194
206
  }, data);
195
207
  }
196
208
 
197
209
  reject(data: any) {
198
- Stream.of(...this.catchFuncs).reduce((inputVal: any, catchFunc: any) => {
210
+ Stream.of(...this.catchFunctions).reduce((inputVal: any, catchFunc: any) => {
199
211
  return catchFunc(inputVal);
200
212
  }, data);
201
213
  }
202
214
 
203
215
  catch(func: (data: any) => any): AsyncRunnable<XMLHttpRequest> {
204
- this.catchFuncs.push(func);
216
+ this.catchFunctions.push(func);
205
217
  return this;
206
218
  }
207
219
 
208
220
  finally(func: () => void): AsyncRunnable<XMLHttpRequest> {
209
- //no ie11 support we probably are going to revert to shims for that one
210
- this.catchFuncs.push(func);
211
- this.thenFunc.push(func);
221
+ // no ie11 support we probably are going to revert to shims for that one
222
+ this.catchFunctions.push(func);
223
+ this.thenFunctions.push(func);
212
224
  return this;
213
225
  }
214
226
 
215
227
  then(func: (data: any) => any): AsyncRunnable<XMLHttpRequest> {
216
- //this.$promise.then(func);
217
- this.thenFunc.push(func);
228
+ this.thenFunctions.push(func);
218
229
  return this;
219
230
  }
220
231
 
@@ -241,10 +252,10 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
241
252
  this.onDone(this.xhrObject, resolve);
242
253
  };
243
254
  xhrObject.onerror = (errorData: any) => {
255
+
244
256
  // some browsers trigger an error when cancelling a request internally
245
257
  // in this case we simply ignore the request and clear up the queue, because
246
258
  // it is not safe anymore to proceed with the current queue
247
-
248
259
  // This bypasses a Safari issue where it keeps requests hanging after page unload
249
260
  // and then triggers a cancel error on then instead of just stopping
250
261
  // and clearing the code
@@ -258,7 +269,7 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
258
269
  }
259
270
 
260
271
  private isCancelledResponse(currentTarget: XMLHttpRequest): boolean {
261
- return currentTarget?.status === 0 && //cancelled by browser
272
+ return currentTarget?.status === 0 && // cancelled by browser
262
273
  currentTarget?.readyState === 4 &&
263
274
  currentTarget?.responseText === '' &&
264
275
  currentTarget?.responseXML === null;
@@ -284,13 +295,14 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
284
295
 
285
296
  this.sendEvent(COMPLETE);
286
297
 
287
- //malforms always result in empty response xml
298
+ // malformed responses always result in empty response xml
299
+ // per spec a valid response cannot be empty
288
300
  if (!this?.xhrObject?.responseXML) {
289
301
  this.handleMalFormedXML(resolve);
290
302
  return;
291
303
  }
292
304
 
293
- (window?.faces ?? window.jsf).ajax.response(this.xhrObject, this.responseContext.value ?? {});
305
+ $faces().ajax.response(this.xhrObject, this.responseContext.value ?? {});
294
306
  }
295
307
 
296
308
  private handleMalFormedXML(resolve: Function) {
@@ -300,9 +312,9 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
300
312
  status: MALFORMEDXML,
301
313
  responseCode: 200,
302
314
  responseText: this.xhrObject?.responseText,
303
- source: {
304
- id: this.source.id.value
305
- }
315
+ // we remap the element just in case it gets replaced
316
+ // it will be unremapped
317
+ source: this.source.id.value
306
318
  };
307
319
  try {
308
320
  this.handleError(errorData, true);
@@ -311,7 +323,7 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
311
323
  // reject would clean up the queue
312
324
  resolve(errorData);
313
325
  }
314
- //non blocking non clearing
326
+ // non blocking non clearing
315
327
  }
316
328
 
317
329
  private onDone(data: any, resolve: Consumer<any>) {
@@ -330,10 +342,10 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
330
342
  private sendRequest(formData: XhrFormData) {
331
343
  let isPost = this.ajaxType != REQ_TYPE_GET;
332
344
  if (formData.isMultipartRequest) {
333
- //in case of a multipart request we send in a formData object as body
345
+ // in case of a multipart request we send in a formData object as body
334
346
  this.xhrObject.send((isPost) ? formData.toFormData() : null);
335
347
  } else {
336
- //in case of a normal request we send it normally
348
+ // in case of a normal request we send it normally
337
349
  this.xhrObject.send((isPost) ? formData.toString() : null);
338
350
  }
339
351
  }
@@ -344,14 +356,15 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
344
356
  private sendEvent(evtType: string) {
345
357
  let eventData = EventData.createFromRequest(this.xhrObject, this.requestContext, evtType);
346
358
  try {
347
- //user code error, we might cover
348
- //this in onError but also we cannot swallow it
349
- //we need to resolve the local handlers lazily,
350
- //because some frameworks might decorate them over the context in the response
359
+ // User code error, we might cover
360
+ // this in onError, but also we cannot swallow it.
361
+ // We need to resolve the local handlers lazily,
362
+ // because some frameworks might decorate them over the context in the response
351
363
  let eventHandler = resolveHandlerFunc(this.requestContext, this.responseContext, ON_EVENT);
352
364
 
353
365
  Implementation.sendEvent(eventData, eventHandler);
354
366
  } catch (e) {
367
+ e.source = e?.source ?? this.requestContext.getIf(SOURCE).value;
355
368
  this.handleError(e);
356
369
  throw e;
357
370
  }
@@ -363,5 +376,4 @@ export class XhrRequest implements AsyncRunnable<XMLHttpRequest> {
363
376
  let eventHandler = resolveHandlerFunc(this.requestContext, this.responseContext, ON_ERROR);
364
377
  Implementation.sendError(errorData, eventHandler);
365
378
  }
366
-
367
379
  }