# All files / src/lib/markdown-it/plugins/markdown-it-block-embed/services VideoServiceBase.ts

94.59% Statements 35/37
95.23% Branches 20/21
71.42% Functions 5/7
94.44% Lines 34/36

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

    22x

    210x
    210x
    210x

    19x

    19x
    19x

    19x
    19x
    18x

    19x
    19x

    19x
    19x
    18x
    18x
    18x

    19x
    19x
    19x
    19x

    19x
    1x
    1x

    1x
    1x

    19x
    19x
    19x
    19x

    19x
    116x

    19x

    22x
     // Copyright (c) Rotorz Limited and portions by original markdown-it-video authors
    // Licensed under the MIT license. See LICENSE file in the project root.

    import PluginEnvironment from '../PluginEnvironment';

    export interface VideoServiceOptions {
      width?: number;
      height?: number;
      ignoreStyle?: boolean;
      [key: string]: any;
    }

    export type UrlFilterDelegate = (
      url: string,
      serviceName: string,
      videoID: string,
      options: any
    ) => string;

    const defaultUrlFilter: UrlFilterDelegate = (url) => url;

    abstract class VideoServiceBase {
      public name: string;
      public options: VideoServiceOptions;
      public env: PluginEnvironment;

      constructor(name: string, options: VideoServiceOptions, env: PluginEnvironment) {
        this.name = name;
        this.options = Object.assign(this.getDefaultOptions(), options);
        this.env = env;
      }

      public getDefaultOptions(): VideoServiceOptions {
        return {};
      }

      /**
       * Overridden by child classes to extract the ID from a URL/reference.
       */
      public extractVideoID(reference: string): string | null {
        return reference;
      }

      /**
       * Overridden by child classes to provide the specific embed URL.
       */
      public abstract getVideoUrl(videoID: string): string;

      public getFilteredVideoUrl(videoID: string): string {
        let filterUrlDelegate: UrlFilterDelegate = typeof this.env.options.filterUrl === 'function'
            ? (this.env.options.filterUrl as UrlFilterDelegate)
            : defaultUrlFilter;
        let videoUrl = this.getVideoUrl(videoID);
        return filterUrlDelegate(videoUrl, this.name, videoID, this.env.options);
      }

      public getEmbedCode(videoID: string): string {
        let containerClassNames: string[] = [];
        if (this.env.options.containerClassName && this.options.ignoreStyle !== true) {
          containerClassNames.push(this.env.options.containerClassName);
        }

        let escapedServiceName = this.env.md.utils.escapeHtml(this.name);
        containerClassNames.push(this.env.options.serviceClassPrefix + escapedServiceName);

        const containerStyles: string[] = [];
        if (this.options.ignoreStyle !== true) {
          containerStyles.push('position: relative;');
          if (this.options.height !== undefined && this.options.width !== undefined) {
            containerStyles.push(`padding-bottom: ${this.options.height / this.options.width * 100}%`);
          }
        }

        let iframeAttributeList = [];
        iframeAttributeList.push([ "type", "text/html" ]);
        iframeAttributeList.push([ "src", this.getFilteredVideoUrl(videoID) ]);
        iframeAttributeList.push([ "frameborder", 0 ]);

        if (this.env.options.outputPlayerSize === true && this.options.ignoreStyle === true) {
          if (this.options.width !== undefined && this.options.width !== null) {
            iframeAttributeList.push([ "width", this.options.width ]);
          }
          if (this.options.height !== undefined && this.options.height !== null) {
            iframeAttributeList.push([ "height", this.options.height ]);
          }
        }

        if (this.env.options.allowFullScreen === true) {
          iframeAttributeList.push([ "webkitallowfullscreen" ]);
          iframeAttributeList.push([ "mozallowfullscreen" ]);
          iframeAttributeList.push([ "allowfullscreen" ]);
        }

        let iframeAttributes = iframeAttributeList
          .map(([key, value]) => (value !== undefined ? `${key}="${value}"` : key))
          .join(" ");

        return `<div class="${containerClassNames.join(" ")}" style="${containerStyles.join(" ")}">`
               + `<iframe ${iframeAttributes}></iframe>`
               + `</div>\n`;
      }

    }

    export default VideoServiceBase;