<commit_before>/**
A QuestionnaireItemMedia that plays a video.
NOTE: Useful to capture failure to loads.
This item reports as an array video playback statistics [url, duration, stallingCount, replayCount, videoStartTimes, videoPlayDurations].
url corresponds to the array of all sources for this element.
The duration is the total video length in seconds.
stallingCount counts how often a stalling event occured.
replayCount counts how often the video got replayed explicitly by the user.
videoStartTimes are the points in time, relative to creation of the video, when the video started playing.
videoPlayDurations are the times in seconds how long the audio played each time.

@class QuestionnaireItemMediaVideo
@augments UIElement
@augments UIElementInteractive
@augments QuestionnaireItem
@augments QuestionnaireItemMedia
*/
class QuestionnaireItemMediaVideo extends QuestionnaireItemMedia {

    /**
    @param {string} [className] CSS class
    @param {string} [question]
    @param {boolean} [required=false]
    @param {string|array<string>} url The URL of the media element to be loaded; if supported by the browser also data URI.
    @param {boolean} required Element must report ready before continue.
    @param {boolean} [readyOnError=true] Sets ready=true if an error occures.
    */
    constructor(className, question, required, url, readyOnError) {
        super(className, question, required, url, readyOnError);

        this.videoNode = null;

        this.videoPlayDurations = []; // Stores how long the video got watched each time
        this.videoCreationTime = null; // Point in time when the video gets created
        this.videoStartTimes = []; // Stores when the video started relative to videoCreationTime
        this.replayCount = 0; // Counts how often the video got replayed explicitly with replay()
    }

    _createAnswerNode() {
        const answerNode = document.createElement("div");

        this._createMediaNode();

        answerNode.appendChild(this.videoNode);

        this.videoNode.addEventListener("timeupdate", (event) => this._onProgress(event));
        this.videoNode.addEventListener("error", (event) => this._onError(event));
        this.videoNode.addEventListener("ended", () => this._onEnded());
        this.videoNode.addEventListener("stalled", () => this._onStalled());
        this.videoNode.addEventListener("play", this._onPlay());

        this.videoCreationTime = new Date().getTime();
        return answerNode;
    }

    releaseUI() {
        super.releaseUI();

        this.videoPlayDurations.push(this.videoNode.currentTime);
        this._updateAnswer();

        this.videoNode = null;
    }

    _loadMedia() {
        this._createMediaNode();
    }

    _createMediaNode() {
        if (this.videoNode !== null) {
            TheFragebogen.logger.debug(this.constructor.name + "()", "audioNode was already created.");
            return;<commit_msg>Documentation: Typos in QuestionnaireItemMediaVideo fixed<commit_after>/**
A QuestionnaireItemMedia that plays a video.
NOTE: Useful to capture failure to loads.
This item reports as an array video playback statistics [url, duration, stallingCount, replayCount, videoStartTimes, videoPlayDurations].
url corresponds to the array of all sources for this element.
The duration is the total video length in seconds.
stallingCount counts how often a stalling event occured.
replayCount counts how often the video got replayed explicitly by the user.
videoStartTimes are the points in time, relative to creation of the video, when the video started playing.
videoPlayDurations are the times in seconds how long the video played each time.

@class QuestionnaireItemMediaVideo
@augments UIElement
@augments UIElementInteractive
@augments QuestionnaireItem
@augments QuestionnaireItemMedia
*/
class QuestionnaireItemMediaVideo extends QuestionnaireItemMedia {

    /**
    @param {string} [className] CSS class
    @param {string} [question]
    @param {boolean} [required=false]
    @param {string|array<string>} url The URL of the media element to be loaded; if supported by the browser also data URI.
    @param {boolean} required Element must report ready before continue.
    @param {boolean} [readyOnError=true] Sets ready=true if an error occures.
    */
    constructor(className, question, required, url, readyOnError) {
        super(className, question, required, url, readyOnError);

        this.videoNode = null;

        this.videoPlayDurations = []; // Stores how long the video got watched each time
        this.videoCreationTime = null; // Point in time when the video gets created
        this.videoStartTimes = []; // Stores when the video started relative to videoCreationTime
        this.replayCount = 0; // Counts how often the video got replayed explicitly with replay()
    }

    _createAnswerNode() {
        const answerNode = document.createElement("div");

        this._createMediaNode();

        answerNode.appendChild(this.videoNode);

        this.videoNode.addEventListener("timeupdate", (event) => this._onProgress(event));
        this.videoNode.addEventListener("error", (event) => this._onError(event));
        this.videoNode.addEventListener("ended", () => this._onEnded());
        this.videoNode.addEventListener("stalled", () => this._onStalled());
        this.videoNode.addEventListener("play", this._onPlay());

        this.videoCreationTime = new Date().getTime();
        return answerNode;
    }

    releaseUI() {
        super.releaseUI();

        this.videoPlayDurations.push(this.videoNode.currentTime);
        this._updateAnswer();

        this.videoNode = null;
    }

    _loadMedia() {
        this._createMediaNode();
    }

    _createMediaNode() {
        if (this.videoNode !== null) {
            TheFragebogen.logger.debug(this.constructor.name + "()", "videoNode was already created.");
            return;
{'fraction_non_alphanumeric': 0.09345318860244234, 'fraction_numerical': 0.00033921302578018993, 'mean_word_length': 3.6034348165495707, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '805004', 'n_tokens_mistral': 1528, 'n_tokens_neox': 1463, 'n_words': 515}