From 1d683cf86063be29ab114da23d9c90d870392180 Mon Sep 17 00:00:00 2001 From: "Luke.Leber" <lleber@3509746.no-reply.drupal.org> Date: Sat, 11 Dec 2021 22:29:50 +0000 Subject: [PATCH] Issue #3253964 by Luke.Leber: Add a css pre-render event dispatch --- inline_all_css.services.yml | 1 + src/Asset/CriticalCssCollectionRenderer.php | 19 +++++++- src/Event/CssPreRenderEvent.php | 51 ++++++++++++++++++++ tests/src/Unit/CssCollectionRendererTest.php | 24 ++++++++- tests/src/Unit/CssPreRenderEventTest.php | 27 +++++++++++ 5 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 src/Event/CssPreRenderEvent.php create mode 100644 tests/src/Unit/CssPreRenderEventTest.php diff --git a/inline_all_css.services.yml b/inline_all_css.services.yml index e714e73..8cd9cb6 100644 --- a/inline_all_css.services.yml +++ b/inline_all_css.services.yml @@ -5,3 +5,4 @@ services: decorates: asset.css.collection_renderer arguments: - '@file_system' + - '@event_dispatcher' diff --git a/src/Asset/CriticalCssCollectionRenderer.php b/src/Asset/CriticalCssCollectionRenderer.php index 9afca72..33900ea 100644 --- a/src/Asset/CriticalCssCollectionRenderer.php +++ b/src/Asset/CriticalCssCollectionRenderer.php @@ -5,6 +5,8 @@ namespace Drupal\inline_all_css\Asset; use Drupal\Core\Asset\AssetCollectionRendererInterface; use Drupal\Core\File\FileSystemInterface; use Drupal\Core\Render\Markup; +use Drupal\inline_all_css\Event\CssPreRenderEvent; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use function file_get_contents; /** @@ -21,14 +23,24 @@ class CriticalCssCollectionRenderer implements AssetCollectionRendererInterface */ protected $fileSystem; + /** + * The event dispatcher service. + * + * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface + */ + protected $eventDispatcher; + /** * Constructs a CriticalCssCollectionRenderer. * * @param \Drupal\Core\File\FileSystemInterface $file_system * The file system service. + * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher + * The event dispatcher service. */ - public function __construct(FileSystemInterface $file_system) { + public function __construct(FileSystemInterface $file_system, EventDispatcherInterface $event_dispatcher) { $this->fileSystem = $file_system; + $this->eventDispatcher = $event_dispatcher; } /** @@ -41,6 +53,11 @@ class CriticalCssCollectionRenderer implements AssetCollectionRendererInterface $css .= file_get_contents($file); } + $event = new CssPreRenderEvent($css); + /* @noinspection PhpMethodParametersCountMismatchInspection */ + $this->eventDispatcher->dispatch($event, CssPreRenderEvent::EVENT_NAME); + $css = $event->getCss(); + return [ [ '#type' => 'html_tag', diff --git a/src/Event/CssPreRenderEvent.php b/src/Event/CssPreRenderEvent.php new file mode 100644 index 0000000..a5de3c2 --- /dev/null +++ b/src/Event/CssPreRenderEvent.php @@ -0,0 +1,51 @@ +<?php + +namespace Drupal\inline_all_css\Event; + +use Drupal\Component\EventDispatcher\Event; + +/** + * Event that is fired before css is rendered. + */ +class CssPreRenderEvent extends Event { + + public const EVENT_NAME = 'inline_all_css_css_pre_render'; + + /** + * The css string that is about to be rendered. + * + * @var string + */ + protected $css; + + /** + * Creates a new css pre-render event. + * + * @param string $css + * The initial css of the event. + */ + public function __construct($css) { + $this->css = $css; + } + + /** + * Gets the css string for this event. + * + * @return string + * The css string for this event. + */ + public function getCss() { + return $this->css; + } + + /** + * Sets the css string for this event. + * + * @param string $css + * The CSS string to set. + */ + public function setCss($css) { + $this->css = $css; + } + +} diff --git a/tests/src/Unit/CssCollectionRendererTest.php b/tests/src/Unit/CssCollectionRendererTest.php index 7f2f632..c27c00c 100644 --- a/tests/src/Unit/CssCollectionRendererTest.php +++ b/tests/src/Unit/CssCollectionRendererTest.php @@ -5,7 +5,9 @@ namespace Drupal\Tests\inline_all_css\Unit; use Drupal\Core\File\FileSystemInterface; use Drupal\Core\Render\Markup; use Drupal\inline_all_css\Asset\CriticalCssCollectionRenderer; +use Drupal\inline_all_css\Event\CssPreRenderEvent; use Drupal\Tests\UnitTestCase; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Test cases for the critical css collection renderer. @@ -37,7 +39,23 @@ class CssCollectionRendererTest extends UnitTestCase { ['public://test-2.css', __DIR__ . '/../../fixtures/test-2.css'], ['public://test-3.css', __DIR__ . '/../../fixtures/test-3.css'], ]); - $this->instance = new CriticalCssCollectionRenderer($filesystem); + + $eventDispatcher = $this->getMockBuilder(EventDispatcherInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $eventDispatcher->method('dispatch') + ->willReturnCallback(static function (CssPreRenderEvent $event) { + $css = $event->getCss(); + $css .= <<<CSS +.event { + color: gray; +} +CSS; + $event->setCss($css); + }); + + $this->instance = new CriticalCssCollectionRenderer($filesystem, $eventDispatcher); } /** @@ -64,7 +82,9 @@ html { body { color: blue; } - +.event { + color: gray; +} CSS), ], ]; diff --git a/tests/src/Unit/CssPreRenderEventTest.php b/tests/src/Unit/CssPreRenderEventTest.php new file mode 100644 index 0000000..35436ec --- /dev/null +++ b/tests/src/Unit/CssPreRenderEventTest.php @@ -0,0 +1,27 @@ +<?php + +namespace Drupal\Tests\inline_all_css\Unit; + +use Drupal\inline_all_css\Event\CssPreRenderEvent; +use Drupal\Tests\UnitTestCase; + +/** + * Test cases for the css pre-render event. + * + * @group inline_all_css + */ +class CssPreRenderEventTest extends UnitTestCase { + + /** + * Test case for the css pre-render event. + */ + public function testCssPreRenderEvent() { + $event = new CssPreRenderEvent('* { color: red; }'); + static::assertSame('* { color: red; }', $event->getCss()); + + $new_css = 'html { color: green; }'; + $event->setCss($new_css); + static::assertSame($new_css, $event->getCss()); + } + +} -- GitLab