core/modules/big_pipe/big_pipe.libraries.yml | 3 ++
core/modules/big_pipe/css/big_pipe.css | 4 ++
core/modules/big_pipe/src/Render/BigPipe.php | 11 ++---
.../src/Render/Placeholder/BigPipeStrategy.php | 52 +++++++++++++++++++++-
core/modules/block/src/BlockViewBuilder.php | 17 +++++++
core/modules/comment/src/CommentLazyBuilders.php | 31 +++++++++++++
.../form/form--comment--preview.html.twig | 3 ++
7 files changed, 113 insertions(+), 8 deletions(-)
diff --git a/core/modules/big_pipe/big_pipe.libraries.yml b/core/modules/big_pipe/big_pipe.libraries.yml
index 6da49b7..9a49d6a 100644
--- a/core/modules/big_pipe/big_pipe.libraries.yml
+++ b/core/modules/big_pipe/big_pipe.libraries.yml
@@ -1,5 +1,8 @@
big_pipe:
version: VERSION
+ css:
+ theme:
+ css/big_pipe.css: {}
js:
js/big_pipe.js: {}
drupalSettings:
diff --git a/core/modules/big_pipe/css/big_pipe.css b/core/modules/big_pipe/css/big_pipe.css
new file mode 100644
index 0000000..49b1259
--- /dev/null
+++ b/core/modules/big_pipe/css/big_pipe.css
@@ -0,0 +1,4 @@
+div[data-big-pipe-placeholder-id] {
+ -webkit-filter: opacity(0.2) blur(1px);
+ filter: opacity(0.2) blur(1px);
+}
diff --git a/core/modules/big_pipe/src/Render/BigPipe.php b/core/modules/big_pipe/src/Render/BigPipe.php
index b312d76..0939ae8 100644
--- a/core/modules/big_pipe/src/Render/BigPipe.php
+++ b/core/modules/big_pipe/src/Render/BigPipe.php
@@ -716,14 +716,11 @@ protected function renderPlaceholder($placeholder, array $placeholder_render_arr
* only keep the first occurrence.
*/
protected function getPlaceholderOrder($html, $placeholders) {
- $fragments = explode('', $fragment, 2);
- $placeholder_id = $t[0];
- $placeholder_ids[] = $placeholder_id;
+ $dom = Html::load($html);
+ $xpath = new \DOMXPath($dom);
+ foreach ($xpath->query('//span[@data-big-pipe-placeholder-id]') as $node) {
+ $placeholder_ids[] = Html::escape($node->getAttribute('data-big-pipe-placeholder-id'));
}
$placeholder_ids = array_unique($placeholder_ids);
diff --git a/core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php b/core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php
index f967eba..a475ed8 100644
--- a/core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php
+++ b/core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php
@@ -5,6 +5,7 @@
use Drupal\Component\Utility\Crypt;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\UrlHelper;
+use Drupal\Core\Render\Markup;
use Drupal\Core\Render\Placeholder\PlaceholderStrategyInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\SessionConfigurationInterface;
@@ -198,8 +199,57 @@ protected static function placeholderIsAttributeSafe($placeholder) {
protected static function createBigPipeJsPlaceholder($original_placeholder, array $placeholder_render_array) {
$big_pipe_placeholder_id = static::generateBigPipePlaceholderId($original_placeholder, $placeholder_render_array);
+ $interface_preview = [];
+ $lazy_builder_as_string = NULL;
+
+ if (isset($placeholder_render_array['#lazy_builder'])) {
+ $callable = $placeholder_render_array['#lazy_builder'][0];
+ if (is_string($callable)) {
+ $lazy_builder_as_string = $callable;
+ if (strpos($callable, ':') !== FALSE && strpos($callable, '::') === FALSE) {
+ try {
+ $callable = \Drupal::service('controller_resolver')->getControllerFromDefinition($callable . 'Preview');
+ }
+ catch (\InvalidArgumentException $e) {}
+ }
+ else {
+ $callable .= 'Preview';
+ }
+ }
+ else if (is_array($callable)) {
+ $lazy_builder_as_string = get_class($callable[0]) . '::' . $callable[1];
+ $callable[1] .= 'Preview';
+ }
+ if (is_callable($callable)) {
+ $interface_preview = call_user_func_array($callable, $placeholder_render_array['#lazy_builder'][1]);
+ assert('is_array($interface_preview)', "Interface preview for $original_placeholder must be a render array.");
+ }
+
+ // Add BigPipe interface preview debug output. (If Twig debug is on.)
+ // @todo inject Twig service.
+ $twig_service = \Drupal::service('twig');
+ if ($twig_service->isDebug()) {
+ $interface_preview_callback = $lazy_builder_as_string . 'Preview';
+ $implemented = is_callable($callable)
+ ? 'YES! See theme debug output below:'
+ : 'NO, contact a developer…';
+ $info = [
+ "",
+ "",
+ "",
+ ];
+ $interface_preview = [
+ '#prefix' => Markup::create("\n\n " . implode("\n ", $info)),
+ 'actual interface preview' => $interface_preview,
+ '#suffix' => Markup::create("\n\n"),
+ ];
+ }
+ }
+
return [
- '#markup' => '',
+ '#prefix' => '',
+ 'interface preview' => $interface_preview,
+ '#suffix' => '',
'#cache' => [
'max-age' => 0,
'contexts' => [
diff --git a/core/modules/block/src/BlockViewBuilder.php b/core/modules/block/src/BlockViewBuilder.php
index 3b20d7b..6b054ad 100644
--- a/core/modules/block/src/BlockViewBuilder.php
+++ b/core/modules/block/src/BlockViewBuilder.php
@@ -191,6 +191,23 @@ public static function lazyBuilder($entity_id, $view_mode) {
}
/**
+ * Interface preview for ::lazyBuilder().
+ */
+ public static function lazyBuilderPreview($entity_id) {
+ $block = Block::load($entity_id);
+ return [
+ '#theme' => 'block',
+ '#attributes' => [],
+ '#configuration' => ['provider' => 'preview'],
+ '#plugin_id' => 'preview__' . $block->getPluginId(),
+ '#base_plugin_id' => '',
+ '#derivative_plugin_id' => '',
+ '#id' => 'preview__' . $entity_id,
+ 'content' => [],
+ ];
+ }
+
+ /**
* #pre_render callback for building a block.
*
* Renders the content using the provided block plugin, and then:
diff --git a/core/modules/comment/src/CommentLazyBuilders.php b/core/modules/comment/src/CommentLazyBuilders.php
index 730c840..f223b32 100644
--- a/core/modules/comment/src/CommentLazyBuilders.php
+++ b/core/modules/comment/src/CommentLazyBuilders.php
@@ -3,6 +3,7 @@
namespace Drupal\comment;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
+use Drupal\Component\Utility\Random;
use Drupal\Core\Entity\EntityFormBuilderInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityManagerInterface;
@@ -111,6 +112,17 @@ public function renderForm($commented_entity_type_id, $commented_entity_id, $fie
}
/**
+ * Interface preview for ::renderForm().
+ */
+ public function renderFormPreview() {
+ return [
+ '#type' => 'form',
+ '#theme' => 'form__comment__preview',
+ '#form_id' => 'comment_form_preview',
+ ];
+ }
+
+ /**
* #lazy_builder callback; builds a comment's links.
*
* @param string $comment_entity_id
@@ -151,6 +163,25 @@ public function renderLinks($comment_entity_id, $view_mode, $langcode, $is_in_pr
}
/**
+ * Interface preview for ::renderLinks().
+ */
+ public function renderLinksPreview() {
+ return [
+ '#theme' => 'links__comment__preview',
+ '#pre_render' => ['drupal_pre_render_links'],
+ '#attributes' => ['class' => ['links', 'inline']],
+ 'preview' => [
+ '#theme' => 'links__node',
+ '#links' => [
+ ['title' => '▆▆▆▆▆', 'url' => Url::fromRoute('')],
+ ['title' => '▆▆▆▆▆', 'url' => Url::fromRoute('')],
+ ],
+ ],
+ ];
+ return $this->renderer->renderPlain($links);
+ }
+
+ /**
* Build the default links (reply, edit, delete …) for a comment.
*
* @param \Drupal\comment\CommentInterface $entity
diff --git a/core/themes/classy/templates/form/form--comment--preview.html.twig b/core/themes/classy/templates/form/form--comment--preview.html.twig
new file mode 100644
index 0000000..ec91299
--- /dev/null
+++ b/core/themes/classy/templates/form/form--comment--preview.html.twig
@@ -0,0 +1,3 @@
+