@@ -108,6 +108,66 @@ async function setClipboard(clipboardData, type) {
108108 } ) ;
109109}
110110
111+ function xhrResponseProcessor ( response ) {
112+ const res = response ;
113+ /**
114+ * only include responseXML when needed
115+ * NOTE: Only add implementation at this time, not enable, to avoid
116+ * unnecessary calculations, and this legacy default behavior is not
117+ * recommended, users should explicitly use `responseType: "document"`
118+ * to obtain it.
119+ if (res.responseType === "" && typeof res.response === "string") {
120+ const mimeTypes = [
121+ "text/xml",
122+ "application/xml",
123+ "application/xhtml+xml",
124+ "image/svg+xml",
125+ ];
126+ for (const mimeType of mimeTypes) {
127+ if (res.contentType.includes(mimeType)) {
128+ const parser = new DOMParser();
129+ res.responseXML = parser.parseFromString(res.response, "text/xml");
130+ break;
131+ }
132+ }
133+ }
134+ */
135+ if ( res . responseType === "arraybuffer" && Array . isArray ( res . response ) ) {
136+ // arraybuffer responses had their data converted in background
137+ // convert it back to arraybuffer
138+ try {
139+ res . response = new Uint8Array ( res . response ) . buffer ;
140+ } catch ( err ) {
141+ console . error ( "error parsing xhr arraybuffer" , err ) ;
142+ }
143+ }
144+ if ( res . responseType === "blob" && Array . isArray ( res . response ) ) {
145+ // blob responses had their data converted in background
146+ // convert it back to blob
147+ try {
148+ const typedArray = new Uint8Array ( res . response ) ;
149+ const type = res . contentType ?? "" ;
150+ res . response = new Blob ( [ typedArray ] , { type } ) ;
151+ } catch ( err ) {
152+ console . error ( "error parsing xhr blob" , err ) ;
153+ }
154+ }
155+ if ( res . responseType === "document" && typeof res . response === "string" ) {
156+ // document responses had their data converted in background
157+ // convert it back to document
158+ try {
159+ const parser = new DOMParser ( ) ;
160+ const mimeType = res . contentType . includes ( "text/html" )
161+ ? "text/html"
162+ : "text/xml" ;
163+ res . response = parser . parseFromString ( res . response , mimeType ) ;
164+ res . responseXML = res . response ;
165+ } catch ( err ) {
166+ console . error ( "error parsing xhr document" , err ) ;
167+ }
168+ }
169+ }
170+
111171/**
112172 * @param {Object } details
113173 * @param {Object } control
@@ -145,69 +205,14 @@ async function xhr(details, control, promise) {
145205 typeof details [ msg . name ] === "function"
146206 ) {
147207 // process xhr response
148- const r = msg . response ;
208+ const response = msg . response ;
149209 // only include responseText when needed
150- if ( [ "" , "text" ] . includes ( r . responseType ) ) {
151- r . responseText = r . response ;
152- }
153- /**
154- * only include responseXML when needed
155- * NOTE: Only add implementation at this time, not enable, to avoid
156- * unnecessary calculations, and this legacy default behavior is not
157- * recommended, users should explicitly use `responseType: "document"`
158- * to obtain it.
159- if (r.responseType === "") {
160- const mimeTypes = [
161- "text/xml",
162- "application/xml",
163- "application/xhtml+xml",
164- "image/svg+xml",
165- ];
166- for (const mimeType of mimeTypes) {
167- if (r.contentType.includes(mimeType)) {
168- const parser = new DOMParser();
169- r.responseXML = parser.parseFromString(r.response, "text/xml");
170- break;
171- }
172- }
210+ if ( [ "" , "text" ] . includes ( response . responseType ) ) {
211+ response . responseText = response . response ;
173212 }
174- */
175213 // only process when xhr is complete and data exist
176- if ( r . readyState === 4 && r . response !== null ) {
177- if ( r . responseType === "arraybuffer" && Array . isArray ( r . response ) ) {
178- // arraybuffer responses had their data converted in background
179- // convert it back to arraybuffer
180- try {
181- r . response = new Uint8Array ( r . response ) . buffer ;
182- } catch ( err ) {
183- console . error ( "error parsing xhr arraybuffer" , err ) ;
184- }
185- }
186- if ( r . responseType === "blob" && Array . isArray ( r . response ) ) {
187- // blob responses had their data converted in background
188- // convert it back to blob
189- try {
190- const typedArray = new Uint8Array ( r . response ) ;
191- const type = r . contentType ?? "" ;
192- r . response = new Blob ( [ typedArray ] , { type } ) ;
193- } catch ( err ) {
194- console . error ( "error parsing xhr blob" , err ) ;
195- }
196- }
197- if ( r . responseType === "document" && typeof r . response === "string" ) {
198- // document responses had their data converted in background
199- // convert it back to document
200- try {
201- const parser = new DOMParser ( ) ;
202- const mimeType = r . contentType . includes ( "text/html" )
203- ? "text/html"
204- : "text/xml" ;
205- r . response = parser . parseFromString ( r . response , mimeType ) ;
206- r . responseXML = r . response ;
207- } catch ( err ) {
208- console . error ( "error parsing xhr document" , err ) ;
209- }
210- }
214+ if ( response . readyState === 4 && response . response !== null ) {
215+ xhrResponseProcessor ( response ) ;
211216 }
212217 // call userscript method
213218 details [ msg . name ] ( msg . response ) ;
0 commit comments