Upgrade filebrowser; minor fixes relevant to the upgrade.
[redakcja.git] / src / fileupload / static / lib / jQuery-File-Upload-10.32.0 / js / jquery.iframe-transport.js
1 /*
2  * jQuery Iframe Transport Plugin
3  * https://github.com/blueimp/jQuery-File-Upload
4  *
5  * Copyright 2011, Sebastian Tschan
6  * https://blueimp.net
7  *
8  * Licensed under the MIT license:
9  * https://opensource.org/licenses/MIT
10  */
11
12 /* global define, require */
13
14 (function (factory) {
15   'use strict';
16   if (typeof define === 'function' && define.amd) {
17     // Register as an anonymous AMD module:
18     define(['jquery'], factory);
19   } else if (typeof exports === 'object') {
20     // Node/CommonJS:
21     factory(require('jquery'));
22   } else {
23     // Browser globals:
24     factory(window.jQuery);
25   }
26 })(function ($) {
27   'use strict';
28
29   // Helper variable to create unique names for the transport iframes:
30   var counter = 0,
31     jsonAPI = $,
32     jsonParse = 'parseJSON';
33
34   if ('JSON' in window && 'parse' in JSON) {
35     jsonAPI = JSON;
36     jsonParse = 'parse';
37   }
38
39   // The iframe transport accepts four additional options:
40   // options.fileInput: a jQuery collection of file input fields
41   // options.paramName: the parameter name for the file form data,
42   //  overrides the name property of the file input field(s),
43   //  can be a string or an array of strings.
44   // options.formData: an array of objects with name and value properties,
45   //  equivalent to the return data of .serializeArray(), e.g.:
46   //  [{name: 'a', value: 1}, {name: 'b', value: 2}]
47   // options.initialIframeSrc: the URL of the initial iframe src,
48   //  by default set to "javascript:false;"
49   $.ajaxTransport('iframe', function (options) {
50     if (options.async) {
51       // javascript:false as initial iframe src
52       // prevents warning popups on HTTPS in IE6:
53       // eslint-disable-next-line no-script-url
54       var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',
55         form,
56         iframe,
57         addParamChar;
58       return {
59         send: function (_, completeCallback) {
60           form = $('<form style="display:none;"></form>');
61           form.attr('accept-charset', options.formAcceptCharset);
62           addParamChar = /\?/.test(options.url) ? '&' : '?';
63           // XDomainRequest only supports GET and POST:
64           if (options.type === 'DELETE') {
65             options.url = options.url + addParamChar + '_method=DELETE';
66             options.type = 'POST';
67           } else if (options.type === 'PUT') {
68             options.url = options.url + addParamChar + '_method=PUT';
69             options.type = 'POST';
70           } else if (options.type === 'PATCH') {
71             options.url = options.url + addParamChar + '_method=PATCH';
72             options.type = 'POST';
73           }
74           // IE versions below IE8 cannot set the name property of
75           // elements that have already been added to the DOM,
76           // so we set the name along with the iframe HTML markup:
77           counter += 1;
78           iframe = $(
79             '<iframe src="' +
80               initialIframeSrc +
81               '" name="iframe-transport-' +
82               counter +
83               '"></iframe>'
84           ).on('load', function () {
85             var fileInputClones,
86               paramNames = $.isArray(options.paramName)
87                 ? options.paramName
88                 : [options.paramName];
89             iframe.off('load').on('load', function () {
90               var response;
91               // Wrap in a try/catch block to catch exceptions thrown
92               // when trying to access cross-domain iframe contents:
93               try {
94                 response = iframe.contents();
95                 // Google Chrome and Firefox do not throw an
96                 // exception when calling iframe.contents() on
97                 // cross-domain requests, so we unify the response:
98                 if (!response.length || !response[0].firstChild) {
99                   throw new Error();
100                 }
101               } catch (e) {
102                 response = undefined;
103               }
104               // The complete callback returns the
105               // iframe content document as response object:
106               completeCallback(200, 'success', { iframe: response });
107               // Fix for IE endless progress bar activity bug
108               // (happens on form submits to iframe targets):
109               $('<iframe src="' + initialIframeSrc + '"></iframe>').appendTo(
110                 form
111               );
112               window.setTimeout(function () {
113                 // Removing the form in a setTimeout call
114                 // allows Chrome's developer tools to display
115                 // the response result
116                 form.remove();
117               }, 0);
118             });
119             form
120               .prop('target', iframe.prop('name'))
121               .prop('action', options.url)
122               .prop('method', options.type);
123             if (options.formData) {
124               $.each(options.formData, function (index, field) {
125                 $('<input type="hidden"/>')
126                   .prop('name', field.name)
127                   .val(field.value)
128                   .appendTo(form);
129               });
130             }
131             if (
132               options.fileInput &&
133               options.fileInput.length &&
134               options.type === 'POST'
135             ) {
136               fileInputClones = options.fileInput.clone();
137               // Insert a clone for each file input field:
138               options.fileInput.after(function (index) {
139                 return fileInputClones[index];
140               });
141               if (options.paramName) {
142                 options.fileInput.each(function (index) {
143                   $(this).prop('name', paramNames[index] || options.paramName);
144                 });
145               }
146               // Appending the file input fields to the hidden form
147               // removes them from their original location:
148               form
149                 .append(options.fileInput)
150                 .prop('enctype', 'multipart/form-data')
151                 // enctype must be set as encoding for IE:
152                 .prop('encoding', 'multipart/form-data');
153               // Remove the HTML5 form attribute from the input(s):
154               options.fileInput.removeAttr('form');
155             }
156             window.setTimeout(function () {
157               // Submitting the form in a setTimeout call fixes an issue with
158               // Safari 13 not triggering the iframe load event after resetting
159               // the load event handler, see also:
160               // https://github.com/blueimp/jQuery-File-Upload/issues/3633
161               form.submit();
162               // Insert the file input fields at their original location
163               // by replacing the clones with the originals:
164               if (fileInputClones && fileInputClones.length) {
165                 options.fileInput.each(function (index, input) {
166                   var clone = $(fileInputClones[index]);
167                   // Restore the original name and form properties:
168                   $(input)
169                     .prop('name', clone.prop('name'))
170                     .attr('form', clone.attr('form'));
171                   clone.replaceWith(input);
172                 });
173               }
174             }, 0);
175           });
176           form.append(iframe).appendTo(document.body);
177         },
178         abort: function () {
179           if (iframe) {
180             // javascript:false as iframe src aborts the request
181             // and prevents warning popups on HTTPS in IE6.
182             iframe.off('load').prop('src', initialIframeSrc);
183           }
184           if (form) {
185             form.remove();
186           }
187         }
188       };
189     }
190   });
191
192   // The iframe transport returns the iframe content document as response.
193   // The following adds converters from iframe to text, json, html, xml
194   // and script.
195   // Please note that the Content-Type for JSON responses has to be text/plain
196   // or text/html, if the browser doesn't include application/json in the
197   // Accept header, else IE will show a download dialog.
198   // The Content-Type for XML responses on the other hand has to be always
199   // application/xml or text/xml, so IE properly parses the XML response.
200   // See also
201   // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation
202   $.ajaxSetup({
203     converters: {
204       'iframe text': function (iframe) {
205         return iframe && $(iframe[0].body).text();
206       },
207       'iframe json': function (iframe) {
208         return iframe && jsonAPI[jsonParse]($(iframe[0].body).text());
209       },
210       'iframe html': function (iframe) {
211         return iframe && $(iframe[0].body).html();
212       },
213       'iframe xml': function (iframe) {
214         var xmlDoc = iframe && iframe[0];
215         return xmlDoc && $.isXMLDoc(xmlDoc)
216           ? xmlDoc
217           : $.parseXML(
218               (xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||
219                 $(xmlDoc.body).html()
220             );
221       },
222       'iframe script': function (iframe) {
223         return iframe && $.globalEval($(iframe[0].body).text());
224       }
225     }
226   });
227 });