-
-
Notifications
You must be signed in to change notification settings - Fork 0
[#302] Cropped the banner featured image on its focal point and gave the divider and figure images a style. #303
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
cbed714
[#302] Rendered the banner featured image through a focal point image…
AlexSkrypnyk 12e779a
[#302] Rendered the divider and the in-content figure through an imag…
AlexSkrypnyk 0b3ce1f
[#302] Added a test for the image styles the theme renders through.
AlexSkrypnyk 91b27cf
[#302] Documented the image styles behind the featured image, divider…
AlexSkrypnyk 7ce713b
[#302] Passed the divider's theme fallback into the image component.
AlexSkrypnyk 40d099d
[#302] Asserted that the divider style caps its derivative and does n…
AlexSkrypnyk 929b94e
[#302] Kept the divider image proportional when its height is clamped.
AlexSkrypnyk 94e85c4
[#302] Gave each data provider the name its test method requires.
AlexSkrypnyk e0b903c
Addressed code review: guarded the divider image and the style effect…
AlexSkrypnyk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| uuid: fb579dc8-21da-4a99-887b-920afb0cde42 | ||
| langcode: en | ||
| status: true | ||
| dependencies: | ||
| module: | ||
| - focal_point | ||
| name: banner_featured | ||
| label: 'Banner featured image (1090x818, WebP)' | ||
| effects: | ||
| 24958aa6-09b2-48bd-b29e-b38b76f1168d: | ||
| uuid: 24958aa6-09b2-48bd-b29e-b38b76f1168d | ||
| id: focal_point_scale_and_crop | ||
| weight: 1 | ||
| data: | ||
| width: 1090 | ||
| height: 818 | ||
| crop_type: focal_point | ||
| a405d584-d557-469f-bdc0-9e7fb2b290d9: | ||
| uuid: a405d584-d557-469f-bdc0-9e7fb2b290d9 | ||
| id: image_convert | ||
| weight: 2 | ||
| data: | ||
| extension: webp |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| uuid: 12950d43-9e28-4023-af34-1ad10d79a313 | ||
| langcode: en | ||
| status: true | ||
| dependencies: { } | ||
| name: divider | ||
| label: 'Divider (480 tall, WebP)' | ||
| effects: | ||
| 8bef4bca-0946-4c77-b443-d3e6bdecf045: | ||
| uuid: 8bef4bca-0946-4c77-b443-d3e6bdecf045 | ||
| id: image_scale | ||
| weight: 1 | ||
| data: | ||
| width: 1090 | ||
| height: 480 | ||
| upscale: false | ||
| bd7d2701-0350-48a9-8961-3697c2dfd7c6: | ||
| uuid: bd7d2701-0350-48a9-8961-3697c2dfd7c6 | ||
| id: image_convert | ||
| weight: 2 | ||
| data: | ||
| extension: webp |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
174 changes: 174 additions & 0 deletions
174
web/modules/custom/do_base/tests/src/Unit/ImageStyleConfigTest.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,174 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace Drupal\Tests\do_base\Unit; | ||
|
|
||
| use Drupal\Tests\UnitTestCase; | ||
| use Drupal\Tests\do_base\Traits\ExportedConfigTrait; | ||
| use PHPUnit\Framework\Attributes\CoversNothing; | ||
| use PHPUnit\Framework\Attributes\DataProvider; | ||
| use PHPUnit\Framework\Attributes\Group; | ||
|
|
||
| /** | ||
| * Tests the image styles the theme renders images through. | ||
| * | ||
| * A style name reaches the theme layer as a plain string, so a missing style or | ||
| * an effect dropped in a routine re-export fails silently. The page still | ||
| * renders; only the size and the crop of the image change. | ||
| */ | ||
| #[CoversNothing] | ||
| #[Group('do_base')] | ||
| class ImageStyleConfigTest extends UnitTestCase { | ||
|
|
||
| use ExportedConfigTrait; | ||
|
|
||
| /** | ||
| * Machine name of the style behind the banner's featured image. | ||
| */ | ||
| protected const FEATURED_STYLE = 'banner_featured'; | ||
|
|
||
| /** | ||
| * Machine name of the style behind the divider graphic. | ||
| */ | ||
| protected const DIVIDER_STYLE = 'divider'; | ||
|
|
||
| /** | ||
| * Tests that every style the theme asks for by name is exported. | ||
| */ | ||
| #[DataProvider('dataProviderStyleNamedByThemeIsExported')] | ||
| public function testStyleNamedByThemeIsExported(string $name): void { | ||
| // Act. | ||
| $style = $this->loadConfig('image.style.' . $name . '.yml'); | ||
|
|
||
| // Assert. | ||
| $this->assertSame($name, $style['name']); | ||
| } | ||
|
|
||
| /** | ||
| * Data provider for testStyleNamedByThemeIsExported. | ||
| */ | ||
| public static function dataProviderStyleNamedByThemeIsExported(): \Iterator { | ||
| yield from static::styleNameCases(); | ||
| } | ||
|
|
||
| /** | ||
| * Tests that the featured image is cropped around the editor's focal point. | ||
| * | ||
| * The banner sizes the image with CSS, so the browser trims everything | ||
| * outside a centred box. A focal point crop places the subject at that | ||
| * centre. | ||
| */ | ||
| public function testFeaturedImageCropsOnTheFocalPoint(): void { | ||
| // Act. | ||
| $effect = $this->effect(static::FEATURED_STYLE, 'focal_point_scale_and_crop'); | ||
|
|
||
| // Assert. | ||
| $this->assertNotNull($effect, 'The featured image style does not crop on a focal point.'); | ||
| $this->assertSame('focal_point', $effect['data']['crop_type']); | ||
| $this->assertGreaterThan(0, $effect['data']['width']); | ||
| $this->assertGreaterThan(0, $effect['data']['height']); | ||
| } | ||
|
|
||
| /** | ||
| * Tests that the divider graphic is capped at the size it is drawn at. | ||
| * | ||
| * CSS bounds the rendered height, so an uncapped derivative sends pixels the | ||
| * page never draws. Upscaling a small graphic to the cap blurs it instead. | ||
| */ | ||
| public function testDividerIsScaledWithinBounds(): void { | ||
| // Act. | ||
| $effect = $this->effect(static::DIVIDER_STYLE, 'image_scale'); | ||
|
|
||
| // Assert. | ||
| $this->assertNotNull($effect, 'The divider style does not scale.'); | ||
| $this->assertGreaterThan(0, $effect['data']['width']); | ||
| $this->assertGreaterThan(0, $effect['data']['height']); | ||
| $this->assertFalse($effect['data']['upscale']); | ||
| } | ||
|
|
||
| /** | ||
| * Tests that the styles rendering uploaded imagery convert to WebP. | ||
| * | ||
| * The theme renders only photographic content through a style: brand renders | ||
| * and generated art uploaded as multi-megabyte PNGs. A style without a | ||
| * convert effect serves the uploaded format. | ||
| */ | ||
| #[DataProvider('dataProviderStyleNamedByThemeConvertsToWebp')] | ||
| public function testStyleNamedByThemeConvertsToWebp(string $name): void { | ||
| // Act. | ||
| $effect = $this->effect($name, 'image_convert'); | ||
|
|
||
| // Assert. | ||
| $this->assertNotNull($effect, sprintf('Style "%s" does not convert.', $name)); | ||
| $this->assertSame('webp', $effect['data']['extension']); | ||
| } | ||
|
|
||
| /** | ||
| * Data provider for testStyleNamedByThemeConvertsToWebp. | ||
| */ | ||
| public static function dataProviderStyleNamedByThemeConvertsToWebp(): \Iterator { | ||
| yield from static::styleNameCases(); | ||
| } | ||
|
|
||
| /** | ||
| * Returns an effect of a style, or NULL when the style does not have one. | ||
| */ | ||
| protected function effect(string $name, string $effect_id): ?array { | ||
| $effects = $this->loadConfig('image.style.' . $name . '.yml')['effects'] ?? []; | ||
|
|
||
| foreach ($effects as $effect) { | ||
| if ($effect['id'] === $effect_id) { | ||
| return $effect; | ||
| } | ||
| } | ||
|
|
||
| return NULL; | ||
| } | ||
|
|
||
| /** | ||
| * Yields one case per style name, keyed by the name. | ||
| */ | ||
| protected static function styleNameCases(): \Iterator { | ||
| foreach (static::themeStyleNames() as $name) { | ||
| yield $name => [$name]; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Lists the style names the theme passes to the image render helpers. | ||
| * | ||
| * Names are read from the theme rather than listed here, so a component that | ||
| * starts rendering through a style of its own is covered without editing this | ||
| * test. | ||
| */ | ||
| protected static function themeStyleNames(): array { | ||
| $helpers = [ | ||
| 'civictheme_media_image_get_variables', | ||
| '_civictheme_preprocess_paragraph__paragraph_field__image', | ||
| '_civictheme_preprocess_paragraph__node_field__image', | ||
| ]; | ||
|
|
||
| $pattern = sprintf('~(?:%s)\([^)]*,\s*\'([a-z0-9_]+)\'\s*\)~', implode('|', $helpers)); | ||
|
|
||
| $names = []; | ||
|
|
||
| foreach (glob(dirname(__DIR__, 7) . '/web/themes/custom/drevops/includes/*.inc') ?: [] as $file) { | ||
| if (preg_match_all($pattern, (string) file_get_contents($file), $matches) === 0) { | ||
| continue; | ||
| } | ||
|
|
||
| $names = array_merge($names, $matches[1]); | ||
| } | ||
|
|
||
| $names = array_unique($names); | ||
| sort($names); | ||
|
|
||
| if ($names === []) { | ||
| throw new \RuntimeException('No image styles found in the theme; the scanned helper names are out of date.'); | ||
| } | ||
|
|
||
| return $names; | ||
| } | ||
|
|
||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| <?php | ||
|
|
||
| /** | ||
| * @file | ||
| * Media component alterations. | ||
| */ | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| use Drupal\media\MediaInterface; | ||
|
|
||
| /** | ||
| * Implements hook_preprocess_HOOK(). | ||
| */ | ||
| function drevops_preprocess_media__civictheme_image(array &$variables): void { | ||
| $media = $variables['media'] ?? NULL; | ||
|
|
||
| // A source file that cannot be read as an image leaves the URL empty. | ||
| if (!$media instanceof MediaInterface || empty($variables['url'])) { | ||
| return; | ||
| } | ||
|
|
||
| // CivicTheme builds this URL from the source file, so it serves the original | ||
| // upload. | ||
| $image = civictheme_media_image_get_variables($media, 'wide'); | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| if (empty($image['url'])) { | ||
| return; | ||
| } | ||
|
|
||
| $variables['url'] = $image['url']; | ||
|
|
||
| // Dimensions measured on the source no longer match once a style resizes the | ||
| // image. The image component resolves them from the URL. | ||
| $variables['width'] = NULL; | ||
| $variables['height'] = NULL; | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.