diff --git a/core/modules/views_ui/src/ViewEditForm.php b/core/modules/views_ui/src/ViewEditForm.php index 690973e7485d7be07a79c5ca98cf8a19e4927914..8ca5612dbbb9873d9ae760a540d944dc25e46dc3 100644 --- a/core/modules/views_ui/src/ViewEditForm.php +++ b/core/modules/views_ui/src/ViewEditForm.php @@ -361,8 +361,16 @@ public function getDisplayTab($view) { $build['details'] = $this->getDisplayDetails($view, $display->display); } // In AJAX context, ViewUI::rebuildCurrentTab() returns this outside of form - // context, so hook_form_views_ui_edit_form_alter() is insufficient. + // context, so hook_form_view_edit_form_alter() is insufficient. + // @todo remove this after + // https://www.drupal.org/project/drupal/issues/3087455 has been resolved. \Drupal::moduleHandler()->alter('views_ui_display_tab', $build, $view, $display_id); + // Because themes can implement hook_form_FORM_ID_alter() and because this + // is a workaround for hook_form_view_edit_form_alter() being insufficient, + // also invoke this on themes. + // @todo remove this after + // https://www.drupal.org/project/drupal/issues/3087455 has been resolved. + \Drupal::theme()->alter('views_ui_display_tab', $build, $view, $display_id); return $build; } @@ -776,6 +784,18 @@ public function renderDisplayTop(ViewUI $view) { ]; } + // In AJAX context, ViewUI::rebuildCurrentTab() returns this outside of form + // context, so hook_form_view_edit_form_alter() is insufficient. + // @todo remove this after + // https://www.drupal.org/project/drupal/issues/3087455 has been resolved. + \Drupal::moduleHandler()->alter('views_ui_display_top', $element, $view, $display_id); + // Because themes can implement hook_form_FORM_ID_alter() and because this + // is a workaround for hook_form_view_edit_form_alter() being insufficient, + // also invoke this on themes. + // @todo remove this after + // https://www.drupal.org/project/drupal/issues/3087455 has been resolved. + \Drupal::theme()->alter('views_ui_display_top', $element, $view, $display_id); + return $element; } diff --git a/core/modules/views_ui/tests/src/FunctionalJavascript/DisplayTest.php b/core/modules/views_ui/tests/src/FunctionalJavascript/DisplayTest.php index 5444eb93bc873ad12aac5cd81f70a4f9380ae7a3..6b7cd1226f88b7fb0215af123a57f27448a9b822 100644 --- a/core/modules/views_ui/tests/src/FunctionalJavascript/DisplayTest.php +++ b/core/modules/views_ui/tests/src/FunctionalJavascript/DisplayTest.php @@ -122,4 +122,29 @@ protected function toggleContextualTriggerVisibility($selector) { $this->getSession()->executeScript("jQuery('{$selector} .contextual .trigger').toggleClass('visually-hidden');"); } + /** + * Confirms that form_alter is triggered after ajax rebuilds. + */ + public function testAjaxRebuild() { + \Drupal::service('theme_installer')->install(['views_test_classy_subtheme']); + + $this->config('system.theme') + ->set('default', 'views_test_classy_subtheme') + ->save(); + + $page = $this->getSession()->getPage(); + $assert_session = $this->assertSession(); + + $this->drupalGet('admin/structure/views/view/content'); + $assert_session->pageTextContains('This is text added to the display tabs at the top'); + $assert_session->pageTextContains('This is text added to the display edit form'); + $page->clickLink('Content: Title (Title)'); + $assert_session->waitForElementVisible('css', '.views-ui-dialog'); + $page->fillField('Label', 'New Title'); + $page->find('css', '.ui-dialog-buttonset button:contains("Apply")')->press(); + $assert_session->waitForElementRemoved('css', '.views-ui-dialog'); + $assert_session->pageTextContains('This is text added to the display tabs at the top'); + $assert_session->pageTextContains('This is text added to the display edit form'); + } + } diff --git a/core/modules/views_ui/tests/themes/views_test_classy_subtheme/views_test_classy_subtheme.info.yml b/core/modules/views_ui/tests/themes/views_test_classy_subtheme/views_test_classy_subtheme.info.yml new file mode 100644 index 0000000000000000000000000000000000000000..fbac46814d9f981478dd084e28d5a9c5e9057c07 --- /dev/null +++ b/core/modules/views_ui/tests/themes/views_test_classy_subtheme/views_test_classy_subtheme.info.yml @@ -0,0 +1,6 @@ +name: 'Theme test subtheme' +type: theme +description: 'Test theme which uses test_basetheme as the base theme.' +version: VERSION +core: 8.x +base theme: classy diff --git a/core/modules/views_ui/tests/themes/views_test_classy_subtheme/views_test_classy_subtheme.theme b/core/modules/views_ui/tests/themes/views_test_classy_subtheme/views_test_classy_subtheme.theme new file mode 100644 index 0000000000000000000000000000000000000000..5e28fe1d241d131395fee70f4410ef7498b443df --- /dev/null +++ b/core/modules/views_ui/tests/themes/views_test_classy_subtheme/views_test_classy_subtheme.theme @@ -0,0 +1,22 @@ +<?php + +/** + * @file + * Implements Views UI alter hooks in a theme to provide test coverage. + */ + +use Drupal\views_ui\ViewUI; + +/** + * Implements hook_views_ui_display_tab_alter(). + */ +function views_test_classy_subtheme_views_ui_display_tab_alter(&$build, ViewUI $view, $display_id) { + $build['details']['top']['display_title']['#description'] = 'This is text added to the display edit form'; +} + +/** + * Implements hook_views_ui_display_top_alter(). + */ +function views_test_classy_subtheme_views_ui_display_top_alter(&$build, ViewUI $view, $display_id) { + $build['tabs']['#suffix'] .= 'This is text added to the display tabs at the top'; +} diff --git a/core/modules/views_ui/views_ui.api.php b/core/modules/views_ui/views_ui.api.php new file mode 100644 index 0000000000000000000000000000000000000000..b220fb2cc2d9eecf05250e93c834d33649cdf544 --- /dev/null +++ b/core/modules/views_ui/views_ui.api.php @@ -0,0 +1,59 @@ +<?php + +/** + * @file + * Describes hooks provided by the Views UI module. + */ + +/** + * @addtogroup hooks + * @{ + */ + +/** + * Alter the top of the display for the Views UI. + * + * This hook can be implemented by themes. + * + * @param array[] $build + * Render array for the display top. + * @param \Drupal\views_ui\ViewUI $view + * The view being edited. + * @param string $display_id + * The display ID. + * + * @todo Until https://www.drupal.org/project/drupal/issues/3087455 is resolved, + * use this hook or hook_views_ui_display_tab_alter() instead of + * hook_form_view_edit_form_alter(). + * + * @see \Drupal\views_ui\ViewUI::renderDisplayTop() + */ +function hook_views_ui_display_top_alter(&$build, \Drupal\views_ui\ViewUI $view, $display_id) { + $build['custom']['#markup'] = 'This text should always appear'; +} + +/** + * Alter the renderable array representing the edit page for one display. + * + * This hook can be implemented by themes. + * + * @param array[] $build + * Render array for the tab contents. + * @param \Drupal\views_ui\ViewUI $view + * The view being edited. + * @param string $display_id + * The display ID. + * + * @todo Until https://www.drupal.org/project/drupal/issues/3087455 is resolved, + * use this hook or hook_views_ui_display_tab_alter() instead of + * hook_form_view_edit_form_alter(). + * + * @see \Drupal\views_ui\ViewEditForm::getDisplayTab() + */ +function hook_views_ui_display_tab_alter(&$build, \Drupal\views_ui\ViewUI $view, $display_id) { + $build['custom']['#markup'] = 'This text should always appear'; +} + +/** + * @} End of "addtogroup hooks". + */