Issue 3167034: Adressing heddn's comments
parent
4f628583a0
commit
b6a453dd08
|
@ -854,6 +854,7 @@ function template_preprocess_image(&$variables) {
|
|||
|
||||
// Without dimensions specified, layout shifts can occur,
|
||||
// which are more noticeable on pages that take some time to load.
|
||||
// As a result, only mark images as lazy load that have dimensions.
|
||||
if (isset($variables['width'], $variables['height'])) {
|
||||
$variables['attributes']['loading'] = 'lazy';
|
||||
}
|
||||
|
|
|
@ -82,10 +82,13 @@ class EditorFileReference extends FilterBase implements ContainerFactoryPluginIn
|
|||
if ($node->nodeName == 'img') {
|
||||
// Without dimensions specified, layout shifts can occur,
|
||||
// which are more noticeable on pages that take some time to load.
|
||||
list($width, $height) = getimagesize($file->getFileUri());
|
||||
$node->setAttribute('width', $width);
|
||||
$node->setAttribute('height', $height);
|
||||
$node->setAttribute('loading', 'lazy');
|
||||
// As a result, only mark images as lazy load that have dimensions.
|
||||
[$width, $height] = @getimagesize($file->getFileUri());
|
||||
if ($width != NULL && $height != NULL) {
|
||||
$node->setAttribute('width', $width);
|
||||
$node->setAttribute('height', $height);
|
||||
$node->setAttribute('loading', 'lazy');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,9 @@
|
|||
|
||||
namespace Drupal\Tests\editor\Functional;
|
||||
|
||||
use Drupal\Core\File\FileSystemInterface;
|
||||
use Drupal\file\Entity\File;
|
||||
use Drupal\node\NodeInterface;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\TestFileCreationTrait;
|
||||
use Drupal\user\Entity\Role;
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
|
@ -17,8 +15,6 @@ use Drupal\user\RoleInterface;
|
|||
*/
|
||||
class EditorPrivateFileReferenceFilterTest extends BrowserTestBase {
|
||||
|
||||
use TestFileCreationTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
|
@ -53,10 +49,6 @@ class EditorPrivateFileReferenceFilterTest extends BrowserTestBase {
|
|||
// Create a content type with a body field.
|
||||
$this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
|
||||
|
||||
// Get test files.
|
||||
/** @var array stdClass */
|
||||
$files = $this->getTestFiles('image');
|
||||
$image = reset($files);
|
||||
// Create a file in the 'private:// ' stream.
|
||||
$filename = 'test.png';
|
||||
$src = '/system/files/' . $filename;
|
||||
|
@ -67,7 +59,7 @@ class EditorPrivateFileReferenceFilterTest extends BrowserTestBase {
|
|||
$file->setTemporary();
|
||||
$file->setOwner($author);
|
||||
// Create the file itself.
|
||||
\Drupal::service('file_system')->copy($image->uri, $file->getFileUri(), FileSystemInterface::EXISTS_RENAME);
|
||||
file_put_contents($file->getFileUri(), $this->randomString());
|
||||
$file->save();
|
||||
|
||||
// The image should be visible for its author.
|
||||
|
|
|
@ -61,29 +61,14 @@ class EditorFileReferenceFilterTest extends KernelTestBase {
|
|||
return $filter->process($input, 'und');
|
||||
};
|
||||
|
||||
/** @var array stdClass */
|
||||
$files = $this->getTestFiles('image');
|
||||
list($width, $height) = getimagesize($files[0]->uri);
|
||||
$images[] = [
|
||||
'uri' => $files[0]->uri,
|
||||
'dimensions' => 'width="' . $width . '" height="' . $height . '"',
|
||||
];
|
||||
list($width, $height) = getimagesize($files[1]->uri);
|
||||
$images[] = [
|
||||
'uri' => $files[1]->uri,
|
||||
'dimensions' => 'width="' . $width . '" height="' . $height . '"',
|
||||
];
|
||||
|
||||
unset($files);
|
||||
|
||||
\Drupal::service('file_system')->copy($images[0]['uri'], 'public://llama.jpg', FileSystemInterface::EXISTS_RENAME);
|
||||
file_put_contents('public://llama.jpg', $this->randomMachineName());
|
||||
$image = File::create(['uri' => 'public://llama.jpg']);
|
||||
$image->save();
|
||||
$id = $image->id();
|
||||
$uuid = $image->uuid();
|
||||
$cache_tag = ['file:' . $id];
|
||||
|
||||
\Drupal::service('file_system')->copy($images[1]['uri'], 'public://alpaca.jpg', FileSystemInterface::EXISTS_RENAME);
|
||||
file_put_contents('public://alpaca.jpg', $this->randomMachineName());
|
||||
$image_2 = File::create(['uri' => 'public://alpaca.jpg']);
|
||||
$image_2->save();
|
||||
$id_2 = $image_2->id();
|
||||
|
@ -102,23 +87,23 @@ class EditorFileReferenceFilterTest extends KernelTestBase {
|
|||
|
||||
// One data-entity-uuid attribute.
|
||||
$input = '<img src="llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" />';
|
||||
$expected_output = '<img src="/' . $this->siteDirectory . '/files/llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" ' . $images[0]['dimensions'] . ' loading="lazy" />';
|
||||
$expected_output = '<img src="/' . $this->siteDirectory . '/files/llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" />';
|
||||
$output = $test($input);
|
||||
$this->assertIdentical($output->getProcessedText(), $expected_output);
|
||||
$this->assertIdentical($expected_output, $output->getProcessedText());
|
||||
$this->assertEqual($cache_tag, $output->getCacheTags());
|
||||
|
||||
// One data-entity-uuid attribute with odd capitalization.
|
||||
$input = '<img src="llama.jpg" data-entity-type="file" DATA-entity-UUID = "' . $uuid . '" />';
|
||||
$expected_output = '<img src="/' . $this->siteDirectory . '/files/llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" ' . $images[0]['dimensions'] . ' loading="lazy" />';
|
||||
$expected_output = '<img src="/' . $this->siteDirectory . '/files/llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" />';
|
||||
$output = $test($input);
|
||||
$this->assertIdentical($output->getProcessedText(), $expected_output);
|
||||
$this->assertIdentical($expected_output, $output->getProcessedText());
|
||||
$this->assertEqual($cache_tag, $output->getCacheTags());
|
||||
|
||||
// One data-entity-uuid attribute on a non-image tag.
|
||||
$input = '<video src="llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" />';
|
||||
$expected_output = '<video src="/' . $this->siteDirectory . '/files/llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '"></video>';
|
||||
$output = $test($input);
|
||||
$this->assertIdentical($output->getProcessedText(), $expected_output);
|
||||
$this->assertIdentical($expected_output, $output->getProcessedText());
|
||||
$this->assertEqual($cache_tag, $output->getCacheTags());
|
||||
|
||||
// One data-entity-uuid attribute with an invalid value.
|
||||
|
@ -130,19 +115,34 @@ class EditorFileReferenceFilterTest extends KernelTestBase {
|
|||
// Two different data-entity-uuid attributes.
|
||||
$input = '<img src="llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" />';
|
||||
$input .= '<img src="alpaca.jpg" data-entity-type="file" data-entity-uuid="' . $uuid_2 . '" />';
|
||||
$expected_output = '<img src="/' . $this->siteDirectory . '/files/llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" ' . $images[0]['dimensions'] . ' loading="lazy" />';
|
||||
$expected_output .= '<img src="/' . $this->siteDirectory . '/files/alpaca.jpg" data-entity-type="file" data-entity-uuid="' . $uuid_2 . '" ' . $images[1]['dimensions'] . ' loading="lazy" />';
|
||||
$expected_output = '<img src="/' . $this->siteDirectory . '/files/llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" />';
|
||||
$expected_output .= '<img src="/' . $this->siteDirectory . '/files/alpaca.jpg" data-entity-type="file" data-entity-uuid="' . $uuid_2 . '" />';
|
||||
$output = $test($input);
|
||||
$this->assertIdentical($output->getProcessedText(), $expected_output);
|
||||
$this->assertIdentical($expected_output, $output->getProcessedText());
|
||||
$this->assertEqual(Cache::mergeTags($cache_tag, $cache_tag_2), $output->getCacheTags());
|
||||
|
||||
// Two identical data-entity-uuid attributes.
|
||||
$input = '<img src="llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" />';
|
||||
$input .= '<img src="llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" />';
|
||||
$expected_output = '<img src="/' . $this->siteDirectory . '/files/llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" ' . $images[0]['dimensions'] . ' loading="lazy" />';
|
||||
$expected_output .= '<img src="/' . $this->siteDirectory . '/files/llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" ' . $images[0]['dimensions'] . ' loading="lazy" />';
|
||||
$expected_output = '<img src="/' . $this->siteDirectory . '/files/llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" />';
|
||||
$expected_output .= '<img src="/' . $this->siteDirectory . '/files/llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" />';
|
||||
$output = $test($input);
|
||||
$this->assertIdentical($output->getProcessedText(), $expected_output);
|
||||
$this->assertIdentical($expected_output, $output->getProcessedText());
|
||||
$this->assertEqual($cache_tag, $output->getCacheTags());
|
||||
|
||||
// Add a valid image for test lazy loading feature.
|
||||
/** @var array stdClass */
|
||||
$files = $this->getTestFiles('image');
|
||||
$image = reset($files);
|
||||
\Drupal::service('file_system')->copy($image->uri, 'public://llama.jpg', FileSystemInterface::EXISTS_REPLACE);
|
||||
[$width, $height] = getimagesize('public://llama.jpg');
|
||||
$dimensions = 'width="' . $width . '" height="' . $height . '"';
|
||||
|
||||
// Test image dimensions and loading attributes are present.
|
||||
$input = '<img src="llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" />';
|
||||
$expected_output = '<img src="/' . $this->siteDirectory . '/files/llama.jpg" data-entity-type="file" data-entity-uuid="' . $uuid . '" ' . $dimensions . ' loading="lazy" />';
|
||||
$output = $test($input);
|
||||
$this->assertIdentical($expected_output, $output->getProcessedText());
|
||||
$this->assertEqual($cache_tag, $output->getCacheTags());
|
||||
}
|
||||
|
||||
|
|
|
@ -16,13 +16,25 @@ class ImageLazyLoadController extends ControllerBase {
|
|||
* The render array.
|
||||
*/
|
||||
public function renderImage() {
|
||||
return [
|
||||
$images['with-dimensions'] = [
|
||||
'#theme' => 'image',
|
||||
'#uri' => '/core/themes/bartik/logo.svg',
|
||||
'#alt' => 'Image lazy load testing image',
|
||||
'#prefix' => '<div id="with-dimensions">',
|
||||
'#suffix' => '</div>',
|
||||
'#width' => '50%',
|
||||
'#height' => '50%',
|
||||
];
|
||||
|
||||
$images['without-dimensions'] = [
|
||||
'#theme' => 'image',
|
||||
'#uri' => '/core/themes/bartik/logo.svg',
|
||||
'#alt' => 'Image lazy load testing image without dimensions',
|
||||
'#prefix' => '<div id="without-dimensions">',
|
||||
'#suffix' => '</div>',
|
||||
];
|
||||
|
||||
return $images;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\Tests\system\Functional\Theme;
|
||||
|
||||
use Behat\Mink\Exception\ElementHtmlException;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
|
@ -28,7 +29,13 @@ class ImageLoadingAttributeTest extends BrowserTestBase {
|
|||
*/
|
||||
public function testImageLoadingAttribute() {
|
||||
$this->drupalGet('image-lazy-load-test');
|
||||
$this->assertSession()->responseContains('loading="lazy"');
|
||||
$this->assertSession()->elementAttributeExists('css', '#with-dimensions img', 'loading');
|
||||
$this->assertSession()->elementAttributeContains('css', '#with-dimensions img', 'loading', 'lazy');
|
||||
|
||||
// Without image dimensions loading attribute is not generated.
|
||||
$this->assertSession()->elementAttributeContains('css', '#without-dimensions img', 'alt', 'Image lazy load testing image without dimensions');
|
||||
$this->expectExceptionMessage('The attribute "loading" was not found in the element matching css "#without-dimensions img".');
|
||||
$this->assertSession()->elementAttributeExists('css', '#without-dimensions img', 'loading');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue