strategy-normal.js 5.77 KB
/*
 * ADOBE CONFIDENTIAL
 *
 * Copyright 2015 Adobe Systems Incorporated
 * All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 */
(function($, player) {
    'use strict';

    /**
     * A simple strategy that cycles through the items following their order in the DOM.
     *
     * @class
     *
     * @param {HTMLElement|jQuery}  el  The sequence element
     */
    var NormalStrategy = function(el) {
        this.$el = $(el);
        this.el = this.$el.get(0);

        this.$el.data('screens-strategy', this);

        this.items().hide();
    };

    /**
     * The sequence elements for this strategy.
     */
    NormalStrategy.prototype.init = function() {};

    NormalStrategy.prototype.items = function() {
        return $(this.el.getElementsByClassName('cq-Sequence-item'));
    };

    /**
     * Get the item which is shown when the sequence starts
     *
     * @return {jQuery} The starting item according to the strategy
     */
    NormalStrategy.prototype.startItem = function() {
        return this.items().first();
    };

    /**
     * Check if a cycle is complete
     *
     * @param {jQuery} [$item] The current sequence element
     *
     * @returns {boolean} `true` if the cycle of the sequence is completed, `false` otherwise
     */
    NormalStrategy.prototype.isCycleComplete = function($item) {
        var last = this.items().last();

        // cycle is complete if no item or if current $item is the last one
        return this.items().length === 0 || ($item && (last[0] === $item[0]));
    };

    /**
     * Get the next sequence element for this strategy.
     *
     * @param  {jQuery} [$item] The current sequence element
     *
     * @return {jQuery} The next item according to the strategy
     */
    NormalStrategy.prototype.next = function($item) {
        var $items = this.items();
        if (!$items.length) {
            return null;
        }

        var index = $item ? $items.index($item) : -1;
        var $nextItem = $items.eq((index + 1) % $items.length);
        var nextItem = $nextItem.get(0);
        var transitionType = 'normal';
        var transitionDuration = 0;

        var $transition = $nextItem.prev('.cq-Sequence-transition');
        if ($item) { // Handle sequences that end with a transition
            $transition = $transition.add($item.next('.cq-Sequence-transition'));
        }
        if ($transition && $transition.length) {
            var transitionMeta = $transition.get(0).getElementsByClassName('transition')[0];
            transitionType = transitionMeta ? transitionMeta.dataset.transition : null;
            transitionDuration = transitionMeta ? parseInt(transitionMeta.dataset.transitionDuration, 10) : null;
        }

        if (nextItem.dataset.duration === '0') {
            $nextItem = this.next();
        }
        else if (nextItem.dataset.pauseSequence === 'true') {
            this.$el.trigger('pause-sequence');
        }
        return {
            $item: $nextItem,
            transitionType: transitionType,
            transitionDuration: transitionDuration
        };
    };

    /**
     * Get the duration for the specified sequence element.
     *
     * @param  {jQuery} [$item] The sequence element to get the duration for
     *
     * @return {Number} The duration for the item in ms
     */
    NormalStrategy.prototype.duration = function($item) {
        var item = $item.get(0);
        var duration = null;
        if (item) {
            duration = parseInt(item.dataset.duration, 10);
            if (!duration) {
                var el = item.querySelector('[data-duration]');
                duration = el ? parseInt(el.dataset.duration, 10) : null;

                // Backward compatibility case where channel was created in 6.3 GA
                // A duration of -1 means that the subsequence is responsible for determining the sequence length
                // This was defaulted in the UI after 6.3 GA but channels with subsequences created in older versions
                // may have issues. Therefore adding this default in the code as well
                if ((!duration) && (item.classList.contains('cq-Screens-subsequence'))) {
                    var iFrame = item.getElementsByTagName('iframe')[0];
                    if (iFrame) {
                        iFrame.setAttribute('data-duration', '-1');
                        duration = -1;
                    }
                }
            }
        }

        duration = parseInt(duration, 10);

        if (isNaN(duration) || duration === 0) {
            // 0 or null case, use duration of the sequence
            duration = parseInt(this.el.dataset.duration, 10) || 5000;
        }

        return duration;
    };

    /**
     * Schedule the current item.
     *
     * @param  {Function} callback   Function to call when the next item should play
     * @param  {Number} duration     The duration in ms
     */
    NormalStrategy.prototype.scheduleCurrent = function(callback, duration) {
        this.timeout = window.setTimeout(callback, duration);
    };

    /**
     * Destroy the strategy.
     */
    NormalStrategy.prototype.destroy = function() {
        this.$el.removeData('screens-strategy');
        this.$el = null;
        this.el = null;
    };

    player.strategies.normal = NormalStrategy;

}(window.jQuery, window.ScreensPlayer));