Version 1
[yaffs-website] / web / modules / contrib / diff / src / Plugin / diff / Layout / VisualInlineDiffLayout.php
diff --git a/web/modules/contrib/diff/src/Plugin/diff/Layout/VisualInlineDiffLayout.php b/web/modules/contrib/diff/src/Plugin/diff/Layout/VisualInlineDiffLayout.php
new file mode 100644 (file)
index 0000000..124cc8b
--- /dev/null
@@ -0,0 +1,200 @@
+<?php
+
+namespace Drupal\diff\Plugin\diff\Layout;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Datetime\DateFormatter;
+use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\PhpStorage\PhpStorageFactory;
+use Drupal\Core\Render\RendererInterface;
+use Drupal\diff\Controller\PluginRevisionController;
+use Drupal\diff\DiffEntityComparison;
+use Drupal\diff\DiffEntityParser;
+use Drupal\diff\DiffLayoutBase;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use HtmlDiffAdvancedInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
+
+/**
+ * Provides Visual Inline diff layout.
+ *
+ * @DiffLayoutBuilder(
+ *   id = "visual_inline",
+ *   label = @Translation("Visual Inline"),
+ *   description = @Translation("Visual layout, displays revision comparison using the entity type view mode."),
+ * )
+ */
+class VisualInlineDiffLayout extends DiffLayoutBase {
+
+  /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
+   * The diff entity comparison service.
+   *
+   * @var \Drupal\diff\DiffEntityComparison
+   */
+  protected $entityComparison;
+
+  /**
+   * The html diff service.
+   *
+   * @var \HtmlDiffAdvancedInterface
+   */
+  protected $htmlDiff;
+
+  /**
+   * The request stack.
+   *
+   * @var \Symfony\Component\HttpFoundation\RequestStack
+   */
+  protected $requestStack;
+
+  /**
+   * The entity display repository.
+   *
+   * @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface
+   */
+  protected $entityDisplayRepository;
+
+  /**
+   * Constructs a VisualInlineDiffLayout object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config
+   *   The configuration factory object.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   * @param \Drupal\diff\DiffEntityParser $entity_parser
+   *   The entity parser.
+   * @param \Drupal\Core\DateTime\DateFormatter $date
+   *   The date service.
+   * @param \Drupal\Core\Render\RendererInterface $renderer
+   *   The renderer.
+   * @param \Drupal\diff\DiffEntityComparison $entity_comparison
+   *   The diff entity comparison service.
+   * @param \HtmlDiffAdvancedInterface $html_diff
+   *   The html diff service.
+   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+   *   The request stack.
+   * @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entity_display_repository
+   *   The entity display repository.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config, EntityTypeManagerInterface $entity_type_manager, DiffEntityParser $entity_parser, DateFormatter $date, RendererInterface $renderer, DiffEntityComparison $entity_comparison, HtmlDiffAdvancedInterface $html_diff, RequestStack $request_stack, EntityDisplayRepositoryInterface $entity_display_repository) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $config, $entity_type_manager, $entity_parser, $date);
+    $this->renderer = $renderer;
+    $this->entityComparison = $entity_comparison;
+    $storage = PhpStorageFactory::get('html_purifier_serializer');
+    if (!$storage->exists('cache.php')) {
+      $storage->save('cache.php', 'dummy');
+    }
+    $html_diff->getConfig()->setPurifierCacheLocation(dirname($storage->getFullPath('cache.php')));
+    $this->htmlDiff = $html_diff;
+    $this->requestStack = $request_stack;
+    $this->entityDisplayRepository = $entity_display_repository;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('config.factory'),
+      $container->get('entity_type.manager'),
+      $container->get('diff.entity_parser'),
+      $container->get('date.formatter'),
+      $container->get('renderer'),
+      $container->get('diff.entity_comparison'),
+      $container->get('diff.html_diff'),
+      $container->get('request_stack'),
+      $container->get('entity_display.repository')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function build(ContentEntityInterface $left_revision, ContentEntityInterface $right_revision, ContentEntityInterface $entity) {
+    // Build the revisions data.
+    $build = $this->buildRevisionsData($left_revision, $right_revision);
+
+    $this->entityTypeManager->getStorage($entity->getEntityTypeId())->resetCache([$entity->id()]);
+    // Build the view modes filter.
+    $options = [];
+    // Get all view modes for entity type.
+    $view_modes = $this->entityDisplayRepository->getViewModeOptionsByBundle($entity->getEntityTypeId(), $entity->bundle());
+    foreach ($view_modes as $view_mode => $view_mode_info) {
+      // Skip view modes that are not used in the front end.
+      if (in_array($view_mode, ['rss', 'search_index'])) {
+        continue;
+      }
+      $options[$view_mode] = [
+        'title' => $view_mode_info,
+        'url' => PluginRevisionController::diffRoute($entity,
+          $left_revision->getRevisionId(),
+          $right_revision->getRevisionId(),
+          'visual_inline',
+          ['view_mode' => $view_mode]
+        ),
+      ];
+    }
+
+    $active_option = array_keys($options);
+    $active_view_mode = $this->requestStack->getCurrentRequest()->query->get('view_mode') ?: reset($active_option);
+
+    $filter = $options[$active_view_mode];
+    unset($options[$active_view_mode]);
+    array_unshift($options, $filter);
+
+    $build['controls']['view_mode'] = [
+      '#type' => 'item',
+      '#title' => $this->t('View mode'),
+      '#wrapper_attributes' => ['class' => 'diff-controls__item'],
+      'filter' => [
+        '#type' => 'operations',
+        '#links' => $options,
+      ],
+    ];
+
+    $view_builder = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId());
+    // Trigger exclusion of interactive items like on preview.
+    $left_revision->in_preview = TRUE;
+    $right_revision->in_preview = TRUE;
+    $left_view = $view_builder->view($left_revision, $active_view_mode);
+    $right_view = $view_builder->view($right_revision, $active_view_mode);
+
+    // Avoid render cache from being built.
+    unset($left_view['#cache']);
+    unset($right_view['#cache']);
+
+    $html_1 = $this->renderer->render($left_view);
+    $html_2 = $this->renderer->render($right_view);
+
+    $this->htmlDiff->setOldHtml($html_1);
+    $this->htmlDiff->setNewHtml($html_2);
+    $this->htmlDiff->build();
+
+    $build['diff'] = [
+      '#markup' => $this->htmlDiff->getDifference(),
+      '#weight' => 10,
+    ];
+
+    $build['#attached']['library'][] = 'diff/diff.visual_inline';
+    return $build;
+  }
+
+}