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