All files / src/app/shared/cms/components/cms-video cms-video.component.ts

81.25% Statements 39/48
62.5% Branches 10/16
87.5% Functions 7/8
81.25% Lines 39/48

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 1211x 1x   1x                         1x               4x 4x         4x     4x 4x 4x 4x 4x       4x 4x 4x       4x 4x 4x                   4x 1x           1x                   4x 4x 2x 2x 2x     2x     2x 2x   2x                 2x 2x 1x 1x 1x     1x     1x 1x   1x                  
import { ChangeDetectionStrategy, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core';
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
 
import { ContentPageletView } from 'ish-core/models/content-view/content-view.model';
import { CMSComponent } from 'ish-shared/cms/models/cms-component/cms-component.model';
 
/**
 * The CMS Video Component integrates a CMS managed video either via native video tag
 * or for selected video hosting platforms with the appropriate iframe embedding.
 * Currently supported video hosting: YouTube, Vimeo.
 */
@Component({
  selector: 'ish-cms-video',
  templateUrl: './cms-video.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CMSVideoComponent implements CMSComponent, OnInit {
  @Input({ required: true }) pagelet: ContentPageletView;
 
  @ViewChild('videoPlayer') videoPlayer: ElementRef;
 
  video: string;
  nativeVideoUrl: SafeUrl;
  iframeVideoUrl: SafeUrl;
  videoHeight = '';
  videoWidth = '';
  autoplay: boolean;
  mute: boolean;
  playing: boolean;
 
  constructor(private sanitizer: DomSanitizer) {}
 
  ngOnInit() {
    this.video = this.pagelet.stringParam('Video');
    this.autoplay = this.pagelet.booleanParam('Autoplay');
    this.mute = this.pagelet.booleanParam('Mute');
    this.processVideoSize();
    this.processVideoUrl();
  }
 
  private processVideoSize() {
    const videoSize = this.pagelet.stringParam('VideoSizePreset');
    if (videoSize) {
      Iif (videoSize === 'custom') {
        this.videoWidth = this.pagelet.stringParam('VideoWidth');
        this.videoHeight = this.pagelet.stringParam('VideoHeight');
      } else {
        const split = videoSize.split('x');
        this.videoWidth = split[0];
        this.videoHeight = split[1];
      }
    }
  }
 
  /**
   * Process video URL by trying different processors.
   * If all fail, fall back to the default processor
   */
  private processVideoUrl() {
    if (!this.tryProcessYouTubeVideo() && !this.tryProcessVimeoVideo()) {
      this.tryProcessDefaultVideo();
    }
  }
 
  // visible-for-testing
  tryProcessDefaultVideo() {
    this.nativeVideoUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.video);
  }
 
  /**
   * process video URL with a YouTube video ID regex (https://github.com/regexhq/youtube-regex)
   */
  // spell-checker: words mbed youtu
  // visible-for-testing
  tryProcessYouTubeVideo(): boolean {
    const youTubeVideoRegex =
      /(?:youtube\.com\/\S*(?:(?:\/e(?:mbed))?\/|watch\?(?:\S*?&?v\=))|youtu\.be\/)([a-zA-Z0-9_-]{6,11})/i;
    if (youTubeVideoRegex.test(this.video)) {
      const videoId = youTubeVideoRegex.exec(this.video)[1];
      const videoUrl = new URL(`https://www.youtube.com/embed/${videoId}`);
      Iif (this.autoplay) {
        videoUrl.searchParams.set('autoplay', '1');
      }
      Iif (this.mute) {
        videoUrl.searchParams.set('mute', '1');
      }
      this.iframeVideoUrl = this.sanitizer.bypassSecurityTrustResourceUrl(videoUrl.toString());
      return true;
    }
    return false;
  }
 
  /**
   * process video URL with a Vimeo video ID regex (https://github.com/regexhq/vimeo-regex)
   */
  // visible-for-testing
  tryProcessVimeoVideo(): boolean {
    const vimeoVideoRegex =
      /(http|https)?:\/\/(www\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|)(\d+)(?:|\/\?)/i;
    if (vimeoVideoRegex.test(this.video)) {
      const videoId = vimeoVideoRegex.exec(this.video)[4];
      const videoUrl = new URL(`https://player.vimeo.com/video/${videoId}`);
      Iif (this.autoplay) {
        videoUrl.searchParams.set('autoplay', '1');
      }
      Iif (this.mute) {
        videoUrl.searchParams.set('muted', '1');
      }
      this.iframeVideoUrl = this.sanitizer.bypassSecurityTrustResourceUrl(videoUrl.toString());
      return true;
    }
    return false;
  }
 
  playVideo() {
    const videoElement = this.videoPlayer.nativeElement;
    videoElement.controls = 'controls';
    videoElement.play();
  }
}