big_pipe.module | 15 ++----
big_pipe.services.yml | 5 ++
.../NoBigPipeRouteAlterSubscriber.php | 53 ++++++++++++++++++++++
src/Render/Placeholder/BigPipeStrategy.php | 8 +---
src/Tests/BigPipeTest.php | 19 ++++++++
.../big_pipe_test/big_pipe_test.routing.yml | 10 ++++
.../Render/Placeholder/BigPipeStrategyTest.php | 31 +++++++------
7 files changed, 110 insertions(+), 31 deletions(-)
diff --git a/big_pipe.module b/big_pipe.module
index 485a0e1..af37695 100644
--- a/big_pipe.module
+++ b/big_pipe.module
@@ -33,16 +33,8 @@ function big_pipe_help($route_name, RouteMatchInterface $route_match) {
* @see \Drupal\big_pipe\Controller\BigPipeController::setNoJsCookie()
*/
function big_pipe_page_attachments(array &$page) {
- // Exclude a few very special routes from no-JS detection.
- $excluded_routes = [
- // The batch system already uses a refresh to work with JS disabled.
- 'system.batch_page.html',
- // The BigPipe placeholder strategy is not applied on the module
- // installation page, so the no-JS detection is also not necessary.
- // @see \Drupal\big_pipe\Render\Placeholder\BigPipeStrategy::processPlaceholders
- 'system.modules_list',
- ];
- if (in_array(\Drupal::routeMatch()->getRouteName(), $excluded_routes)) {
+ // Routes that don't use BigPipe also don't need no-JS detection.
+ if (\Drupal::routeMatch()->getRouteObject()->getOption('_no_big_pipe')) {
return;
}
@@ -64,8 +56,7 @@ function big_pipe_page_attachments(array &$page) {
'#noscript' => TRUE,
'#attributes' => [
'http-equiv' => 'Refresh',
- // @todo: Switch to Url::fromRoute() once https://www.drupal.org/node/2589967 is resolved.
- 'content' => '0; URL=' . Url::fromUri('internal:/big_pipe/no-js', ['query' => \Drupal::service('redirect.destination')->getAsArray()])->toString(),
+ 'content' => '0; URL=' . Url::fromRoute('big_pipe.nojs', [], ['query' => \Drupal::service('redirect.destination')->getAsArray()])->toString(),
],
],
'big_pipe_detect_nojs',
diff --git a/big_pipe.services.yml b/big_pipe.services.yml
index 9a78385..9209fc0 100644
--- a/big_pipe.services.yml
+++ b/big_pipe.services.yml
@@ -19,6 +19,11 @@ services:
decoration_inner_name: html_response.attachments_processor.original
arguments: ['@html_response.attachments_processor.original', '@asset.resolver', '@config.factory', '@asset.css.collection_renderer', '@asset.js.collection_renderer', '@request_stack', '@renderer', '@module_handler']
+ route_subscriber.no_big_pipe:
+ class: Drupal\big_pipe\EventSubscriber\NoBigPipeRouteAlterSubscriber
+ tags:
+ - { name: event_subscriber }
+
# @todo Move this into Drupal 8 core.
cache_context.session.exists:
class: Drupal\big_pipe\Cache\Context\SessionExistsCacheContext
diff --git a/src/EventSubscriber/NoBigPipeRouteAlterSubscriber.php b/src/EventSubscriber/NoBigPipeRouteAlterSubscriber.php
new file mode 100644
index 0000000..973c2c5
--- /dev/null
+++ b/src/EventSubscriber/NoBigPipeRouteAlterSubscriber.php
@@ -0,0 +1,53 @@
+ refresh to work without JavaScript.
+ 'system.batch_page.html',
+ // When a user would install the BigPipe module using a browser and with
+ // JavaScript disabled, the first response contains the status messages
+ // for installing a module, but then the BigPipe no-JS redirect occurs,
+ // which then causes the user to not see those status messages.
+ // @see https://www.drupal.org/node/2469431#comment-10901944
+ 'system.modules_list',
+ ];
+
+ $route_collection = $event->getRouteCollection();
+ foreach ($no_big_pipe_routes as $excluded_route) {
+ if ($route = $route_collection->get($excluded_route)) {
+ $route->setOption('_no_big_pipe', TRUE);
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ static function getSubscribedEvents() {
+ $events[RoutingEvents::ALTER][] = ['onRoutingRouteAlterSetNoBigPipe'];
+ return $events;
+ }
+
+}
diff --git a/src/Render/Placeholder/BigPipeStrategy.php b/src/Render/Placeholder/BigPipeStrategy.php
index 3a81b76..e24c9ad 100644
--- a/src/Render/Placeholder/BigPipeStrategy.php
+++ b/src/Render/Placeholder/BigPipeStrategy.php
@@ -110,12 +110,8 @@ class BigPipeStrategy implements PlaceholderStrategyInterface {
* {@inheritdoc}
*/
public function processPlaceholders(array $placeholders) {
- // Don't apply the BigPipe placeholder strategy on the module installation
- // page. When a user would install the BigPipe module using a browser that
- // has JavaScript disabled, the status messages shown immediately after
- // installing the module would get lost.
- // @see https://www.drupal.org/node/2469431#comment-10901944
- if ($this->routeMatch->getRouteName() === 'system.modules_list') {
+ // Routes can opt out from using the BigPipe HTML delivery technique.
+ if ($this->routeMatch->getRouteObject()->getOption('_no_big_pipe')) {
return [];
}
diff --git a/src/Tests/BigPipeTest.php b/src/Tests/BigPipeTest.php
index f44844b..d4cbf88 100644
--- a/src/Tests/BigPipeTest.php
+++ b/src/Tests/BigPipeTest.php
@@ -91,6 +91,8 @@ class BigPipeTest extends WebTestBase {
$this->assertRaw('');
$this->assertBigPipeNoJsMetaRefreshRedirect();
$this->assertBigPipeNoJsCookieExists(TRUE);
+ $this->assertNoRaw('');
$this->assertBigPipeNoJsMetaRefreshRedirect();
$this->assertBigPipeNoJsCookieExists(TRUE);
+ $this->assertNoRaw('