diff --git a/core/core.services.yml b/core/core.services.yml index 3ff7f36..891d0b7 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -570,10 +570,6 @@ services: http_negotiation.format_negotiator: class: Drupal\Core\ContentNegotiation private: true - http_negotiation.wrapper_format_subscriber: - class: Drupal\Core\EventSubscriber\WrapperFormatSubscriber - tags: - - { name: event_subscriber } http_middleware.negotiation: class: Drupal\Core\StackMiddleware\NegotiationMiddleware arguments: ['@http_negotiation.format_negotiator'] diff --git a/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php index fcc51a3..c9ad6f8 100644 --- a/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php @@ -50,6 +50,8 @@ class MainContentViewSubscriber implements EventSubscriberInterface { */ protected $mainContentRenderers; + const WRAPPER_ENVELOPE = '_wrapper_format'; + /** * Constructs a new MainContentViewSubscriber object. * @@ -76,20 +78,17 @@ public function onViewRenderArray(GetResponseForControllerResultEvent $event) { $request = $event->getRequest(); $result = $event->getControllerResult(); - $format = $request->getRequestFormat(); - // Render the controller result into a response if it's a render array. if (is_array($result)) { - if (isset($this->mainContentRenderers[$format])) { - $renderer = $this->classResolver->getInstanceFromDefinition($this->mainContentRenderers[$format]); + $wrapper = $request->query->get(static::WRAPPER_ENVELOPE, 'html'); + if (isset($this->mainContentRenderers[$wrapper])) { + $renderer = $this->classResolver->getInstanceFromDefinition($this->mainContentRenderers[$wrapper]); $event->setResponse($renderer->renderResponse($result, $request, $this->routeMatch)); } else { - $supported_formats = array_keys($this->mainContentRenderers); - $supported_mimetypes = array_map([$request, 'getMimeType'], $supported_formats); $event->setResponse(new JsonResponse([ 'message' => 'Not Acceptable.', - 'supported_mime_types' => $supported_mimetypes, + 'supported_wrapper_envelopes' => array_keys($this->mainContentRenderers), ], 406)); } } diff --git a/core/lib/Drupal/Core/EventSubscriber/WrapperFormatSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/WrapperFormatSubscriber.php deleted file mode 100644 index f293c57..0000000 --- a/core/lib/Drupal/Core/EventSubscriber/WrapperFormatSubscriber.php +++ /dev/null @@ -1,40 +0,0 @@ -getRequest(); - if ($request->query->has(static::WRAPPER_FORMAT)) { - $request->setRequestFormat($request->query->get(static::WRAPPER_FORMAT)); - } - } - - /** - * {@inheritdoc} - */ - public static function getSubscribedEvents() { - $events[KernelEvents::REQUEST][] = ['onRequest', 48]; - - return $events; - } - -} diff --git a/core/lib/Drupal/Core/Render/Element/RenderElement.php b/core/lib/Drupal/Core/Render/Element/RenderElement.php index 7600f62..b9de164 100644 --- a/core/lib/Drupal/Core/Render/Element/RenderElement.php +++ b/core/lib/Drupal/Core/Render/Element/RenderElement.php @@ -7,7 +7,7 @@ namespace Drupal\Core\Render\Element; -use Drupal\Core\EventSubscriber\WrapperFormatSubscriber; +use Drupal\Core\EventSubscriber\MainContentViewSubscriber; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\PluginBase; use Drupal\Core\Render\Element; @@ -241,7 +241,7 @@ public static function preRenderAjaxForm($element) { $settings += array( 'url' => isset($settings['callback']) ? Url::fromRoute('system.ajax') : NULL, 'options' => array(), - WrapperFormatSubscriber::WRAPPER_FORMAT => 'ajax', + MainContentViewSubscriber::WRAPPER_ENVELOPE => 'ajax', ); // @todo Legacy support. Remove in Drupal 8. diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php index fe96f9f..5b8b109 100644 --- a/core/modules/simpletest/src/WebTestBase.php +++ b/core/modules/simpletest/src/WebTestBase.php @@ -20,6 +20,7 @@ use Drupal\Core\Database\Database; use Drupal\Core\Database\ConnectionNotDefinedException; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\EventSubscriber\MainContentViewSubscriber; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Render\Element; use Drupal\Core\Session\AccountInterface; @@ -1556,8 +1557,8 @@ protected function drupalGetJSON($path, array $options = array(), array $headers * Requests a Drupal path in drupal_ajax format and JSON-decodes the response. */ protected function drupalGetAjax($path, array $options = array(), array $headers = array()) { - if (!preg_grep('/^Accept:/', $headers)) { - $headers[] = 'Accept: application/vnd.drupal-ajax'; + if (!isset($options['query'][MainContentViewSubscriber::WRAPPER_ENVELOPE])) { + $options['query'][MainContentViewSubscriber::WRAPPER_ENVELOPE] = 'drupal_ajax'; } return Json::decode($this->drupalGet($path, $options, $headers)); } @@ -1785,6 +1786,11 @@ protected function drupalPostForm($path, $edit, $submit, array $options = array( * @see ajax.js */ protected function drupalPostAjaxForm($path, $edit, $triggering_element, $ajax_path = NULL, array $options = array(), array $headers = array(), $form_html_id = NULL, $ajax_settings = NULL) { + if (isset($options['query'][MainContentViewSubscriber::WRAPPER_ENVELOPE])) { + $original_wrapper = $options['query'][MainContentViewSubscriber::WRAPPER_ENVELOPE]; + unset($options['query'][MainContentViewSubscriber::WRAPPER_ENVELOPE]); + } + // Get the content of the initial page prior to calling drupalPostForm(), // since drupalPostForm() replaces $this->content. if (isset($path)) { @@ -1793,8 +1799,11 @@ protected function drupalPostAjaxForm($path, $edit, $triggering_element, $ajax_p $content = $this->content; $drupal_settings = $this->drupalSettings; - if (!preg_grep('/^Accept:/', $headers)) { - $headers[] = 'Accept: application/vnd.drupal-ajax'; + if (isset($original_wrapper)) { + $options['query'][MainContentViewSubscriber::WRAPPER_ENVELOPE] = $original_wrapper; + } + else { + $options['query'][MainContentViewSubscriber::WRAPPER_ENVELOPE] = 'drupal_ajax'; } // Get the Ajax settings bound to the triggering element. @@ -1834,8 +1843,9 @@ protected function drupalPostAjaxForm($path, $edit, $triggering_element, $ajax_p // Unless a particular path is specified, use the one specified by the // Ajax settings, or else 'system/ajax'. if (!isset($ajax_path)) { - $ajax_path = isset($ajax_settings['url']) ? $ajax_settings['url'] : 'system/ajax'; + $ajax_path = isset($ajax_settings['url']) ? preg_replace('/^' . preg_quote($GLOBALS['base_path'], '/') . '/', '', $ajax_settings['url']) : 'system/ajax'; } + $ajax_path = $this->container->get('url_generator')->generateFromPath($ajax_path, $options); // Submit the POST request. $return = Json::decode($this->drupalPostForm(NULL, $edit, array('path' => $ajax_path, 'triggering_element' => $triggering_element), $options, $headers, $form_html_id, $extra_post)); diff --git a/core/modules/system/src/Tests/Ajax/DialogTest.php b/core/modules/system/src/Tests/Ajax/DialogTest.php index 741ee5d..c78e94c 100644 --- a/core/modules/system/src/Tests/Ajax/DialogTest.php +++ b/core/modules/system/src/Tests/Ajax/DialogTest.php @@ -7,7 +7,7 @@ namespace Drupal\system\Tests\Ajax; -use Drupal\Core\EventSubscriber\WrapperFormatSubscriber; +use Drupal\Core\EventSubscriber\MainContentViewSubscriber; use Drupal\Core\Url; /** @@ -94,7 +94,7 @@ public function testDialog() { $this->assertRaw($dialog_contents, 'Non-JS modal dialog page present.'); // Emulate going to the JS version of the page and check the JSON response. - $ajax_result = $this->drupalGetAjax('ajax-test/dialog-contents', array(), array('Accept: application/vnd.drupal-modal')); + $ajax_result = $this->drupalGetAjax('ajax-test/dialog-contents', array('query' => array(MainContentViewSubscriber::WRAPPER_ENVELOPE => 'drupal_modal'))); $this->assertEqual($modal_expected_response, $ajax_result[3], 'Modal dialog JSON response matches.'); // Check that requesting a "normal" dialog without JS goes to a page. @@ -107,7 +107,7 @@ public function testDialog() { $ajax_result = $this->drupalPostAjaxForm('ajax-test/dialog', array( // We have to mock a form element to make drupalPost submit from a link. 'textfield' => 'test', - ), array(), 'ajax-test/dialog-contents', array(), array('Accept: application/vnd.drupal-dialog'), NULL, array( + ), array(), 'ajax-test/dialog-contents', array('query' => array(MainContentViewSubscriber::WRAPPER_ENVELOPE => 'drupal_dialog')), array(), NULL, array( 'submit' => array( 'dialogOptions[target]' => 'ajax-test-dialog-wrapper-1', ) @@ -120,7 +120,7 @@ public function testDialog() { $ajax_result = $this->drupalPostAjaxForm('ajax-test/dialog', array( // We have to mock a form element to make drupalPost submit from a link. 'textfield' => 'test', - ), array(), 'ajax-test/dialog-contents', array(), array('Accept: application/vnd.drupal-dialog'), NULL, array( + ), array(), 'ajax-test/dialog-contents', array('query' => array(MainContentViewSubscriber::WRAPPER_ENVELOPE => 'drupal_dialog')), array(), NULL, array( // Don't send a target. 'submit' => array() )); @@ -160,13 +160,13 @@ public function testDialog() { $this->assertTrue(!empty($form), 'Non-JS form page present.'); // Emulate going to the JS version of the form and check the JSON response. - $ajax_result = $this->drupalGetAjax('ajax-test/dialog-form', array(), array('Accept: application/vnd.drupal-modal')); + $ajax_result = $this->drupalGetAjax('ajax-test/dialog-form', array('query' => array(MainContentViewSubscriber::WRAPPER_ENVELOPE => 'drupal_modal'))); $expected_ajax_settings = [ 'edit-preview' => [ 'callback' => '::preview', 'event' => 'click', 'url' => Url::fromRoute('system.ajax')->toString(), - WrapperFormatSubscriber::WRAPPER_FORMAT => 'ajax', + MainContentViewSubscriber::WRAPPER_ENVELOPE => 'ajax', 'submit' => [ '_triggering_element_name' => 'op', '_triggering_element_value' => 'Preview', @@ -189,7 +189,7 @@ public function testDialog() { $this->assertTrue(!empty($form), 'Non-JS entity form page present.'); // Emulate going to the JS version of the form and check the JSON response. - $ajax_result = $this->drupalGetAjax('admin/structure/contact/add', array(), array('Accept: application/vnd.drupal-modal')); + $ajax_result = $this->drupalGetAjax('admin/structure/contact/add', array('query' => array(MainContentViewSubscriber::WRAPPER_ENVELOPE => 'drupal_modal'))); $this->setRawContent($ajax_result[3]['data']); // Remove the data, the form build id and token will never match. unset($ajax_result[3]['data']); diff --git a/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php index ba261cb..663a904 100644 --- a/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php +++ b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php @@ -120,7 +120,7 @@ public function dialog() { '#url' => Url::fromRoute('ajax_test.dialog_contents'), '#attributes' => array( 'class' => array('use-ajax'), - 'data-accepts' => 'application/vnd.drupal-modal', + 'data-accepts' => 'application/vnd.drupal-modal', // TODO replace this. ), );