From 5fb617d7ac1335c9a5cefddc1bba11c204f4a5ed Mon Sep 17 00:00:00 2001 From: Dries <dries@buytaert.net> Date: Thu, 27 Feb 2014 20:52:40 +0100 Subject: [PATCH] Issue #1938926 by sun, Cottser, joelpittet, pplantinga: Convert simpletest theme tables to table #type. --- core/includes/common.inc | 43 +++-- core/includes/form.inc | 91 ++++++++--- .../simpletest/css/simpletest.module.css | 2 +- .../simpletest/Form/SimpletestTestForm.php | 144 ++++++++++++++--- .../simpletest/Tests/BrokenSetUpTest.php | 6 +- .../InstallationProfileModuleTestsTest.php | 2 +- .../Tests/MissingCheckedRequirementsTest.php | 2 +- .../simpletest/Tests/SimpleTestTest.php | 2 +- core/modules/simpletest/simpletest.module | 8 +- core/modules/simpletest/simpletest.theme.inc | 148 ------------------ core/modules/system/system.module | 3 + 11 files changed, 236 insertions(+), 215 deletions(-) diff --git a/core/includes/common.inc b/core/includes/common.inc index 1a98d8a95a61..5a84f53695a6 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -1921,18 +1921,7 @@ function drupal_html_id($id) { } $seen_ids = &drupal_static(__FUNCTION__, $seen_ids_init); - $id = strtr(drupal_strtolower($id), array(' ' => '-', '_' => '-', '[' => '-', ']' => '')); - - // As defined in http://www.w3.org/TR/html4/types.html#type-name, HTML IDs can - // only contain letters, digits ([0-9]), hyphens ("-"), underscores ("_"), - // colons (":"), and periods ("."). We strip out any character not in that - // list. Note that the CSS spec doesn't allow colons or periods in identifiers - // (http://www.w3.org/TR/CSS21/syndata.html#characters), so we strip those two - // characters as well. - $id = preg_replace('/[^A-Za-z0-9\-_]/', '', $id); - - // Removing multiple consecutive hyphens. - $id = preg_replace('/\-+/', '-', $id); + $id = drupal_clean_id_identifier($id); // Ensure IDs are unique by appending a counter after the first occurrence. // The counter needs to be appended with a delimiter that does not exist in // the base ID. Requiring a unique delimiter helps ensure that we really do @@ -1948,6 +1937,36 @@ function drupal_html_id($id) { return $id; } +/** + * Prepares a string for use as a valid HTML ID. + * + * Only use this function when you want to intentionally skip the uniqueness + * guarantee of drupal_html_id(). + * + * @param string $id + * The ID to clean. + * + * @return string + * The cleaned ID. + * + * @see drupal_html_id() + */ +function drupal_clean_id_identifier($id) { + $id = strtr(drupal_strtolower($id), array(' ' => '-', '_' => '-', '[' => '-', ']' => '')); + + // As defined in http://www.w3.org/TR/html4/types.html#type-name, HTML IDs can + // only contain letters, digits ([0-9]), hyphens ("-"), underscores ("_"), + // colons (":"), and periods ("."). We strip out any character not in that + // list. Note that the CSS spec doesn't allow colons or periods in identifiers + // (http://www.w3.org/TR/CSS21/syndata.html#characters), so we strip those two + // characters as well. + $id = preg_replace('/[^A-Za-z0-9\-_]/', '', $id); + + // Removing multiple consecutive hyphens. + $id = preg_replace('/\-+/', '-', $id); + return $id; +} + /** * Adds a JavaScript file, setting, or inline code to the page. * diff --git a/core/includes/form.inc b/core/includes/form.inc index 15c6634d8fbd..8636c1a1fb64 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -1785,52 +1785,81 @@ function form_process_table($element, &$form_state) { // tableselect element behaves as if it had been of #type checkboxes or // radios. foreach (element_children($element) as $key) { + $row = &$element[$key]; + // Prepare the element #parents for the tableselect form element. + // Their values have to be located in child keys (#tree is ignored), since + // form_validate_table() has to be able to validate whether input (for the + // parent #type 'table' element) has been submitted. + $element_parents = array_merge($element['#parents'], array($key)); + + // Since the #parents of the tableselect form element will equal the + // #parents of the row element, prevent FormBuilder from auto-generating + // an #id for the row element, since drupal_html_id() would automatically + // append a suffix to the tableselect form element's #id otherwise. + $row['#id'] = drupal_html_id('edit-' . implode('-', $element_parents) . '-row'); + // Do not overwrite manually created children. - if (!isset($element[$key]['select'])) { + if (!isset($row['select'])) { // Determine option label; either an assumed 'title' column, or the // first available column containing a #title or #markup. // @todo Consider to add an optional $element[$key]['#title_key'] // defaulting to 'title'? - $title = ''; - if (!empty($element[$key]['title']['#title'])) { - $title = $element[$key]['title']['#title']; + unset($label_element); + $title = NULL; + if (isset($row['title']['#type']) && $row['title']['#type'] == 'label') { + $label_element = &$row['title']; } else { - foreach (element_children($element[$key]) as $column) { - if (isset($element[$key][$column]['#title'])) { - $title = $element[$key][$column]['#title']; - break; - } - if (isset($element[$key][$column]['#markup'])) { - $title = $element[$key][$column]['#markup']; - break; + if (!empty($row['title']['#title'])) { + $title = $row['title']['#title']; + } + else { + foreach (element_children($row) as $column) { + if (isset($row[$column]['#title'])) { + $title = $row[$column]['#title']; + break; + } + if (isset($row[$column]['#markup'])) { + $title = $row[$column]['#markup']; + break; + } } } - } - if ($title !== '') { - $title = t('Update !title', array('!title' => $title)); + if (isset($title) && $title !== '') { + $title = t('Update !title', array('!title' => $title)); + } } // Prepend the select column to existing columns. - $element[$key] = array('select' => array()) + $element[$key]; - $element[$key]['select'] += array( + $row = array('select' => array()) + $row; + $row['select'] += array( '#type' => $element['#multiple'] ? 'checkbox' : 'radio', - '#title' => $title, - '#title_display' => 'invisible', + '#id' => drupal_html_id('edit-' . implode('-', $element_parents)), // @todo If rows happen to use numeric indexes instead of string keys, // this results in a first row with $key === 0, which is always FALSE. '#return_value' => $key, '#attributes' => $element['#attributes'], + '#wrapper_attributes' => array( + 'class' => array('table-select'), + ), ); - $element_parents = array_merge($element['#parents'], array($key)); if ($element['#multiple']) { - $element[$key]['select']['#default_value'] = isset($value[$key]) ? $key : NULL; - $element[$key]['select']['#parents'] = $element_parents; + $row['select']['#default_value'] = isset($value[$key]) ? $key : NULL; + $row['select']['#parents'] = $element_parents; } else { - $element[$key]['select']['#default_value'] = ($element['#default_value'] == $key ? $key : NULL); - $element[$key]['select']['#parents'] = $element['#parents']; - $element[$key]['select']['#id'] = drupal_html_id('edit-' . implode('-', $element_parents)); + $row['select']['#default_value'] = ($element['#default_value'] == $key ? $key : NULL); + $row['select']['#parents'] = $element['#parents']; + } + if ($label_element) { + $label_element['#id'] = $row['select']['#id'] . '--label'; + $label_element['#for'] = $row['select']['#id']; + $row['select']['#attributes']['aria-labelledby'] = $label_element['#id']; + $row['select']['#title_display'] = 'none'; + } + else { + $row['select']['#title'] = $title; + $row['select']['#title_display'] = 'invisible'; } } } @@ -2958,7 +2987,17 @@ function theme_form_element_label($variables) { $attributes['class'] = 'visually-hidden'; } - if (!empty($element['#id'])) { + // A #for property of a dedicated #type 'label' element as precedence. + if (!empty($element['#for'])) { + $attributes['for'] = $element['#for']; + // A custom #id allows the referenced form input element to refer back to + // the label element; e.g., in the 'aria-labelledby' attribute. + if (!empty($element['#id'])) { + $attributes['id'] = $element['#id']; + } + } + // Otherwise, point to the #id of the form input element. + elseif (!empty($element['#id'])) { $attributes['for'] = $element['#id']; } diff --git a/core/modules/simpletest/css/simpletest.module.css b/core/modules/simpletest/css/simpletest.module.css index 86bd04b07869..611cc4a92b22 100644 --- a/core/modules/simpletest/css/simpletest.module.css +++ b/core/modules/simpletest/css/simpletest.module.css @@ -3,7 +3,7 @@ #simpletest-form-table th.select-all { width: 1em; } -th.simpletest_test { +th.simpletest-test-label { width: 16em; } diff --git a/core/modules/simpletest/lib/Drupal/simpletest/Form/SimpletestTestForm.php b/core/modules/simpletest/lib/Drupal/simpletest/Form/SimpletestTestForm.php index acef8285442b..85dc889878c2 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/Form/SimpletestTestForm.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/Form/SimpletestTestForm.php @@ -7,6 +7,8 @@ namespace Drupal\simpletest\Form; +use Drupal\Component\Utility\SortArray; +use Drupal\Component\Utility\String; use Drupal\Core\Form\FormBase; /** @@ -46,14 +48,45 @@ public function buildForm(array $form, array &$form_state) { ); $form['tests'] = array( - '#type' => 'details', - '#title' => $this->t('Tests'), - '#open' => TRUE, - '#description' => $this->t('Select the test(s) or test group(s) you would like to run, and click <em>Run tests</em>.'), + '#type' => 'table', + '#id' => 'simpletest-form-table', + '#tableselect' => TRUE, + '#header' => array( + array('data' => $this->t('Test'), 'class' => array('simpletest-test-label')), + array('data' => $this->t('Description'), 'class' => array('simpletest-test-description')), + ), + '#empty' => $this->t('No tests to display.'), + '#attached' => array( + 'library' => array( + array('simpletest', 'drupal.simpletest'), + ), + ), ); - $form['tests']['table'] = array( - '#theme' => 'simpletest_test_table', + // Define the images used to expand/collapse the test groups. + $image_collapsed = array( + '#theme' => 'image', + '#uri' => 'core/misc/menu-collapsed.png', + '#width' => '7', + '#height' => '7', + '#alt' => $this->t('Expand'), + '#title' => $this->t('Expand'), + '#suffix' => '<a href="#" class="simpletest-collapse">(' . $this->t('Expand') . ')</a>', + ); + $image_extended = array( + '#theme' => 'image', + '#uri' => 'core/misc/menu-expanded.png', + '#width' => '7', + '#height' => '7', + '#alt' => $this->t('Collapse'), + '#title' => $this->t('Collapse'), + '#suffix' => '<a href="#" class="simpletest-collapse">(' . $this->t('Collapse') . ')</a>', + ); + $js = array( + 'images' => array( + drupal_render($image_collapsed), + drupal_render($image_extended), + ), ); // Generate the list of tests arranged by group. @@ -62,24 +95,103 @@ public function buildForm(array $form, array &$form_state) { $form_state['storage']['PHPUnit'] = $groups['PHPUnit']; foreach ($groups as $group => $tests) { + $form['tests'][$group] = array( + '#attributes' => array('class' => array('simpletest-group')), + ); + + // Make the class name safe for output on the page by replacing all + // non-word/decimal characters with a dash (-). + $group_class = 'module-' . strtolower(trim(preg_replace("/[^\w\d]/", "-", $group))); + + // Override tableselect column with custom selector for this group. + // This group-select-all checkbox is injected via JavaScript. + $form['tests'][$group]['select'] = array( + '#wrapper_attributes' => array( + 'id' => $group_class, + 'class' => array('simpletest-select-all'), + ), + ); + $form['tests'][$group]['title'] = array( + // Expand/collapse image. + '#prefix' => '<div class="simpletest-image" id="simpletest-test-group-' . $group_class . '"></div>', + '#markup' => '<label for="' . $group_class . '-select-all" class="simpletest-group-label">' . $group . '</label>', + '#wrapper_attributes' => array( + 'class' => array('simpletest-group-label'), + ), + ); + $form['tests'][$group]['description'] = array( + '#markup' => ' ', + '#wrapper_attributes' => array( + 'class' => array('simpletest-group-description'), + ), + ); + + // Add individual tests to group. + $current_js = array( + 'testClass' => $group_class . '-test', + 'testNames' => array(), + // imageDirection maps to the 'images' index in the $js array. + 'imageDirection' => 0, + 'clickActive' => FALSE, + ); + + // Sort test classes within group alphabetically by name/label. + uasort($tests, function ($a, $b) { + return SortArray::sortByKeyString($a, $b, 'name'); + }); + + // Cycle through each test within the current group. foreach ($tests as $class => $info) { - $form['tests']['table'][$group][$class] = array( - '#type' => 'checkbox', + $test_id = drupal_clean_id_identifier($class); + $test_checkbox_id = 'edit-tests-' . $test_id; + $current_js['testNames'][] = $test_checkbox_id; + + $form['tests'][$class] = array( + '#attributes' => array('class' => array($group_class . '-test', 'js-hide')), + ); + $form['tests'][$class]['title'] = array( + '#type' => 'label', '#title' => $info['name'], - '#description' => $info['description'], + '#wrapper_attributes' => array( + 'class' => array('simpletest-test-label', 'table-filter-text-source'), + ), + ); + $form['tests'][$class]['description'] = array( + '#prefix' => '<div class="description">', + '#markup' => String::format('@description (@class)', array( + '@description' => $info['description'], + '@class' => $class, + )), + '#suffix' => '</div>', + '#wrapper_attributes' => array( + 'class' => array('simpletest-test-description', 'table-filter-text-source'), + ), ); } + + $js['simpletest-test-group-' . $group_class] = $current_js; } + // Add JavaScript array of settings. + $form['tests']['#attached']['js'][] = array( + 'type' => 'setting', + 'data' => array('simpleTest' => $js), + ); + // Action buttons. - $form['tests']['op'] = array( + $form['actions'] = array('#type' => 'actions'); + $form['actions']['submit'] = array( '#type' => 'submit', '#value' => $this->t('Run tests'), + '#tableselect' => TRUE, + '#button_type' => 'primary', ); + $form['clean'] = array( '#type' => 'fieldset', '#title' => $this->t('Clean test environment'), '#description' => $this->t('Remove tables with the prefix "simpletest" and temporary directories that are left over from tests that crashed. This is intended for developers when creating tests.'), + '#weight' => 200, ); $form['clean']['op'] = array( '#type' => 'submit', @@ -94,21 +206,20 @@ public function buildForm(array $form, array &$form_state) { * {@inheritdoc} */ public function submitForm(array &$form, array &$form_state) { - // Get list of tests. - $tests_list = array(); simpletest_classloader_register(); $phpunit_all = array_keys($form_state['storage']['PHPUnit']); - foreach ($form_state['values'] as $class_name => $value) { + $tests_list = array(); + foreach ($form_state['values']['tests'] as $class_name => $value) { // Since class_exists() will likely trigger an autoload lookup, // we do the fast check first. - if ($value === 1 && class_exists($class_name)) { + if ($value === $class_name && class_exists($class_name)) { $test_type = in_array($class_name, $phpunit_all) ? 'UnitTest' : 'WebTest'; $tests_list[$test_type][] = $class_name; } } - if (count($tests_list) > 0 ) { + if (!empty($tests_list)) { $test_id = simpletest_run_tests($tests_list, 'drupal'); $form_state['redirect_route'] = array( 'route_name' => 'simpletest.result_form', @@ -117,9 +228,6 @@ public function submitForm(array &$form, array &$form_state) { ), ); } - else { - drupal_set_message($this->t('No test(s) selected.'), 'error'); - } } } diff --git a/core/modules/simpletest/lib/Drupal/simpletest/Tests/BrokenSetUpTest.php b/core/modules/simpletest/lib/Drupal/simpletest/Tests/BrokenSetUpTest.php index 898151917230..43f9443f0da9 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/Tests/BrokenSetUpTest.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/Tests/BrokenSetUpTest.php @@ -89,7 +89,7 @@ function testMethod() { if (!$this->isInChildSite()) { // Verify that a broken setUp() method is caught. file_put_contents($this->sharedTriggerFile, 'setup'); - $edit['Drupal\simpletest\Tests\BrokenSetUpTest'] = TRUE; + $edit['tests[Drupal\simpletest\Tests\BrokenSetUpTest]'] = TRUE; $this->drupalPostForm('admin/config/development/testing', $edit, t('Run tests')); $this->assertRaw('Broken setup'); $this->assertNoRaw('The setUp() method has run.'); @@ -100,7 +100,7 @@ function testMethod() { // Verify that a broken tearDown() method is caught. file_put_contents($this->sharedTriggerFile, 'teardown'); - $edit['Drupal\simpletest\Tests\BrokenSetUpTest'] = TRUE; + $edit['tests[Drupal\simpletest\Tests\BrokenSetUpTest]'] = TRUE; $this->drupalPostForm('admin/config/development/testing', $edit, t('Run tests')); $this->assertNoRaw('Broken setup'); $this->assertRaw('The setUp() method has run.'); @@ -111,7 +111,7 @@ function testMethod() { // Verify that a broken test method is caught. file_put_contents($this->sharedTriggerFile, 'test'); - $edit['Drupal\simpletest\Tests\BrokenSetUpTest'] = TRUE; + $edit['tests[Drupal\simpletest\Tests\BrokenSetUpTest]'] = TRUE; $this->drupalPostForm('admin/config/development/testing', $edit, t('Run tests')); $this->assertNoRaw('Broken setup'); $this->assertRaw('The setUp() method has run.'); diff --git a/core/modules/simpletest/lib/Drupal/simpletest/Tests/InstallationProfileModuleTestsTest.php b/core/modules/simpletest/lib/Drupal/simpletest/Tests/InstallationProfileModuleTestsTest.php index 911c824c32c8..994fb3613af0 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/Tests/InstallationProfileModuleTestsTest.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/Tests/InstallationProfileModuleTestsTest.php @@ -57,7 +57,7 @@ function testInstallationProfileTests() { $this->drupalGet('admin/config/development/testing'); $this->assertText('Installation profile module tests helper'); $edit = array( - 'Drupal\drupal_system_listing_compatible_test\Tests\SystemListingCompatibleTest' => TRUE, + 'tests[Drupal\drupal_system_listing_compatible_test\Tests\SystemListingCompatibleTest]' => TRUE, ); $this->drupalPostForm(NULL, $edit, t('Run tests')); $this->assertText('SystemListingCompatibleTest test executed.'); diff --git a/core/modules/simpletest/lib/Drupal/simpletest/Tests/MissingCheckedRequirementsTest.php b/core/modules/simpletest/lib/Drupal/simpletest/Tests/MissingCheckedRequirementsTest.php index 24b43483954d..0f63734b4e5d 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/Tests/MissingCheckedRequirementsTest.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/Tests/MissingCheckedRequirementsTest.php @@ -55,7 +55,7 @@ protected function testCheckRequirements() { // that the child tests did not run. if (!$this->isInChildSite()) { // Run this test from web interface. - $edit['Drupal\simpletest\Tests\MissingCheckedRequirementsTest'] = TRUE; + $edit['tests[Drupal\simpletest\Tests\MissingCheckedRequirementsTest]'] = TRUE; $this->drupalPostForm('admin/config/development/testing', $edit, t('Run tests')); $this->assertRaw('Test is not allowed to run.', 'Test check for requirements came up.'); $this->assertNoText('Test ran when it failed requirements check.', 'Test requirements stopped test from running.'); diff --git a/core/modules/simpletest/lib/Drupal/simpletest/Tests/SimpleTestTest.php b/core/modules/simpletest/lib/Drupal/simpletest/Tests/SimpleTestTest.php index 4a105467602b..488b9a707422 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/Tests/SimpleTestTest.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/Tests/SimpleTestTest.php @@ -162,7 +162,7 @@ function testWebTestRunner() { $this->drupalGet('admin/config/development/testing'); $edit = array(); - $edit['Drupal\simpletest\Tests\SimpleTestTest'] = TRUE; + $edit['tests[Drupal\simpletest\Tests\SimpleTestTest]'] = TRUE; $this->drupalPostForm(NULL, $edit, t('Run tests')); // Parse results and confirm that they are correct. diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module index f7e375aaf018..3a18a9e15304 100644 --- a/core/modules/simpletest/simpletest.module +++ b/core/modules/simpletest/simpletest.module @@ -26,6 +26,10 @@ function simpletest_help($path, $arg) { $output .= '<p>' . t('After the tests run, a message will be displayed next to each test group indicating whether tests within it passed, failed, or had exceptions. A pass means that the test returned the expected results, while fail means that it did not. An exception normally indicates an error outside of the test, such as a PHP warning or notice. If there were failures or exceptions, the results will be expanded to show details, and the tests that had failures or exceptions will be indicated in red or pink rows. You can then use these results to refine your code and tests, until all tests pass.') . '</p></dd>'; $output .= '</dl>'; return $output; + + case 'admin/config/development/testing': + $output = t('Select the test(s) or test group(s) you would like to run, and click <em>Run tests</em>.'); + return $output; } } @@ -61,10 +65,6 @@ function simpletest_permission() { */ function simpletest_theme() { return array( - 'simpletest_test_table' => array( - 'render element' => 'table', - 'file' => 'simpletest.theme.inc', - ), 'simpletest_result_summary' => array( 'render element' => 'form', 'file' => 'simpletest.theme.inc', diff --git a/core/modules/simpletest/simpletest.theme.inc b/core/modules/simpletest/simpletest.theme.inc index 59fed6616642..9890c620afe0 100644 --- a/core/modules/simpletest/simpletest.theme.inc +++ b/core/modules/simpletest/simpletest.theme.inc @@ -5,154 +5,6 @@ * Page callbacks for simpletest module. */ -/** - * Returns an HTML table for a test list generated by simpletest_test_form(). - * - * @param $variables - * An associative array containing: - * - table: A render element representing the table. - * - * @ingroup themeable - */ -function theme_simpletest_test_table($variables) { - $table = $variables['table']; - - drupal_add_library('simpletest', 'drupal.simpletest'); - - // Create header for test selection table. - $header = array( - array('class' => array('select-all')), - array('data' => t('Test'), 'class' => array('simpletest_test')), - array('data' => t('Description'), 'class' => array('simpletest_description')), - ); - - // Define the images used to expand/collapse the test groups. - $image_collapsed = array( - '#theme' => 'image', - '#uri' => 'core/misc/menu-collapsed.png', - '#width' => '7', - '#height' => '7', - '#alt' => t('Expand'), - '#title' => t('Expand'), - '#suffix' => '<a href="#" class="simpletest-collapse">(' . t('Expand') . ')</a>', - ); - $image_extended = array( - '#theme' => 'image', - '#uri' => 'core/misc/menu-expanded.png', - '#width' => '7', - '#height' => '7', - '#alt' => t('Collapse'), - '#title' => t('Collapse'), - '#suffix' => ' <a href="#" class="simpletest-collapse">(' . t('Collapse') . ')</a>', - ); - $js = array( - 'images' => array( - drupal_render($image_collapsed), - drupal_render($image_extended), - ), - ); - - // Cycle through each test group and create a row. - $rows = array(); - foreach (element_children($table) as $key) { - $element = &$table[$key]; - $row = array(); - - // Make the class name safe for output on the page by replacing all - // non-word/decimal characters with a dash (-). - $test_class = 'module-' . strtolower(trim(preg_replace("/[^\w\d]/", "-", $key))); - - // Select the right "expand"/"collapse" image, depending on whether the - // category is expanded (at least one test selected) or not. - $open = !empty($element['#open']); - $image_index = $open ? 1 : 0; - - // Place-holder for checkboxes to select group of tests. - $row[] = array('id' => $test_class, 'class' => array('simpletest-select-all')); - - // Expand/collapse image and group title. - $row[] = array( - 'data' => '<div class="simpletest-image" id="simpletest-test-group-' . $test_class . '"></div>' . - '<label for="' . $test_class . '-select-all" class="simpletest-group-label">' . $key . '</label>', - 'class' => array('simpletest-group-label'), - ); - - $row[] = array( - 'data' => ' ', - 'class' => array('simpletest-group-description'), - ); - - $rows[] = array('data' => $row, 'class' => array('simpletest-group')); - - // Add individual tests to group. - $current_js = array( - 'testClass' => $test_class . '-test', - 'testNames' => array(), - 'imageDirection' => $image_index, - 'clickActive' => FALSE, - ); - - // Sorting $element by children's #title attribute instead of by class name. - uasort($element, 'element_sort_by_title'); - - // Cycle through each test within the current group. - foreach (element_children($element) as $test_name) { - $test = $element[$test_name]; - $row = array(); - - $current_js['testNames'][] = $test['#id']; - - // Store test title and description so that checkbox won't render them. - $title = $test['#title']; - $description = $test['#description']; - - $test['#title_display'] = 'invisible'; - unset($test['#description']); - - // Test name is used to determine what tests to run. - $test['#name'] = $test_name; - - $row[] = array( - 'data' => drupal_render($test), - 'class' => array('simpletest-test-select'), - ); - $row[] = array( - 'data' => '<label for="' . $test['#id'] . '">' . $title . '</label>', - 'class' => array('simpletest-test-label', 'table-filter-text-source'), - ); - $row[] = array( - 'data' => '<div class="description">' . format_string('@description (@class)', array('@description' => $description, '@class' => $test_name)) . '</div>', - 'class' => array('simpletest-test-description', 'table-filter-text-source'), - ); - - $rows[] = array('data' => $row, 'class' => array($test_class . '-test', ($open ? '' : 'js-hide'))); - } - $js['simpletest-test-group-' . $test_class] = $current_js; - unset($table[$key]); - } - - // Add js array of settings. - $attached = array(); - $attached['#attached']['js'][] = array( - 'data' => array('simpleTest' => $js), - 'type' => 'setting', - ); - drupal_render($attached); - - if (empty($rows)) { - return '<strong>' . t('No tests to display.') . '</strong>'; - } - else { - $simpletest_form_table = array( - '#theme' => 'table', - '#header' => $header, - '#rows' => $rows, - '#attributes' => array('id' => 'simpletest-form-table'), - ); - return drupal_render($simpletest_form_table); - } -} - /** * Returns HTML for the summary status of a simpletest result. * diff --git a/core/modules/system/system.module b/core/modules/system/system.module index ef3749110d3a..c85ab3c2e2fd 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -520,6 +520,9 @@ function system_element_info() { ); // Form structure. + $types['label'] = array( + '#theme' => 'form_element_label', + ); $types['item'] = array( // Forms that show author fields to both anonymous and authenticated users // need to dynamically switch between #type 'textfield' and #type 'item' to -- GitLab