jsf.js_next_gen 4.0.2-beta.8 → 4.0.3-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/window/faces-development.js +86 -56
- package/dist/window/faces-development.js.map +1 -1
- package/dist/window/faces.js +1 -1
- package/dist/window/faces.js.map +1 -1
- package/dist/window/jsf-development.js +86 -56
- package/dist/window/jsf-development.js.map +1 -1
- package/dist/window/jsf.js +1 -1
- package/dist/window/jsf.js.map +1 -1
- package/faulty_response.html +167 -0
- package/package.json +1 -1
- package/src/main/typescript/impl/AjaxImpl.ts +22 -19
- package/src/main/typescript/impl/PushImpl.ts +1 -1
- package/src/main/typescript/impl/core/Const.ts +1 -1
- package/src/main/typescript/impl/xhrCore/ErrorData.ts +20 -15
- package/src/main/typescript/impl/xhrCore/XhrRequest.ts +78 -27
- package/src/main/typescript/test/impl/ImplTest.spec.ts +85 -0
- package/src/main/typescript/test/xhrCore/EventTests.spec.ts +1 -1
- package/src/main/typescript/test/xhrCore/RequestTest.spec.ts +3 -3
- package/src/main/typescript/test/xhrCore/RequestTest_23.spec.ts +3 -3
- package/src/main/typescript/test/xhrCore/ResponseTest.spec.ts +2 -2
- package/target/impl/AjaxImpl.js +21 -19
- package/target/impl/AjaxImpl.js.map +1 -1
- package/target/impl/PushImpl.js +3 -3
- package/target/impl/PushImpl.js.map +1 -1
- package/target/impl/core/Const.js +2 -2
- package/target/impl/core/Const.js.map +1 -1
- package/target/impl/xhrCore/ErrorData.js +11 -10
- package/target/impl/xhrCore/ErrorData.js.map +1 -1
- package/target/impl/xhrCore/XhrRequest.js +49 -22
- package/target/impl/xhrCore/XhrRequest.js.map +1 -1
- package/target/test/impl/ImplTest.spec.js +64 -0
- package/target/test/impl/ImplTest.spec.js.map +1 -1
- package/target/test/xhrCore/EventTests.spec.js +1 -1
- package/target/test/xhrCore/EventTests.spec.js.map +1 -1
- package/target/test/xhrCore/RequestTest.spec.js +3 -4
- package/target/test/xhrCore/RequestTest.spec.js.map +1 -1
- package/target/test/xhrCore/RequestTest_23.spec.js +3 -3
- package/target/test/xhrCore/RequestTest_23.spec.js.map +1 -1
- package/target/test/xhrCore/ResponseTest.spec.js +2 -2
- package/target/test/xhrCore/ResponseTest.spec.js.map +1 -1
- package/webpack.config.js +54 -0
- package/webpack.config.js.map +1 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang='de'>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset='UTF-8'>
|
|
5
|
+
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
|
|
6
|
+
<title>Test
|
|
7
|
+
</title>
|
|
8
|
+
<link rel='stylesheet' href='./fixtures/css/tobago.css' type='text/css'>
|
|
9
|
+
<link rel='stylesheet' href='./fixtures/css/bootstrap-icons.css' type='text/css'>
|
|
10
|
+
<script src='./fixtures/jakarta.faces.resource/faces.js.jsf' type='text/javascript'></script>
|
|
11
|
+
<script src='./fixtures/js/tobago.js' type='module'></script>
|
|
12
|
+
</head>
|
|
13
|
+
<body>
|
|
14
|
+
<tobago-page locale='de' class='container-fluid' id='page' focus-on-error='true' wait-overlay-delay-full='1000' wait-overlay-delay-ajax='1000'>
|
|
15
|
+
<form action='/content/010-input/Input.xhtml' id='page::form' method='post' accept-charset='UTF-8' data-tobago-context-path=''>
|
|
16
|
+
<input type='hidden' name='jakarta.faces.source' id='jakarta.faces.source' disabled='disabled'>
|
|
17
|
+
<tobago-focus id='page::lastFocusId'>
|
|
18
|
+
<input type='hidden' name='page::lastFocusId' id='page::lastFocusId::field'>
|
|
19
|
+
</tobago-focus>
|
|
20
|
+
<input type='hidden' name='org.apache.myfaces.tobago.webapp.Secret' id='org.apache.myfaces.tobago.webapp.Secret' value='secretValue'>
|
|
21
|
+
<div class='tobago-page-menuStore'>
|
|
22
|
+
</div>
|
|
23
|
+
<div class='tobago-page-toastStore'>
|
|
24
|
+
</div>
|
|
25
|
+
<span id='page::faces-state-container'><input type='hidden' name='jakarta.faces.ViewState' id='j_id__v_0:jakarta.faces.ViewState:1' value='viewStateValue' autocomplete='off'><input type='hidden' name='jakarta.faces.RenderKitId' value='tobago'><input type='hidden' id='j_id__v_0:jakarta.faces.ClientWindow:1' name='jakarta.faces.ClientWindow' value='clientWindowValue'></span>
|
|
26
|
+
<button type='button' id='page:button' name='page:button' class='tobago-button btn btn-secondary tobago-auto-spacing'><tobago-behavior event='click' client-id='page:button' execute='page:button' render='page'></tobago-behavior><span>page ajax</span></button>
|
|
27
|
+
</form>
|
|
28
|
+
<noscript>
|
|
29
|
+
<div class='tobago-page-noscript'>Diese Seite benötigt JavaScript, allerdings ist JavaScript in Ihrem Browser derzeit deaktiviert. Um JavaScript zu aktivieren, lesen Sie ggf. die Anleitung Ihres Browsers.
|
|
30
|
+
</div>
|
|
31
|
+
</noscript>
|
|
32
|
+
</tobago-page>
|
|
33
|
+
</body>
|
|
34
|
+
</html>
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
---- update ---
|
|
39
|
+
|
|
40
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
41
|
+
<partial-response id='j_id__v_0'>
|
|
42
|
+
<changes>
|
|
43
|
+
<update id='page'><![CDATA[
|
|
44
|
+
<html lang='de'>
|
|
45
|
+
<head>
|
|
46
|
+
<meta charset='UTF-8'/>
|
|
47
|
+
<meta name='viewport' content='width=device-width, initial-scale=1.0'/>
|
|
48
|
+
<title>Test
|
|
49
|
+
</title>
|
|
50
|
+
<link rel='stylesheet' href='./fixtures/css/tobago.css' type='text/css'>
|
|
51
|
+
<link rel='stylesheet' href='./fixtures/css/bootstrap-icons.css' type='text/css'>
|
|
52
|
+
<script src='./fixtures/jakarta.faces.resource/faces.js.jsf' type='text/javascript'></script>
|
|
53
|
+
<script src='./fixtures/js/tobago.js' type='module'></script>
|
|
54
|
+
</head>
|
|
55
|
+
<body>
|
|
56
|
+
<tobago-page locale='de' class='container-fluid' id='page' focus-on-error='true' wait-overlay-delay-full='1000' wait-overlay-delay-ajax='1000'>
|
|
57
|
+
<form action='/content/010-input/Input.xhtml' id='page::form' method='post' accept-charset='UTF-8' data-tobago-context-path=''>
|
|
58
|
+
<input type='hidden' name='jakarta.faces.source' id='jakarta.faces.source' disabled='disabled'/>
|
|
59
|
+
<tobago-focus id='page::lastFocusId'>
|
|
60
|
+
<input type='hidden' name='page::lastFocusId' id='page::lastFocusId::field'/>
|
|
61
|
+
</tobago-focus>
|
|
62
|
+
<input type='hidden' name='org.apache.myfaces.tobago.webapp.Secret' id='org.apache.myfaces.tobago.webapp.Secret' value='secretValue'/>
|
|
63
|
+
<div class='tobago-page-menuStore'>
|
|
64
|
+
</div>
|
|
65
|
+
<div class='tobago-page-toastStore'>
|
|
66
|
+
</div>
|
|
67
|
+
<span id='page::faces-state-container'></span>
|
|
68
|
+
<button type='button' id='page:button' name='page:button' class='tobago-button btn btn-secondary tobago-auto-spacing'><tobago-behavior event='click' client-id='page:button' execute='page:button' render='page'></tobago-behavior><span>page ajax</span></button>
|
|
69
|
+
</form>
|
|
70
|
+
<noscript>
|
|
71
|
+
<div class='tobago-page-noscript'>Diese Seite benötigt JavaScript, allerdings ist JavaScript in Ihrem Browser derzeit deaktiviert. Um JavaScript zu aktivieren, lesen Sie ggf. die Anleitung Ihres Browsers.
|
|
72
|
+
</div>
|
|
73
|
+
</noscript>
|
|
74
|
+
</tobago-page>
|
|
75
|
+
</body>
|
|
76
|
+
</html>]]>
|
|
77
|
+
</update>
|
|
78
|
+
<update id='j_id__v_0:jakarta.faces.ViewState:1'><![CDATA[viewStateValue]]>
|
|
79
|
+
</update>
|
|
80
|
+
<update id='j_id__v_0:jakarta.faces.ClientWindow:1'><![CDATA[clientWindowValue]]>
|
|
81
|
+
</update>
|
|
82
|
+
</changes>
|
|
83
|
+
</partial-response>`;
|
|
84
|
+
|
|
85
|
+
static SHADOW_DOM_UPDATE=`
|
|
86
|
+
<partial-response>
|
|
87
|
+
<changes><update id="shadowContent"><![CDATA[<div id="shadowContent">after update</div>]]></update></changes>
|
|
88
|
+
</partial-response>
|
|
89
|
+
`;
|
|
90
|
+
|
|
91
|
+
static UPDATE_INSERT_2 = `
|
|
92
|
+
<partial-response>
|
|
93
|
+
<changes>
|
|
94
|
+
<update id="changesArea"><![CDATA[
|
|
95
|
+
<div id='changesArea'>update succeeded 2</div><script type='text/javascript'>document.getElementById('evalarea2').innerHTML='embedded script at update succeed';</script>
|
|
96
|
+
]]></update>
|
|
97
|
+
<insert id="inserted1" >
|
|
98
|
+
<before id='changesArea'><![CDATA[insert before succeeded should display before test1<script type='text/javascript'>document.getElementById('evalarea3').innerHTML='embedded script at insert succeed';</script>]]></before>
|
|
99
|
+
</insert>
|
|
100
|
+
<insert id="inserted2">
|
|
101
|
+
<after id='changesArea'><![CDATA[insert after succeeded should display after test1]]></after>
|
|
102
|
+
</insert>
|
|
103
|
+
</changes>
|
|
104
|
+
</partial-response>
|
|
105
|
+
|
|
106
|
+
---- after ----
|
|
107
|
+
|
|
108
|
+
<head>
|
|
109
|
+
<meta charset="UTF-8">
|
|
110
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
111
|
+
<title>Test
|
|
112
|
+
</title>
|
|
113
|
+
<link rel="stylesheet" href="./fixtures/css/tobago.css" type="text/css">
|
|
114
|
+
<link rel="stylesheet" href="./fixtures/css/bootstrap-icons.css" type="text/css">
|
|
115
|
+
<script src="./fixtures/jakarta.faces.resource/faces.js.jsf" type="text/javascript"></script>
|
|
116
|
+
<script src="./fixtures/js/tobago.js" type="module"></script>
|
|
117
|
+
</head>
|
|
118
|
+
<body>
|
|
119
|
+
<html>
|
|
120
|
+
<head>
|
|
121
|
+
<meta charset="UTF-8">
|
|
122
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
123
|
+
<title>Test
|
|
124
|
+
</title>
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
<link rel="stylesheet" href="./fixtures/css/tobago.css" type="text/css">
|
|
128
|
+
<link rel="stylesheet" href="./fixtures/css/bootstrap-icons.css" type="text/css">
|
|
129
|
+
<script src="./fixtures/jakarta.faces.resource/faces.js.jsf" type="text/javascript"></script>
|
|
130
|
+
<script src="./fixtures/js/tobago.js" type="module"></script>
|
|
131
|
+
</head>
|
|
132
|
+
<body>
|
|
133
|
+
<tobago-page locale="de" class="container-fluid" id="page" focus-on-error="true" wait-overlay-delay-full="1000"
|
|
134
|
+
wait-overlay-delay-ajax="1000">
|
|
135
|
+
<form action="/content/010-input/Input.xhtml" id="page::form" method="post" accept-charset="UTF-8"
|
|
136
|
+
data-tobago-context-path="">
|
|
137
|
+
<input type="hidden" name="jakarta.faces.source" id="jakarta.faces.source" disabled="disabled">
|
|
138
|
+
<tobago-focus id="page::lastFocusId">
|
|
139
|
+
<input type="hidden" name="page::lastFocusId" id="page::lastFocusId::field">
|
|
140
|
+
</tobago-focus>
|
|
141
|
+
<input type="hidden" name="org.apache.myfaces.tobago.webapp.Secret" id="org.apache.myfaces.tobago.webapp.Secret"
|
|
142
|
+
value="secretValue">
|
|
143
|
+
<div class="tobago-page-menuStore">
|
|
144
|
+
</div>
|
|
145
|
+
<div class="tobago-page-toastStore">
|
|
146
|
+
</div>
|
|
147
|
+
<span id="page::faces-state-container"></span>
|
|
148
|
+
<button type="button" id="page:button" name="page:button"
|
|
149
|
+
class="tobago-button btn btn-secondary tobago-auto-spacing">
|
|
150
|
+
<tobago-behavior event="click" client-id="page:button" execute="page:button"
|
|
151
|
+
render="page"></tobago-behavior>
|
|
152
|
+
<span>page ajax</span></button>
|
|
153
|
+
<input type="hidden" name="jakarta.faces.ViewState" value="viewStateValue"
|
|
154
|
+
id="j_id__v_0:jakarta.faces.ViewState:1"><input type="hidden" '="" name="jakarta.faces.ClientWindow"
|
|
155
|
+
value="clientWindowValue" id="j_id__v_0:jakarta.faces.ClientWindow:1">
|
|
156
|
+
</form>
|
|
157
|
+
<noscript>
|
|
158
|
+
<div class='tobago-page-noscript'>Diese Seite benötigt JavaScript, allerdings ist JavaScript in Ihrem Browser
|
|
159
|
+
derzeit deaktiviert. Um JavaScript zu aktivieren, lesen Sie ggf. die Anleitung Ihres Browsers.
|
|
160
|
+
</div>
|
|
161
|
+
</noscript>
|
|
162
|
+
</tobago-page>
|
|
163
|
+
|
|
164
|
+
</body>
|
|
165
|
+
</html>
|
|
166
|
+
|
|
167
|
+
</body>
|
package/package.json
CHANGED
|
@@ -219,13 +219,14 @@ export module Implementation {
|
|
|
219
219
|
// by passing a boolean as return value into the onElem call
|
|
220
220
|
// we can stop early at the first false, just like the spec requests
|
|
221
221
|
|
|
222
|
-
let ret;
|
|
222
|
+
let ret = true;
|
|
223
223
|
funcs.every(func => {
|
|
224
224
|
let returnVal = resolveAndExecute(source, event, func);
|
|
225
|
-
if(returnVal
|
|
226
|
-
ret =
|
|
225
|
+
if(returnVal === false) {
|
|
226
|
+
ret = false;
|
|
227
227
|
}
|
|
228
|
-
|
|
228
|
+
//we short circuit in case of false and break the every loop
|
|
229
|
+
return ret;
|
|
229
230
|
});
|
|
230
231
|
return ret;
|
|
231
232
|
|
|
@@ -659,13 +660,14 @@ export module Implementation {
|
|
|
659
660
|
}
|
|
660
661
|
|
|
661
662
|
/**
|
|
662
|
-
* transforms the user values to the expected
|
|
663
|
-
*
|
|
664
|
-
* (
|
|
665
|
-
*
|
|
663
|
+
* transforms the user values to the expected values
|
|
664
|
+
* handling '@none', '@all', '@form', and '@this' appropriately.
|
|
665
|
+
* (Note: Although we could employ a simple string replacement method,
|
|
666
|
+
* it could result in duplicate entries under certain conditions.)
|
|
666
667
|
*
|
|
667
|
-
*
|
|
668
|
-
*
|
|
668
|
+
* Specific standardized constants such as
|
|
669
|
+
* '@all', '@none', '@form', and '@this'
|
|
670
|
+
* require special treatment.
|
|
669
671
|
*
|
|
670
672
|
* @param targetConfig the target configuration receiving the final values
|
|
671
673
|
* @param targetKey the target key
|
|
@@ -764,15 +766,14 @@ export module Implementation {
|
|
|
764
766
|
}
|
|
765
767
|
|
|
766
768
|
/**
|
|
767
|
-
*
|
|
768
|
-
*
|
|
769
|
+
* Filters the provided options using a blacklist to ensure
|
|
770
|
+
* only pass-through parameters are processed for the Ajax request.
|
|
769
771
|
*
|
|
770
|
-
* Note this is
|
|
771
|
-
*
|
|
772
|
-
*
|
|
773
|
-
* it breaks any legacy code
|
|
772
|
+
* Note that this issue is leftover from a previous implementation.
|
|
773
|
+
* The specification-conforming behavior is to use parameters for pass-through values.
|
|
774
|
+
* This will be addressed soon, after confirming that removal won't break any legacy code.
|
|
774
775
|
*
|
|
775
|
-
* @param {Context} mappedOpts
|
|
776
|
+
* @param {Context} mappedOpts - The options to be filtered.
|
|
776
777
|
*/
|
|
777
778
|
function extractLegacyParams(mappedOpts: Options): {[key: string]: any} {
|
|
778
779
|
//we now can use the full code reduction given by our stream api
|
|
@@ -783,8 +784,9 @@ export module Implementation {
|
|
|
783
784
|
}
|
|
784
785
|
|
|
785
786
|
/**
|
|
786
|
-
*
|
|
787
|
-
*
|
|
787
|
+
* Extracts the MyFaces configuration parameters
|
|
788
|
+
* that augment JSF with additional functionality.
|
|
789
|
+
*
|
|
788
790
|
* @param mappedOpts
|
|
789
791
|
* @private
|
|
790
792
|
*/
|
|
@@ -796,6 +798,7 @@ export module Implementation {
|
|
|
796
798
|
.reduce(collectAssoc, {})?.[MYFACES];
|
|
797
799
|
}
|
|
798
800
|
|
|
801
|
+
|
|
799
802
|
function remapArrayToAssocArr(arrayedParams: [[string, any]] | {[key: string]: any}): {[key: string]: any} {
|
|
800
803
|
if(Array.isArray(arrayedParams)) {
|
|
801
804
|
return arrayedParams.reduce(collectAssoc, {} as any);
|
|
@@ -153,7 +153,7 @@ export module PushImpl {
|
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
onerror(event: any) {
|
|
156
|
-
let message = JSON.parse(event
|
|
156
|
+
let message = JSON.parse(event?.data ?? null);
|
|
157
157
|
//TODO replace this with a more readable Stream code
|
|
158
158
|
for (let i = clientIdsByTokens[this.channelToken].length - 1; i >= 0; i--) {
|
|
159
159
|
let socketClientId = clientIdsByTokens[this.channelToken][i];
|
|
@@ -90,7 +90,7 @@ export const RESPONSE_TEXT = "responseText";
|
|
|
90
90
|
export const RESPONSE_XML = "responseXML";
|
|
91
91
|
|
|
92
92
|
/*ajax errors spec 14.4.2*/
|
|
93
|
-
export const
|
|
93
|
+
export const HTTP_ERROR = "httpError";
|
|
94
94
|
export const EMPTY_RESPONSE = "emptyResponse";
|
|
95
95
|
export const MALFORMEDXML = "malformedXML";
|
|
96
96
|
export const SERVER_ERROR = "serverError";
|
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
import {
|
|
17
17
|
EMPTY_STR, ERROR,
|
|
18
18
|
ERROR_MESSAGE,
|
|
19
|
-
ERROR_NAME,
|
|
19
|
+
ERROR_NAME, HTTP_ERROR,
|
|
20
20
|
RESPONSE_TEXT,
|
|
21
21
|
RESPONSE_XML, SERVER_ERROR,
|
|
22
22
|
SOURCE,
|
|
23
23
|
STATUS,
|
|
24
24
|
UNKNOWN
|
|
25
25
|
} from "../core/Const";
|
|
26
|
-
import {Config} from "mona-dish";
|
|
26
|
+
import {Config, Optional, XMLQuery} from "mona-dish";
|
|
27
27
|
|
|
28
28
|
import {EventData} from "./EventData";
|
|
29
29
|
import {ExtLang} from "../util/Lang";
|
|
@@ -49,8 +49,8 @@ export enum ErrorType {
|
|
|
49
49
|
export class ErrorData extends EventData implements IErrorData {
|
|
50
50
|
|
|
51
51
|
type: string = "error";
|
|
52
|
-
source:
|
|
53
|
-
|
|
52
|
+
source: string;
|
|
53
|
+
|
|
54
54
|
errorName: string;
|
|
55
55
|
errorMessage: string;
|
|
56
56
|
|
|
@@ -62,19 +62,24 @@ export class ErrorData extends EventData implements IErrorData {
|
|
|
62
62
|
|
|
63
63
|
serverErrorName: string;
|
|
64
64
|
serverErrorMessage: string;
|
|
65
|
-
|
|
65
|
+
description: string;
|
|
66
66
|
|
|
67
|
-
constructor(source: string, errorName: string, errorMessage: string, responseText: string = null, responseXML:
|
|
67
|
+
constructor(source: string, errorName: string, errorMessage: string, responseText: string = null, responseXML: Document = null, responseCode: number = -1, statusOverride: string = null, type = ErrorType.CLIENT_ERROR) {
|
|
68
68
|
super();
|
|
69
|
-
this.source =
|
|
70
|
-
this.sourceId = source;
|
|
69
|
+
this.source = source;
|
|
71
70
|
this.type = ERROR;
|
|
72
71
|
this.errorName = errorName;
|
|
72
|
+
|
|
73
73
|
//tck requires that the type is prefixed to the message itself (jsdoc also) in case of a server error
|
|
74
|
-
this.
|
|
75
|
-
this.responseCode = responseCode
|
|
74
|
+
this.errorMessage = errorMessage;
|
|
75
|
+
this.responseCode = `${responseCode}`;
|
|
76
76
|
this.responseText = responseText;
|
|
77
|
-
this.
|
|
77
|
+
this.responseXML = responseXML;
|
|
78
|
+
|
|
79
|
+
this.status = statusOverride;
|
|
80
|
+
|
|
81
|
+
this.description = `Status: ${this.status}\nResponse Code: ${this.responseCode}\nError Message: ${this.errorMessage}`;
|
|
82
|
+
|
|
78
83
|
this.typeDetails = type;
|
|
79
84
|
|
|
80
85
|
if (type == ErrorType.SERVER_ERROR) {
|
|
@@ -87,8 +92,8 @@ export class ErrorData extends EventData implements IErrorData {
|
|
|
87
92
|
return new ErrorData((e as any)?.source ?? "client", e?.name ?? EMPTY_STR, e?.message ?? EMPTY_STR, e?.stack ?? EMPTY_STR);
|
|
88
93
|
}
|
|
89
94
|
|
|
90
|
-
static fromHttpConnection(source: any, name: string, message: string, responseText, responseCode: number, status: string = EMPTY_STR): ErrorData {
|
|
91
|
-
return new ErrorData(source, name, message, responseText,
|
|
95
|
+
static fromHttpConnection(source: any, name: string, message: string, responseText: string, responseXML: Document, responseCode: number, status: string = EMPTY_STR): ErrorData {
|
|
96
|
+
return new ErrorData(source, name, message, responseText, responseXML, responseCode, status, ErrorType.HTTP_ERROR);
|
|
92
97
|
}
|
|
93
98
|
|
|
94
99
|
static fromGeneric(context: Config, errorCode: number, errorType: ErrorType = ErrorType.SERVER_ERROR): ErrorData {
|
|
@@ -100,10 +105,10 @@ export class ErrorData extends EventData implements IErrorData {
|
|
|
100
105
|
let errorMessage = getMsg(context, ERROR_MESSAGE);
|
|
101
106
|
let status = getMsg(context, STATUS);
|
|
102
107
|
let responseText = getMsg(context, RESPONSE_TEXT);
|
|
103
|
-
let responseXML =
|
|
108
|
+
let responseXML: Document = context.getIf(RESPONSE_XML).value;
|
|
104
109
|
|
|
105
110
|
|
|
106
|
-
return new ErrorData(source, errorName, errorMessage, responseText, responseXML, errorCode
|
|
111
|
+
return new ErrorData(source, errorName, errorMessage, responseText, responseXML, errorCode, status, errorType);
|
|
107
112
|
}
|
|
108
113
|
|
|
109
114
|
private static getMsg(context, param) {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import {AsyncRunnable, IAsyncRunnable} from "../util/AsyncRunnable";
|
|
18
|
-
import {Config, DQ} from "mona-dish";
|
|
18
|
+
import {Config, DQ, XMLQuery} from "mona-dish";
|
|
19
19
|
import {Implementation} from "../AjaxImpl";
|
|
20
20
|
|
|
21
21
|
import {XhrFormData} from "./XhrFormData";
|
|
@@ -34,14 +34,23 @@ import {
|
|
|
34
34
|
MALFORMEDXML,
|
|
35
35
|
NO_TIMEOUT,
|
|
36
36
|
ON_ERROR,
|
|
37
|
-
ON_EVENT,
|
|
37
|
+
ON_EVENT,
|
|
38
|
+
P_EXECUTE,
|
|
38
39
|
REQ_ACCEPT,
|
|
39
40
|
REQ_TYPE_GET,
|
|
40
|
-
REQ_TYPE_POST,
|
|
41
|
+
REQ_TYPE_POST,
|
|
42
|
+
SOURCE,
|
|
41
43
|
STATE_EVT_TIMEOUT,
|
|
42
44
|
STD_ACCEPT,
|
|
43
45
|
URL_ENCODED,
|
|
44
|
-
VAL_AJAX,
|
|
46
|
+
VAL_AJAX,
|
|
47
|
+
IDENT_NONE,
|
|
48
|
+
CTX_PARAM_SRC_FRM_ID,
|
|
49
|
+
CTX_PARAM_SRC_CTL_ID,
|
|
50
|
+
CTX_PARAM_PPS,
|
|
51
|
+
P_AJAX_SOURCE,
|
|
52
|
+
RESPONSE_TEXT,
|
|
53
|
+
RESPONSE_XML, STATUS, EMPTY_RESPONSE, HTTP_ERROR, UNKNOWN, SERVER_ERROR, EMPTY_STR
|
|
45
54
|
} from "../core/Const";
|
|
46
55
|
import {
|
|
47
56
|
resolveFinalUrl,
|
|
@@ -75,6 +84,10 @@ export class XhrRequest extends AsyncRunnable<XMLHttpRequest> {
|
|
|
75
84
|
|
|
76
85
|
private xhrObject = new XMLHttpRequest();
|
|
77
86
|
|
|
87
|
+
static readonly TYPE_CHECKBOX = "checkbox";
|
|
88
|
+
static readonly TYPE_RADIO = "radio";
|
|
89
|
+
|
|
90
|
+
|
|
78
91
|
/**
|
|
79
92
|
* Required Parameters
|
|
80
93
|
*
|
|
@@ -126,7 +139,6 @@ export class XhrRequest extends AsyncRunnable<XMLHttpRequest> {
|
|
|
126
139
|
executes, partialIdsArray
|
|
127
140
|
);
|
|
128
141
|
|
|
129
|
-
|
|
130
142
|
this.contentType = formData.isMultipartRequest ? "undefined" : this.contentType;
|
|
131
143
|
|
|
132
144
|
// next step the pass through parameters are merged in for post params
|
|
@@ -279,7 +291,7 @@ export class XhrRequest extends AsyncRunnable<XMLHttpRequest> {
|
|
|
279
291
|
// reject means clear queue, in this case we abort entirely the processing
|
|
280
292
|
// does not happen yet, we have to probably rethink this strategy in the future
|
|
281
293
|
// when we introduce cancel functionality
|
|
282
|
-
this.
|
|
294
|
+
this.handleHttpError(reject);
|
|
283
295
|
}
|
|
284
296
|
|
|
285
297
|
/**
|
|
@@ -293,7 +305,7 @@ export class XhrRequest extends AsyncRunnable<XMLHttpRequest> {
|
|
|
293
305
|
// timeout also means we we probably should clear the queue,
|
|
294
306
|
// the state is unsafe for the next requests
|
|
295
307
|
this.sendEvent(STATE_EVT_TIMEOUT);
|
|
296
|
-
this.
|
|
308
|
+
this.handleHttpError(resolve);
|
|
297
309
|
}
|
|
298
310
|
|
|
299
311
|
/**
|
|
@@ -307,27 +319,66 @@ export class XhrRequest extends AsyncRunnable<XMLHttpRequest> {
|
|
|
307
319
|
private onResponseReceived(resolve: Consumer<any>) {
|
|
308
320
|
|
|
309
321
|
this.sendEvent(COMPLETE);
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
// all errors from the server are resolved without interfering in the queue
|
|
315
|
-
this.handleGenericError(resolve);
|
|
316
|
-
return;
|
|
322
|
+
|
|
323
|
+
//request error resolution as per spec:
|
|
324
|
+
if(!this.processRequestErrors(resolve)) {
|
|
325
|
+
$faces().ajax.response(this.xhrObject, this.responseContext.value ?? {});
|
|
317
326
|
}
|
|
327
|
+
}
|
|
318
328
|
|
|
319
|
-
|
|
329
|
+
private processRequestErrors(resolve: Consumer<any>): boolean {
|
|
330
|
+
const responseXML = new XMLQuery(this.xhrObject?.responseXML);
|
|
331
|
+
const responseCode = this.xhrObject?.status ?? -1;
|
|
332
|
+
if(responseXML.isXMLParserError()) {
|
|
333
|
+
// invalid response
|
|
334
|
+
const errorName = "Invalid Response";
|
|
335
|
+
const errorMessage = "The response xml is invalid";
|
|
336
|
+
|
|
337
|
+
this.handleGenericResponseError(errorName, errorMessage, MALFORMEDXML, resolve);
|
|
338
|
+
return true;
|
|
339
|
+
} else if(responseXML.isAbsent()) {
|
|
340
|
+
// empty response
|
|
341
|
+
const errorName = "Empty Response";
|
|
342
|
+
const errorMessage = "The response has provided no data";
|
|
343
|
+
|
|
344
|
+
this.handleGenericResponseError(errorName, errorMessage, EMPTY_RESPONSE, resolve);
|
|
345
|
+
return true;
|
|
346
|
+
} else if (responseCode >= 300 || responseCode < 200) {
|
|
347
|
+
// other server errors
|
|
348
|
+
// all errors from the server are resolved without interfering in the queue
|
|
349
|
+
this.handleHttpError(resolve);
|
|
350
|
+
return true;
|
|
351
|
+
}
|
|
352
|
+
//additional errors are application errors and must be handled within the response
|
|
353
|
+
return false;
|
|
354
|
+
}
|
|
355
|
+
private handleGenericResponseError(errorName: string, errorMessage: string, responseStatus: string, resolve: (s?: any) => void) {
|
|
356
|
+
const errorData: ErrorData = new ErrorData(
|
|
357
|
+
this.internalContext.getIf(CTX_PARAM_SRC_CTL_ID).value,
|
|
358
|
+
errorName, errorMessage,
|
|
359
|
+
this.xhrObject?.responseText ?? "",
|
|
360
|
+
this.xhrObject?.responseXML ?? null,
|
|
361
|
+
this.xhrObject.status,
|
|
362
|
+
responseStatus
|
|
363
|
+
);
|
|
364
|
+
this.finalizeError(errorData, resolve);
|
|
320
365
|
}
|
|
321
366
|
|
|
322
|
-
private
|
|
367
|
+
private handleHttpError(resolveOrReject: Function, errorMessage: string = "Generic HTTP Serror") {
|
|
323
368
|
this.stopProgress = true;
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
369
|
+
|
|
370
|
+
const errorData = new ErrorData(
|
|
371
|
+
this.internalContext.getIf(CTX_PARAM_SRC_CTL_ID).value,
|
|
372
|
+
HTTP_ERROR, errorMessage,
|
|
373
|
+
this.xhrObject?.responseText ?? "",
|
|
374
|
+
this.xhrObject?.responseXML ?? null,
|
|
375
|
+
this.xhrObject?.status ?? -1,
|
|
376
|
+
HTTP_ERROR
|
|
377
|
+
)
|
|
378
|
+
this.finalizeError(errorData, resolveOrReject);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
private finalizeError(errorData: ErrorData, resolveOrReject: Function) {
|
|
331
382
|
try {
|
|
332
383
|
this.handleError(errorData, true);
|
|
333
384
|
} finally {
|
|
@@ -335,8 +386,8 @@ export class XhrRequest extends AsyncRunnable<XMLHttpRequest> {
|
|
|
335
386
|
// reject would clean up the queue
|
|
336
387
|
// resolve would trigger the next element in the queue to be processed
|
|
337
388
|
resolveOrReject(errorData);
|
|
389
|
+
this.stopProgress = true;
|
|
338
390
|
}
|
|
339
|
-
// non blocking non clearing
|
|
340
391
|
}
|
|
341
392
|
|
|
342
393
|
/**
|
|
@@ -395,7 +446,7 @@ export class XhrRequest extends AsyncRunnable<XMLHttpRequest> {
|
|
|
395
446
|
}
|
|
396
447
|
|
|
397
448
|
private handleError(exception, responseFormatError: boolean = false) {
|
|
398
|
-
const errorData = (responseFormatError) ? ErrorData.fromHttpConnection(exception.source, exception.type, exception.
|
|
449
|
+
const errorData = (responseFormatError) ? ErrorData.fromHttpConnection(exception.source, exception.type, exception.message ?? EMPTY_STR, exception.responseText, exception.responseXML, exception.responseCode, exception.status) : ErrorData.fromClient(exception);
|
|
399
450
|
const eventHandler = resolveHandlerFunc(this.requestContext, this.responseContext, ON_ERROR);
|
|
400
451
|
|
|
401
452
|
Implementation.sendError(errorData, eventHandler);
|
|
@@ -412,9 +463,9 @@ export class XhrRequest extends AsyncRunnable<XMLHttpRequest> {
|
|
|
412
463
|
|
|
413
464
|
//Checkbox and radio only value pass if checked is set, otherwise they should not show
|
|
414
465
|
//up at all, and if checked is set, they either can have a value or simply being boolean
|
|
415
|
-
if((type ==
|
|
466
|
+
if((type == XhrRequest.TYPE_CHECKBOX || type == XhrRequest.TYPE_RADIO) && !issuingItem.checked) {
|
|
416
467
|
return;
|
|
417
|
-
} else if((type ==
|
|
468
|
+
} else if((type == XhrRequest.TYPE_CHECKBOX || type == XhrRequest.TYPE_RADIO)) {
|
|
418
469
|
arr.assign(issuingItemId).value = itemValue.orElse(true).value;
|
|
419
470
|
} else if (itemValue.isPresent()) {
|
|
420
471
|
arr.assign(issuingItemId).value = itemValue.value;
|
|
@@ -140,6 +140,91 @@ describe('faces.ajax.request test suite', () => {
|
|
|
140
140
|
});
|
|
141
141
|
|
|
142
142
|
|
|
143
|
+
it("chain must handle the true false return values correctly", function () {
|
|
144
|
+
let func1 = () => {
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
let func2 = () => {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
let func3 = () => {
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
let func4 = () => {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
let ret = faces.util.chain(this, {}, func1);
|
|
160
|
+
expect(ret).to.be.true;
|
|
161
|
+
|
|
162
|
+
ret = faces.util.chain(this, {}, func2);
|
|
163
|
+
expect(ret).to.be.false;
|
|
164
|
+
|
|
165
|
+
ret = faces.util.chain(this, {}, func3);
|
|
166
|
+
expect(ret).to.be.true;
|
|
167
|
+
|
|
168
|
+
ret = faces.util.chain(this, {}, func4);
|
|
169
|
+
expect(ret).to.be.true;
|
|
170
|
+
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
it("sidebehavior chain on undefined must not break the chain only a dedicated false does", function() {
|
|
174
|
+
let called = {};
|
|
175
|
+
window.called = called;
|
|
176
|
+
|
|
177
|
+
let func1 = () => {
|
|
178
|
+
called["func1"] = true;
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
let func2 = `function func2(called) {
|
|
183
|
+
called["func2"] = true;
|
|
184
|
+
return true;
|
|
185
|
+
}`;
|
|
186
|
+
|
|
187
|
+
let func3 = () => {
|
|
188
|
+
called["func3"] = true;
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
let func4 = `return (function func4(called) {
|
|
193
|
+
called["func4"] = true;
|
|
194
|
+
return undefined;
|
|
195
|
+
})(event)`;
|
|
196
|
+
|
|
197
|
+
let func5 = `return (function func4(called) {
|
|
198
|
+
called["func5"] = true;
|
|
199
|
+
return false;
|
|
200
|
+
})(event)`;
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
let func6 = () => {
|
|
205
|
+
called["func6"] = true;
|
|
206
|
+
return false;
|
|
207
|
+
};
|
|
208
|
+
delete Array.prototype["flatMap"];
|
|
209
|
+
faces.util.chain(this, called, func1, func2, func3, func4, func5, func6);
|
|
210
|
+
|
|
211
|
+
expect(called["func1"]).to.be.true;
|
|
212
|
+
expect(called["func2"]).to.be.true;
|
|
213
|
+
expect(!!called["func3"]).to.be.true;
|
|
214
|
+
expect(!!called["func4"]).to.be.true;
|
|
215
|
+
expect(!!called["func5"]).to.be.true;
|
|
216
|
+
expect(!!called["func6"]).to.be.false;
|
|
217
|
+
|
|
218
|
+
/*called = {};
|
|
219
|
+
faces.util.chain(this, called, func1, func2, func4, func5, func6);
|
|
220
|
+
expect(called["func1"]).to.be.true;
|
|
221
|
+
expect(called["func2"]).to.be.true;
|
|
222
|
+
expect(!!called["func4"]).to.be.true;
|
|
223
|
+
expect(!!called["func5"]).to.be.false;*/
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
|
|
143
228
|
|
|
144
229
|
|
|
145
230
|
});
|
|
@@ -111,7 +111,7 @@ describe('tests the addOnEvent and addOnError handling', function () {
|
|
|
111
111
|
expect(onErrorCalled1).to.eq(1);
|
|
112
112
|
expect(onErrorCalled2).to.eq(1);
|
|
113
113
|
expect(errorTitle).to.eq('Erro21');
|
|
114
|
-
expect(errorMessage).to.eq('
|
|
114
|
+
expect(errorMessage).to.eq('Error2 Text');
|
|
115
115
|
} finally {
|
|
116
116
|
console.error = oldErr;
|
|
117
117
|
}
|