diff --git a/core/lib/Drupal/Core/Render/Renderer.php b/core/lib/Drupal/Core/Render/Renderer.php index 09a1bf1..e5a832f 100644 --- a/core/lib/Drupal/Core/Render/Renderer.php +++ b/core/lib/Drupal/Core/Render/Renderer.php @@ -506,10 +506,10 @@ protected function doRender(&$elements, $is_root_call = FALSE) { // We store the resulting output in $elements['#markup'], to be consistent // with how render cached output gets stored. This ensures that placeholder - // replacement logic gets the same data to work with, no matter if #cache is - // disabled, #cache is enabled, there is a cache hit or miss. - $prefix = isset($elements['#prefix']) ? $this->xssFilterAdminIfUnsafe($elements['#prefix']) : ''; - $suffix = isset($elements['#suffix']) ? $this->xssFilterAdminIfUnsafe($elements['#suffix']) : ''; + // Only apply the prefix and suffix markup around the children if they have + // not already been rendered by the theme manager. + $prefix = !isset($elements['#render_children']) && isset($elements['#prefix']) ? $this->xssFilterAdminIfUnsafe($elements['#prefix']) : ''; + $suffix = !isset($elements['#render_children']) && isset($elements['#suffix']) ? $this->xssFilterAdminIfUnsafe($elements['#suffix']) : ''; $elements['#markup'] = Markup::create($prefix . $elements['#children'] . $suffix); diff --git a/core/modules/file/src/Tests/FileFieldValidateTest.php b/core/modules/file/src/Tests/FileFieldValidateTest.php index 9d43060..de3b1c5 100644 --- a/core/modules/file/src/Tests/FileFieldValidateTest.php +++ b/core/modules/file/src/Tests/FileFieldValidateTest.php @@ -71,8 +71,10 @@ function testFileMaxSize() { $field_name = strtolower($this->randomMachineName()); $this->createFileField($field_name, 'node', $type_name, array(), array('required' => '1')); - $small_file = $this->getTestFile('text', 131072); // 128KB. - $large_file = $this->getTestFile('text', 1310720); // 1.2MB + // 128KB. + $small_file = $this->getTestFile('text', 131072); + // 1.2MB. + $large_file = $this->getTestFile('text', 1310720); // Test uploading both a large and small file with different increments. $sizes = array( @@ -185,4 +187,25 @@ public function testFileRemoval() { $this->assertText('Article ' . $node->getTitle() . ' has been updated.'); } + /** + * Test the validation message is displayed only once for ajax uploads. + */ + public function testAJAXValidationMessage() { + $field_name = strtolower($this->randomMachineName()); + $this->createFileField($field_name, 'node', 'article'); + + $this->drupalGet('node/add/article'); + /** @var \Drupal\file\FileInterface $image_file */ + $image_file = $this->getTestFile('image'); + $edit = array( + 'files[' . $field_name . '_0]' => $this->container->get('file_system')->realpath($image_file->getFileUri()), + 'title[0][value]' => $this->randomMachineName(), + ); + $this->drupalPostAjaxForm(NULL, $edit, $field_name . '_0_upload_button'); + $elements = $this->xpath('//div[contains(@class, :class)]', array( + ':class' => 'messages--error', + )); + $this->assertEqual(count($elements), 1, 'Ajax validation messages are displayed once.'); + } + } diff --git a/core/modules/image/src/Tests/ImageFieldValidateTest.php b/core/modules/image/src/Tests/ImageFieldValidateTest.php index 2532524..c48f3b6 100644 --- a/core/modules/image/src/Tests/ImageFieldValidateTest.php +++ b/core/modules/image/src/Tests/ImageFieldValidateTest.php @@ -8,6 +8,7 @@ * @group image */ class ImageFieldValidateTest extends ImageFieldTestBase { + /** * Test min/max resolution settings. */ @@ -102,4 +103,26 @@ function testRequiredAttributes() { $this->assertNoText(t('Title field is required.')); } + /** + * Test the validation message is displayed only once for ajax uploads. + */ + public function testAJAXValidationMessage() { + $field_name = strtolower($this->randomMachineName()); + $this->createImageField($field_name, 'article'); + + $this->drupalGet('node/add/article'); + /** @var \Drupal\file\FileInterface[] $text_files */ + $text_files = $this->drupalGetTestFiles('text'); + $text_file = reset($text_files); + $edit = array( + 'files[' . $field_name . '_0]' => $this->container->get('file_system')->realpath($text_file->uri), + 'title[0][value]' => $this->randomMachineName(), + ); + $this->drupalPostAjaxForm(NULL, $edit, $field_name . '_0_upload_button'); + $elements = $this->xpath('//div[contains(@class, :class)]', array( + ':class' => 'messages--error', + )); + $this->assertEqual(count($elements), 1, 'Ajax validation messages are displayed once.'); + } + }