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, window, document, JSON */ 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 /*jshint scripturl: true */ 54 var initialIframeSrc = options.initialIframeSrc || 'javascript:false;', 55 /*jshint scripturl: false */ 56 form, 57 iframe, 58 addParamChar; 59 return { 60 send: function (_, completeCallback) { 61 form = $('<form style="display:none;"></form>'); 62 form.attr('accept-charset', options.formAcceptCharset); 63 addParamChar = /\?/.test(options.url) ? '&' : '?'; 64 // XDomainRequest only supports GET and POST: 65 if (options.type === 'DELETE') { 66 options.url = options.url + addParamChar + '_method=DELETE'; 67 options.type = 'POST'; 68 } else if (options.type === 'PUT') { 69 options.url = options.url + addParamChar + '_method=PUT'; 70 options.type = 'POST'; 71 } else if (options.type === 'PATCH') { 72 options.url = options.url + addParamChar + '_method=PATCH'; 73 options.type = 'POST'; 74 } 75 // IE versions below IE8 cannot set the name property of 76 // elements that have already been added to the DOM, 77 // so we set the name along with the iframe HTML markup: 78 counter += 1; 79 iframe = $( 80 '<iframe src="' + initialIframeSrc + 81 '" name="iframe-transport-' + counter + '"></iframe>' 82 ).bind('load', function () { 83 var fileInputClones, 84 paramNames = $.isArray(options.paramName) ? 85 options.paramName : [options.paramName]; 86 iframe 87 .unbind('load') 88 .bind('load', function () { 89 var response; 90 // Wrap in a try/catch block to catch exceptions thrown 91 // when trying to access cross-domain iframe contents: 92 try { 93 response = iframe.contents(); 94 // Google Chrome and Firefox do not throw an 95 // exception when calling iframe.contents() on 96 // cross-domain requests, so we unify the response: 97 if (!response.length || !response[0].firstChild) { 98 throw new Error(); 99 } 100 } catch (e) { 101 response = undefined; 102 } 103 // The complete callback returns the 104 // iframe content document as response object: 105 completeCallback( 106 200, 107 'success', 108 {'iframe': response} 109 ); 110 // Fix for IE endless progress bar activity bug 111 // (happens on form submits to iframe targets): 112 $('<iframe src="' + initialIframeSrc + '"></iframe>') 113 .appendTo(form); 114 window.setTimeout(function () { 115 // Removing the form in a setTimeout call 116 // allows Chrome's developer tools to display 117 // the response result 118 form.remove(); 119 }, 0); 120 }); 121 form 122 .prop('target', iframe.prop('name')) 123 .prop('action', options.url) 124 .prop('method', options.type); 125 if (options.formData) { 126 $.each(options.formData, function (index, field) { 127 $('<input type="hidden"/>') 128 .prop('name', field.name) 129 .val(field.value) 130 .appendTo(form); 131 }); 132 } 133 if (options.fileInput && options.fileInput.length && 134 options.type === 'POST') { 135 fileInputClones = options.fileInput.clone(); 136 // Insert a clone for each file input field: 137 options.fileInput.after(function (index) { 138 return fileInputClones[index]; 139 }); 140 if (options.paramName) { 141 options.fileInput.each(function (index) { 142 $(this).prop( 143 'name', 144 paramNames[index] || options.paramName 145 ); 146 }); 147 } 148 // Appending the file input fields to the hidden form 149 // removes them from their original location: 150 form 151 .append(options.fileInput) 152 .prop('enctype', 'multipart/form-data') 153 // enctype must be set as encoding for IE: 154 .prop('encoding', 'multipart/form-data'); 155 // Remove the HTML5 form attribute from the input(s): 156 options.fileInput.removeAttr('form'); 157 } 158 form.submit(); 159 // Insert the file input fields at their original location 160 // by replacing the clones with the originals: 161 if (fileInputClones && fileInputClones.length) { 162 options.fileInput.each(function (index, input) { 163 var clone = $(fileInputClones[index]); 164 // Restore the original name and form properties: 165 $(input) 166 .prop('name', clone.prop('name')) 167 .attr('form', clone.attr('form')); 168 clone.replaceWith(input); 169 }); 170 } 171 }); 172 form.append(iframe).appendTo(document.body); 173 }, 174 abort: function () { 175 if (iframe) { 176 // javascript:false as iframe src aborts the request 177 // and prevents warning popups on HTTPS in IE6. 178 // concat is used to avoid the "Script URL" JSLint error: 179 iframe 180 .unbind('load') 181 .prop('src', initialIframeSrc); 182 } 183 if (form) { 184 form.remove(); 185 } 186 } 187 }; 188 } 189 }); 190 191 // The iframe transport returns the iframe content document as response. 192 // The following adds converters from iframe to text, json, html, xml 193 // and script. 194 // Please note that the Content-Type for JSON responses has to be text/plain 195 // or text/html, if the browser doesn't include application/json in the 196 // Accept header, else IE will show a download dialog. 197 // The Content-Type for XML responses on the other hand has to be al
197ways 198 // application/xml or text/xml, so IE properly parses the XML response. 199 // See also 200 // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation 201 $.ajaxSetup({ 202 converters: { 203 'iframe text': function (iframe) { 204 return iframe && $(iframe[0].body).text(); 205 }, 206 'iframe json': function (iframe) { 207 return iframe && jsonAPI[jsonParse]($(iframe[0].body).text()); 208 }, 209 'iframe html': function (iframe) { 210 return iframe && $(iframe[0].body).html(); 211 }, 212 'iframe xml': function (iframe) { 213 var xmlDoc = iframe && iframe[0]; 214 return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc : 215 $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) || 216 $(xmlDoc.body).html()); 217 }, 218 'iframe script': function (iframe) { 219 return iframe && $.globalEval($(iframe[0].body).text()); 220 } 221 } 222 }); 223 224}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.