diff --git a/colorbox.libraries.yml b/colorbox.libraries.yml index b3ade86..e3ac4d7 100644 --- a/colorbox.libraries.yml +++ b/colorbox.libraries.yml @@ -25,6 +25,14 @@ colorbox-dev: dependencies: - core/jquery - core/once + +colorbox-remote-video: + js: + js/colorbox-remote-video.js: {} + dependencies: + - system/drupal.system + - colorbox/colorbox + - core/once dompurify: remote: https://github.com/cure53/DOMPurify diff --git a/js/colorbox-remote-video.js b/js/colorbox-remote-video.js new file mode 100644 index 0000000..b52201d --- /dev/null +++ b/js/colorbox-remote-video.js @@ -0,0 +1,22 @@ +/** + * @file + * The remote video colorbox integration. + */ + +(function($, Drupal, once) { + Drupal.behaviors.videoRemoteColorbox = { + attach: function (context, settings) { + $(document).ready(function() { + once('colorbox-remote-video', '.remote-video-colorbox-launch-modal', context).forEach(function(el) { + $(el).click(function(e) { + // Allow the thumbnail that launches the modal to link to other places + // such as video URL, so if the modal is sidestepped things degrade + // gracefully. + e.preventDefault(); + $.colorbox($.extend(settings.colorbox, {'html': $(this).data('remote-video-colorbox-modal')})); + }); + }); + }); + } + }; +})(jQuery, Drupal, once); diff --git a/src/Plugin/Field/FieldFormatter/VideoColorbox.php b/src/Plugin/Field/FieldFormatter/VideoColorbox.php new file mode 100644 index 0000000..082725b --- /dev/null +++ b/src/Plugin/Field/FieldFormatter/VideoColorbox.php @@ -0,0 +1,228 @@ +videoFormatter = $video_formatter; + $this->renderer = $renderer; + $this->colorboxAttachment = $colorbox_attachment; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + $formatter_manager = $container->get('plugin.manager.field.formatter'); + return new static( + $plugin_id, + $plugin_definition, + $configuration['field_definition'], + $configuration['settings'], + $configuration['label'], + $configuration['view_mode'], + $configuration['third_party_settings'], + $container->get('renderer'), + $formatter_manager->createInstance('oembed', $configuration), + $container->get('colorbox.attachment') + ); + } + + /** + * {@inheritdoc} + */ + public static function defaultSettings() { + return OEmbedFormatter::defaultSettings() + [ + 'display' => 'thumbnail', + 'link_text' => 'View Video', + 'image_style' => 'thumbnail', + ] + parent::defaultSettings(); + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + $image_styles = image_style_options(FALSE); + $element = parent::settingsForm($form, $form_state); + $element += $this->videoFormatter->settingsForm([], $form_state); + $element['display'] = [ + '#type' => 'select', + '#title' => $this->t('Display'), + '#default_value' => $this->getSetting('display'), + '#options' => [ + 'thumbnail' => $this->t('Thumbnail'), + 'text' => $this->t('Text'), + ], + ]; + $element['link_text'] = [ + '#type' => 'textfield', + '#title' => $this->t('Link text'), + '#default_value' => $this->getSetting('link_text'), + '#states' => [ + 'visible' => [ + [':input[name="options[settings][display]"]' => ['value' => 'text']], + ], + ], + ]; + $element['image_style'] = [ + '#title' => $this->t('Image style'), + '#type' => 'select', + '#default_value' => $this->getSetting('image_style'), + '#empty_option' => $this->t('None (original image)'), + '#options' => $image_styles, + '#states' => [ + 'visible' => [ + [':input[name="options[settings][display]"]' => ['value' => 'thumbnail']], + ], + ], + ]; + return $element; + } + + /** + * {@inheritdoc} + */ + public function settingsSummary() { + $summary[] = $this->t('Text that launches a modal window.'); + if ($video_settings_summary = $this->videoFormatter->settingsSummary()) { + $summary[] = reset($video_settings_summary); + } + if ($this->getSetting('display') == 'text') { + $summary[] = $this->t('Link text: @link_text.', [ + '@link_text' => $this->getSetting('link_text'), + ]); + } + else { + $image_styles = image_style_options(FALSE); + if (isset($image_styles[$this->getSetting('image_style')])) { + $summary[] = $this->t('Thumbnail image: @image_style.', [ + '@image_style' => $image_styles[$this->getSetting('image_style')], + ]); + } + else { + $summary[] = $this->t('Colorbox image style: Original image'); + } + } + return $summary; + } + + /** + * {@inheritdoc} + */ + public function viewElements(FieldItemListInterface $items, $langcode) { + $element = []; + $videos = $this->videoFormatter->viewElements($items, $langcode); + foreach ($items as $delta => $item) { + $element[$delta] = [ + '#type' => 'container', + '#attributes' => [ + 'data-remote-video-colorbox-modal' => (string) $this->renderer->render($videos[$delta]), + 'class' => ['remote-video-colorbox-launch-modal'], + ], + '#attached' => [ + 'library' => [ + 'colorbox/colorbox-remote-video', + ], + ], + // Ensure the cache context from the video formatter which was rendered + // early still exists in the renderable array for this formatter. + '#cache' => [ + 'contexts' => ['user.permissions'], + ], + ]; + if ($this->getSetting('display') == 'text') { + $element[$delta]['children'][] = [ + '#type' => 'inline_template', + '#template' => '', + '#context' => [ + 'link_text' => $this->t($this->getSetting('link_text')), + ], + ]; + } + else { + $element[$delta]['children'][] = [ + '#theme' => 'image_formatter', + '#item' => $items->getEntity()->get('thumbnail')->first(), + '#item_attributes' => [], + '#image_style' => $this->getSetting('image_style'), + '#url' => \Drupal\Core\Url::fromUri($item->getValue()['value']) + ]; + } + } + $this->colorboxAttachment->attach($element); + return $element; + } + +}