Chris@0: ajaxResponseAttachmentsProcessor = $ajax_response_attachments_processor; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Request parameter to indicate that a request is a Drupal Ajax request. Chris@0: */ Chris@0: const AJAX_REQUEST_PARAMETER = '_drupal_ajax'; Chris@0: Chris@0: /** Chris@0: * Sets the AJAX parameter from the current request. Chris@0: * Chris@0: * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event Chris@0: * The response event, which contains the current request. Chris@0: */ Chris@0: public function onRequest(GetResponseEvent $event) { Chris@0: // Pass to the Html class that the current request is an Ajax request. Chris@0: if ($event->getRequest()->request->get(static::AJAX_REQUEST_PARAMETER)) { Chris@0: Html::setIsAjax(TRUE); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Renders the ajax commands right before preparing the result. Chris@0: * Chris@0: * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event Chris@0: * The response event, which contains the possible AjaxResponse object. Chris@0: */ Chris@0: public function onResponse(FilterResponseEvent $event) { Chris@0: $response = $event->getResponse(); Chris@0: if ($response instanceof AjaxResponse) { Chris@0: $this->ajaxResponseAttachmentsProcessor->processAttachments($response); Chris@0: Chris@0: // IE 9 does not support XHR 2 (http://caniuse.com/#feat=xhr2), so Chris@0: // for that browser, jquery.form submits requests containing a file upload Chris@0: // via an IFRAME rather than via XHR. Since the response is being sent to Chris@0: // an IFRAME, it must be formatted as HTML. Specifically: Chris@0: // - It must use the text/html content type or else the browser will Chris@0: // present a download prompt. Note: This applies to both file uploads Chris@0: // as well as any ajax request in a form with a file upload form. Chris@0: // - It must place the JSON data into a textarea to prevent browser Chris@0: // extensions such as Linkification and Skype's Browser Highlighter Chris@0: // from applying HTML transformations such as URL or phone number to Chris@0: // link conversions on the data values. Chris@0: // Chris@0: // Since this affects the format of the output, it could be argued that Chris@0: // this should be implemented as a separate Accept MIME type. However, Chris@0: // that would require separate variants for each type of AJAX request Chris@0: // (e.g., drupal-ajax, drupal-dialog, drupal-modal), so for expediency, Chris@0: // this browser workaround is implemented via a GET or POST parameter. Chris@0: // Chris@0: // @see http://malsup.com/jquery/form/#file-upload Chris@0: // @see https://www.drupal.org/node/1009382 Chris@0: // @see https://www.drupal.org/node/2339491 Chris@0: // @see Drupal.ajax.prototype.beforeSend() Chris@0: $accept = $event->getRequest()->headers->get('accept'); Chris@0: Chris@0: if (strpos($accept, 'text/html') !== FALSE) { Chris@0: $response->headers->set('Content-Type', 'text/html; charset=utf-8'); Chris@0: Chris@0: // Browser IFRAMEs expect HTML. Browser extensions, such as Linkification Chris@0: // and Skype's Browser Highlighter, convert URLs, phone numbers, etc. Chris@0: // into links. This corrupts the JSON response. Protect the integrity of Chris@0: // the JSON data by making it the value of a textarea. Chris@0: // @see http://malsup.com/jquery/form/#file-upload Chris@0: // @see https://www.drupal.org/node/1009382 Chris@0: $response->setContent(''); Chris@0: } Chris@0: Chris@0: // User-uploaded files cannot set any response headers, so a custom header Chris@0: // is used to indicate to ajax.js that this response is safe. Note that Chris@0: // most Ajax requests bound using the Form API will be protected by having Chris@0: // the URL flagged as trusted in Drupal.settings, so this header is used Chris@0: // only for things like custom markup that gets Ajax behaviors attached. Chris@0: $response->headers->set('X-Drupal-Ajax-Token', 1); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public static function getSubscribedEvents() { Chris@0: $events[KernelEvents::RESPONSE][] = ['onResponse', -100]; Chris@0: $events[KernelEvents::REQUEST][] = ['onRequest', 50]; Chris@0: Chris@0: return $events; Chris@0: } Chris@0: Chris@0: }