#1018714 by effulgentsia: Fixed Image Upload Widget Not Working in IE8
parent
c65b74496b
commit
e830c0e095
|
@ -425,32 +425,67 @@ function ajax_base_page_theme() {
|
|||
* @see drupal_deliver_html_page()
|
||||
*/
|
||||
function ajax_deliver($page_callback_result) {
|
||||
// Browsers do not allow JavaScript to read the contents of a user's local
|
||||
// files. To work around that, the jQuery Form plugin submits forms containing
|
||||
// a file input element to an IFRAME, instead of using XHR. Browsers do not
|
||||
// normally expect JSON strings as content within an IFRAME, so the response
|
||||
// must be customized accordingly.
|
||||
// @see http://malsup.com/jquery/form/#file-upload
|
||||
// @see Drupal.ajax.prototype.beforeSend()
|
||||
$iframe_upload = !empty($_POST['ajax_iframe_upload']);
|
||||
|
||||
// Emit a Content-Type HTTP header if none has been added by the page callback
|
||||
// or by a wrapping delivery callback.
|
||||
if (is_null(drupal_get_http_header('Content-Type'))) {
|
||||
// The standard header for JSON is application/json.
|
||||
// @see http://www.ietf.org/rfc/rfc4627.txt?number=4627
|
||||
// However, browsers do not allow JavaScript to read the contents of a
|
||||
// user's local files. To work around that, jQuery submits forms containing
|
||||
// a file input element to an IFRAME, instead of using XHR.
|
||||
// @see http://malsup.com/jquery/form/#file-upload
|
||||
// When Internet Explorer receives application/json content in an IFRAME, it
|
||||
// treats it as a file download and prompts the user to save it. To prevent
|
||||
// that, we return the content as text/plain. But only for POST requests,
|
||||
// since jQuery should always use XHR for GET requests and the incorrect
|
||||
// mime type should not end up in page or proxy server caches.
|
||||
// @see http://drupal.org/node/995854
|
||||
$iframe_upload = !isset($_SERVER['HTTP_X_REQUESTED_WITH']) || $_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest';
|
||||
if ($iframe_upload && $_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
drupal_add_http_header('Content-Type', 'text/plain; charset=utf-8');
|
||||
if (!$iframe_upload) {
|
||||
// Standard JSON can be returned to a browser's XHR object, and to
|
||||
// non-browser user agents.
|
||||
// @see http://www.ietf.org/rfc/rfc4627.txt?number=4627
|
||||
drupal_add_http_header('Content-Type', 'application/json; charset=utf-8');
|
||||
}
|
||||
else {
|
||||
drupal_add_http_header('Content-Type', 'application/json; charset=utf-8');
|
||||
// Browser IFRAMEs expect HTML. With most other content types, Internet
|
||||
// Explorer presents the user with a download prompt.
|
||||
drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize whatever was returned by the page callback to an AJAX commands
|
||||
// array.
|
||||
// Print the response.
|
||||
$commands = ajax_prepare_response($page_callback_result);
|
||||
$json = ajax_render($commands);
|
||||
if (!$iframe_upload) {
|
||||
// Standard JSON can be returned to a browser's XHR object, and to
|
||||
// non-browser user agents.
|
||||
print $json;
|
||||
}
|
||||
else {
|
||||
// Browser IFRAMEs expect HTML. Browser extensions, such as Linkification
|
||||
// and Skype's Browser Highlighter, convert URLs, phone numbers, etc. into
|
||||
// links. This corrupts the JSON response. Protect the integrity of the
|
||||
// JSON data by making it the value of a textarea.
|
||||
// @see http://malsup.com/jquery/form/#file-upload
|
||||
// @see http://drupal.org/node/1009382
|
||||
print '<textarea>' . $json . '</textarea>';
|
||||
}
|
||||
|
||||
// Perform end-of-request tasks.
|
||||
ajax_footer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the return value of a page callback into an AJAX commands array.
|
||||
*
|
||||
* @param $page_callback_result
|
||||
* The result of a page callback. Can be one of:
|
||||
* - NULL: to indicate no content.
|
||||
* - An integer menu status constant: to indicate an error condition.
|
||||
* - A string of HTML content.
|
||||
* - A renderable array of content.
|
||||
*
|
||||
* @return
|
||||
* An AJAX commands array that can be passed to ajax_render().
|
||||
*/
|
||||
function ajax_prepare_response($page_callback_result) {
|
||||
$commands = array();
|
||||
if (!isset($page_callback_result)) {
|
||||
// Simply delivering an empty commands array is sufficient. This results
|
||||
|
@ -501,11 +536,7 @@ function ajax_deliver($page_callback_result) {
|
|||
$commands[] = ajax_command_prepend(NULL, theme('status_messages'));
|
||||
}
|
||||
|
||||
// Unlike the recommendation in http://malsup.com/jquery/form/#file-upload,
|
||||
// we do not have to wrap the JSON string in a TEXTAREA, because
|
||||
// drupal_json_encode() returns an HTML-safe JSON string.
|
||||
print ajax_render($commands);
|
||||
ajax_footer();
|
||||
return $commands;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
38
misc/ajax.js
38
misc/ajax.js
|
@ -318,20 +318,38 @@ Drupal.ajax.prototype.beforeSubmit = function (form_values, element, options) {
|
|||
* Prepare the AJAX request before it is sent.
|
||||
*/
|
||||
Drupal.ajax.prototype.beforeSend = function (xmlhttprequest, options) {
|
||||
// For forms without file inputs, the jQuery Form plugin serializes the form
|
||||
// values, and then calls jQuery's $.ajax() function, which invokes this
|
||||
// handler. In this circumstance, options.extraData is never used. For forms
|
||||
// with file inputs, the jQuery Form plugin uses the browser's normal form
|
||||
// submission mechanism, but captures the response in a hidden IFRAME. In this
|
||||
// circumstance, it calls this handler first, and then appends hidden fields
|
||||
// to the form to submit the values in options.extraData. There is no simple
|
||||
// way to know which submission mechanism will be used, so we add to extraData
|
||||
// regardless, and allow it to be ignored in the former case.
|
||||
if (this.form) {
|
||||
options.extraData = options.extraData || {};
|
||||
|
||||
// Let the server know when the IFRAME submission mechanism is used. The
|
||||
// server can use this information to wrap the JSON response in a TEXTAREA,
|
||||
// as per http://jquery.malsup.com/form/#file-upload.
|
||||
options.extraData.ajax_iframe_upload = '1';
|
||||
|
||||
// The triggering element is about to be disabled (see below), but if it
|
||||
// contains a value (e.g., a checkbox, textfield, select, etc.), ensure that
|
||||
// value is included in the submission. As per above, submissions that use
|
||||
// $.ajax() are already serialized prior to the element being disabled, so
|
||||
// this is only needed for IFRAME submissions.
|
||||
var v = $.fieldValue(this.element);
|
||||
if (v !== null) {
|
||||
options.extraData[this.element.name] = v;
|
||||
}
|
||||
}
|
||||
|
||||
// Disable the element that received the change to prevent user interface
|
||||
// interaction while the AJAX request is in progress. ajax.ajaxing prevents
|
||||
// the element from triggering a new request, but does not prevent the user
|
||||
// from changing its value.
|
||||
// Forms without file inputs are already serialized before this function is
|
||||
// called. Forms with file inputs use an IFRAME to perform a POST request
|
||||
// similar to a browser, so disabled elements are not contained in the
|
||||
// submitted values. Therefore, we manually add the element's value to
|
||||
// options.extraData.
|
||||
var v = $.fieldValue(this.element);
|
||||
if (v !== null) {
|
||||
options.extraData = options.extraData || {};
|
||||
options.extraData[this.element.name] = v;
|
||||
}
|
||||
$(this.element).addClass('progress-disabled').attr('disabled', true);
|
||||
|
||||
// Insert progressbar or throbber.
|
||||
|
|
Loading…
Reference in New Issue