/**
  * {@inheritdoc}
  */
 public function viewElements(FieldItemListInterface $items, $langcode)
 {
     $elements = parent::viewElements($items, $langcode);
     // Unset #item_attributes to test that the theme function can handle that.
     foreach ($elements as &$element) {
         if (isset($element['#item_attributes'])) {
             unset($element['#item_attributes']);
         }
     }
     return $elements;
 }
 /**
  * Test responsive image formatters on node display.
  *
  * If the empty styles param is set, then the function only tests for the
  * fallback image style (large).
  *
  * @param string $scheme
  *   File scheme to use.
  * @param bool $empty_styles
  *   If true, use an empty string for image style names.
  *   Defaults to false.
  */
 protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles = FALSE)
 {
     /** @var \Drupal\Core\Render\RendererInterface $renderer */
     $renderer = $this->container->get('renderer');
     $node_storage = $this->container->get('entity.manager')->getStorage('node');
     $field_name = Unicode::strtolower($this->randomMachineName());
     $this->createImageField($field_name, 'article', array('uri_scheme' => $scheme));
     // Create a new node with an image attached. Make sure we use a large image
     // so the scale effects of the image styles always have an effect.
     $test_image = current($this->drupalGetTestFiles('image', 39325));
     // Create alt text for the image.
     $alt = $this->randomMachineName();
     $nid = $this->uploadNodeImage($test_image, $field_name, 'article', $alt);
     $node_storage->resetCache(array($nid));
     $node = $node_storage->load($nid);
     // Test that the default formatter is being used.
     $image_uri = File::load($node->{$field_name}->target_id)->getFileUri();
     $image = array('#theme' => 'image', '#uri' => $image_uri, '#width' => 360, '#height' => 240, '#alt' => $alt);
     $default_output = str_replace("\n", NULL, $renderer->renderRoot($image));
     $this->assertRaw($default_output, 'Default formatter displaying correctly on full node view.');
     // Test field not being configured. This should not cause a fatal error.
     $display_options = array('type' => 'responsive_image_test', 'settings' => ResponsiveImageFormatter::defaultSettings());
     $display = $this->container->get('entity.manager')->getStorage('entity_view_display')->load('node.article.default');
     if (!$display) {
         $values = ['targetEntityType' => 'node', 'bundle' => 'article', 'mode' => 'default', 'status' => TRUE];
         $display = $this->container->get('entity.manager')->getStorage('entity_view_display')->create($values);
     }
     $display->setComponent($field_name, $display_options)->save();
     $this->drupalGet('node/' . $nid);
     // Test theme function for responsive image, but using the test formatter.
     $display_options = array('type' => 'responsive_image_test', 'settings' => array('image_link' => 'file', 'responsive_image_style' => 'style_one'));
     $display = entity_get_display('node', 'article', 'default');
     $display->setComponent($field_name, $display_options)->save();
     $this->drupalGet('node/' . $nid);
     // Use the responsive image formatter linked to file formatter.
     $display_options = array('type' => 'responsive_image', 'settings' => array('image_link' => 'file', 'responsive_image_style' => 'style_one'));
     $display = entity_get_display('node', 'article', 'default');
     $display->setComponent($field_name, $display_options)->save();
     $default_output = '<a href="' . file_url_transform_relative(file_create_url($image_uri)) . '"><picture';
     $this->drupalGet('node/' . $nid);
     $cache_tags_header = $this->drupalGetHeader('X-Drupal-Cache-Tags');
     $this->assertTrue(!preg_match('/ image_style\\:/', $cache_tags_header), 'No image style cache tag found.');
     $this->removeWhiteSpace();
     $this->assertRaw($default_output, 'Image linked to file formatter displaying correctly on full node view.');
     // Verify that the image can be downloaded.
     $this->assertEqual(file_get_contents($test_image->uri), $this->drupalGet(file_create_url($image_uri)), 'File was downloaded successfully.');
     if ($scheme == 'private') {
         // Only verify HTTP headers when using private scheme and the headers are
         // sent by Drupal.
         $this->assertEqual($this->drupalGetHeader('Content-Type'), 'image/png', 'Content-Type header was sent.');
         $this->assertTrue(strstr($this->drupalGetHeader('Cache-Control'), 'private') !== FALSE, 'Cache-Control header was sent.');
         // Log out and try to access the file.
         $this->drupalLogout();
         $this->drupalGet(file_create_url($image_uri));
         $this->assertResponse('403', 'Access denied to original image as anonymous user.');
         // Log in again.
         $this->drupalLogin($this->adminUser);
     }
     // Use the responsive image formatter with a responsive image style.
     $display_options['settings']['responsive_image_style'] = 'style_one';
     $display_options['settings']['image_link'] = '';
     $display->setComponent($field_name, $display_options)->save();
     // Create a derivative so at least one MIME type will be known.
     $large_style = ImageStyle::load('large');
     $large_style->createDerivative($image_uri, $large_style->buildUri($image_uri));
     // Output should contain all image styles and all breakpoints.
     $this->drupalGet('node/' . $nid);
     if (!$empty_styles) {
         $this->assertRaw('/styles/medium/');
         // Make sure the IE9 workaround is present.
         $this->assertRaw('<!--[if IE 9]><video style="display: none;"><![endif]-->');
         $this->assertRaw('<!--[if IE 9]></video><![endif]-->');
         // Assert the empty image is present.
         $this->assertRaw('data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==');
         $thumbnail_style = ImageStyle::load('thumbnail');
         // Assert the output of the 'srcset' attribute (small multipliers first).
         $this->assertRaw('data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== 1x, ' . file_url_transform_relative($thumbnail_style->buildUrl($image_uri)) . ' 1.5x');
         $this->assertRaw('/styles/medium/');
         // Assert the output of the original image.
         $this->assertRaw(file_url_transform_relative(file_create_url($image_uri)) . ' 3x');
         // Assert the output of the breakpoints.
         $this->assertRaw('media="(min-width: 0px)"');
         $this->assertRaw('media="(min-width: 560px)"');
         // Assert the output of the 'sizes' attribute.
         $this->assertRaw('sizes="(min-width: 700px) 700px, 100vw"');
         $this->assertPattern('/media="\\(min-width: 560px\\)".+?sizes="\\(min-width: 700px\\) 700px, 100vw"/');
         // Assert the output of the 'srcset' attribute (small images first).
         $medium_style = ImageStyle::load('medium');
         $this->assertRaw(file_url_transform_relative($medium_style->buildUrl($image_uri)) . ' 220w, ' . file_url_transform_relative($large_style->buildUrl($image_uri)) . ' 360w');
         $this->assertRaw('media="(min-width: 851px)"');
     }
     $this->assertRaw('/styles/large/');
     $cache_tags = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Tags'));
     $this->assertTrue(in_array('config:responsive_image.styles.style_one', $cache_tags));
     if (!$empty_styles) {
         $this->assertTrue(in_array('config:image.style.medium', $cache_tags));
         $this->assertTrue(in_array('config:image.style.thumbnail', $cache_tags));
         $this->assertRaw('type="image/png"');
     }
     $this->assertTrue(in_array('config:image.style.large', $cache_tags));
     // Test the fallback image style.
     $image = \Drupal::service('image.factory')->get($image_uri);
     $fallback_image = array('#theme' => 'image', '#alt' => $alt, '#srcset' => array(array('uri' => file_url_transform_relative($large_style->buildUrl($image->getSource())))));
     // The image.html.twig template has a newline after the <img> tag but
     // responsive-image.html.twig doesn't have one after the fallback image, so
     // we remove it here.
     $default_output = trim($renderer->renderRoot($fallback_image));
     $this->assertRaw($default_output, 'Image style large formatter displaying correctly on full node view.');
     if ($scheme == 'private') {
         // Log out and try to access the file.
         $this->drupalLogout();
         $this->drupalGet($large_style->buildUrl($image_uri));
         $this->assertResponse('403', 'Access denied to image style large as anonymous user.');
         $cache_tags_header = $this->drupalGetHeader('X-Drupal-Cache-Tags');
         $this->assertTrue(!preg_match('/ image_style\\:/', $cache_tags_header), 'No image style cache tag found.');
     }
 }
 /**
  * {@inheritdoc}
  */
 public static function isApplicable(FieldDefinitionInterface $field_definition)
 {
     // This formatter only applies to multi-image fields
     return parent::isApplicable($field_definition) && $field_definition->getFieldStorageDefinition()->isMultiple();
 }