<commit_before>
function SmileySlider(container) {

    var width = 329
    var height = 37

    var headWidth = 40
    var maxHeadX = width - headWidth + 1

    var base = document.createElement('div')
    base.style.width = width + "px"
    base.style.height = height + "px"
    base.style.background = "white"

    var track = document.createElement('div')
    track.style.width = width + "px"
    track.style.height = 6 + "px"
    track.style.marginRight = '-' + track.style.width
    track.style.marginBottom = '-' + track.style.height
    track.style.position = "relative"
    track.style.top = 15 + "px"
    track.style.background = "url('smiley-slider.png')"
    base.appendChild(track)

    var head = document.createElement('div')
    head.style.width = headWidth + "px"
    head.style.height = height + "px"
    head.style.marginRight = '-' + head.style.width
    head.style.marginBottom = '-' + head.style.height
    head.style.position = "relative"
    head.style.background = "url('smiley-slider.png') scroll 0px -6px"
    base.appendChild(head)

    var face = document.createElement('canvas')
    face.style.width = 36 + "px"
    face.style.height = 37 + "px"
    face.style.position = "relative"
    face.style.left = 4 + "px"
    face.width = "36"
    face.height = "37"
    head.appendChild(face)

    var glass = document.createElement('div')
    glass.style.width = width + "px"
    glass.style.height = height + "px"
    glass.style.marginRight = '-' + glass.style.width
    glass.style.marginBottom = '-' + glass.style.height
    glass.style.position = "relative"
    base.appendChild(glass)

    container.appendChild(base)

    //////////////////////////////////////////////////////////////
    // head position

    var onHeadMove = null

    function positionInt(e) {
        if (e === undefined) {
            return getPos(head).x - getPos(base).x
        } else {
            head.style.left = Math.round(cap(e, 0, maxHeadX)) + "px"
            var p = position()
            drawFace(face, 100, p, 0.8)
            if (onHeadMove) onHeadMove(p)
        }
    }

    function position(e) {
        if (e === undefined) {
            return lerp(0, 0, maxHeadX, 1, positionInt())
        } else if (typeof(e) == "function") {
            onHeadMove = e
        } else {
            positionInt(lerp(0, 0, 1, maxHeadX, e))
        }
    }

    this.position = position
    position(0.5)

    //////////////////////////////////////////////////////////////
    // mouse

    glass.onmousedown = function (e) {
        e.preventDefault()
        var pos = getRelPos(glass, e)

        var grabX = headWidth / 2
        var headX = positionInt()
        if (pos.x >= headX && pos.x < headX + headWidth) {
            grabX = pos.x - headX
        }

        positionInt(pos.x - grabX)

        var oldMove = document.onmousemove
        document.onmousemove = function (e) {
            var pos = getRelPos(glass, e)

            positionInt(pos.x - grabX)
        }

        var oldUp = document.onmouseup
        document.onmouseup = function (e) {
            document.onmousemove = oldMove
            document.onmouseup = oldUp
        }
    }

    //////////////////////////////////////////////////////////////
    // core drawing code

    const PI180 = Math.PI / 180;

    function drawFace(canvas, radius, emotion, innerScale) {
        emotion = Math.max(0, Math.min(1, emotion));
        var diam = radius * 2;

        var ctx = canvas.getContext('2d');
        ctx.clearRect (0, 0, diam, diam);

        ctx.beginPath();
        ctx.fillStyle = '#414084';
        drawSmile(ctx, 15.5, 20, innerScale, emotion);
        ctx.closePath();
        ctx.fill();

        ctx.beginPath();
        ctx.lineWidth = 1;
        ctx.strokeStyle = '#414084';
        drawEyeBrows(ctx, 9.5, 16, 23, 16, 7, 5, emotion);
        ctx.stroke();
    };

    function drawSmile(context, mainRadius, offsetY, innerScale, emotion) {
        var eased = 1 - easeInQuad(emotion, 0, 1, 1);
        var innerScale = innerScale - (eased * 0.4);
        var curveOffset = easeInCubic(emotion, 0.1, 0.6, 1);
        drawArc(context, mainRadius, offsetY, innerScale, emotion);
        drawArc(context, mainRadius, offsetY, innerScale, emotion, curveOffset, true);
    }

    function easeInCubic(t, b, c, d) {
        return c*(t/=d)*t*t + b;
    }

    function easeInQuad(t, b, c, d) {
        return c*(t/=d)*t + b;
    }

    function drawArc(context, mainRadius, offsetY, innerScale, emotion, curveOffset, reverseX) {
        curveOffset = (curveOffset === undefined) ? 0 : curveOffset;

        var innerRadius = mainRadius * innerScale;
        var pad = mainRadius - innerRadius;
        var diam = innerRadius * 2;

        const PI180 = Math.PI / 180;
        const SEGS = 16;

        var theta = 360 / SEGS;
        var emoScale = (emotion - 0.5) * 2;

        var sides = [pad, pad + diam];
        var ct = [[0, 0], [0, 0]];

        ct[0][0] = innerRadius * Math.cos((theta * 3) * PI180) + pad ;
        ct[0][1] = innerRadius * Math.sin((theta * 3) * PI180) * emoScale + offsetY + pad - (curveOffset * mainRadius);

        ct[1][0] = innerRadius * Math.cos((theta * 5) * PI180) + pad + (innerRadius * 2);
        ct[1][1] = innerRadius * Math.sin((theta * 5) * PI180) * emoScale + offsetY + pad - (curveOffset * mainRadius);

        if (reverseX) {
            sides.reverse();
            ct.reverse();
        }

        context.moveTo(sides[0], offsetY + pad);
        context.bezierCurveTo(ct[0][0], ct[0][1], ct[1][0], ct[1][1], sides[1], offsetY + pad);
    }

    function drawEyeBrows(context, x1, y1, x2, y2, width, distance, emotion) {
        var a = (emotion - 0.5) * 30;
        var hW = width * 0.5;

        var l1 = rotZ(-hW, -distance, -a);
        var l2 = rotZ(hW , -distance, -a);

        var r1 = rotZ(-hW, -distance, a);
        var r2 = rotZ(hW , -distance, a);

        context.moveTo(l1[0] + x1, l1[1] + y1);
        context.lineTo(l2[0] + x1, l2[1] + y1);

        context.moveTo(r1[0] + x2, r1[1] + y2);
        context.lineTo(r2[0] + x2, r2[1] + y2);
    }

    function rotZ(x, y, angle) {
        var cos = Math.cos(angle * PI180);
        var sin = Math.sin(angle * PI180);
        var tx = x * cos - y * sin;
        var ty = x * sin + y * cos;
        return [tx, ty];
    }

    //////////////////////////////////////////////////////////////
    // utils

    function cap(t, mi, ma) {
        if (t < mi) return mi
        if (t > ma) return ma
        return t
    }

    function lerp(t0, v0, t1, v1, t) {
        return (t - t0) * (v1 - v0) / (t1 - t0) + v0
    }

    function getPos(e) {
        var x = 0, y = 0
        while (e != null) {
            x += e.offsetLeft
            y += e.offsetTop
            e = e.offsetParent
        }
        return {x : x, y : x}
    }

    function getRelPos(to, event) {
        var pos = getPos(to)
        return {
            x : event.pageX - pos.x,
            y : event.pageY - pos.y
        }
    }
}

<commit_msg>allows overriding the image source<commit_after>
function SmileySlider(container, imgSrc) {
    if (!imgSrc)
        imgSrc = "smiley-slider.png"

    var width = 329
    var height = 37

    var headWidth = 40
    var maxHeadX = width - headWidth + 1

    var base = document.createElement('div')
    base.style.width = width + "px"
    base.style.height = height + "px"
    base.style.background = "white"

    var track = document.createElement('div')
    track.style.width = width + "px"
    track.style.height = 6 + "px"
    track.style.marginRight = '-' + track.style.width
    track.style.marginBottom = '-' + track.style.height
    track.style.position = "relative"
    track.style.top = 15 + "px"
    track.style.background = "url('" + imgSrc + "')"
    base.appendChild(track)

    var head = document.createElement('div')
    head.style.width = headWidth + "px"
    head.style.height = height + "px"
    head.style.marginRight = '-' + head.style.width
    head.style.marginBottom = '-' + head.style.height
    head.style.position = "relative"
    head.style.background = "url('" + imgSrc + "') scroll 0px -6px"
    base.appendChild(head)

    var face = document.createElement('canvas')
    face.style.width = 36 + "px"
    face.style.height = 37 + "px"
    face.style.position = "relative"
    face.style.left = 4 + "px"
    face.width = "36"
    face.height = "37"
    head.appendChild(face)

    var glass = document.createElement('div')
    glass.style.width = width + "px"
    glass.style.height = height + "px"
    glass.style.marginRight = '-' + glass.style.width
    glass.style.marginBottom = '-' + glass.style.height
    glass.style.position = "relative"
    base.appendChild(glass)

    container.appendChild(base)

    //////////////////////////////////////////////////////////////
    // head position

    var onHeadMove = null

    function positionInt(e) {
        if (e === undefined) {
            return getPos(head).x - getPos(base).x
        } else {
            head.style.left = Math.round(cap(e, 0, maxHeadX)) + "px"
            var p = position()
            drawFace(face, 100, p, 0.8)
            if (onHeadMove) onHeadMove(p)
        }
    }

    function position(e) {
        if (e === undefined) {
            return lerp(0, 0, maxHeadX, 1, positionInt())
        } else if (typeof(e) == "function") {
            onHeadMove = e
        } else {
            positionInt(lerp(0, 0, 1, maxHeadX, e))
        }
    }

    this.position = position
    position(0.5)

    //////////////////////////////////////////////////////////////
    // mouse

    glass.onmousedown = function (e) {
        e.preventDefault()
        var pos = getRelPos(glass, e)

        var grabX = headWidth / 2
        var headX = positionInt()
        if (pos.x >= headX && pos.x < headX + headWidth) {
            grabX = pos.x - headX
        }

        positionInt(pos.x - grabX)

        var oldMove = document.onmousemove
        document.onmousemove = function (e) {
            var pos = getRelPos(glass, e)

            positionInt(pos.x - grabX)
        }

        var oldUp = document.onmouseup
        document.onmouseup = function (e) {
            document.onmousemove = oldMove
            document.onmouseup = oldUp
        }
    }

    //////////////////////////////////////////////////////////////
    // core drawing code

    const PI180 = Math.PI / 180;

    function drawFace(canvas, radius, emotion, innerScale) {
        emotion = Math.max(0, Math.min(1, emotion));
        var diam = radius * 2;

        var ctx = canvas.getContext('2d');
        ctx.clearRect (0, 0, diam, diam);

        ctx.beginPath();
        ctx.fillStyle = '#414084';
        drawSmile(ctx, 15.5, 20, innerScale, emotion);
        ctx.closePath();
        ctx.fill();

        ctx.beginPath();
        ctx.lineWidth = 1;
        ctx.strokeStyle = '#414084';
        drawEyeBrows(ctx, 9.5, 16, 23, 16, 7, 5, emotion);
        ctx.stroke();
    };

    function drawSmile(context, mainRadius, offsetY, innerScale, emotion) {
        var eased = 1 - easeInQuad(emotion, 0, 1, 1);
        var innerScale = innerScale - (eased * 0.4);
        var curveOffset = easeInCubic(emotion, 0.1, 0.6, 1);
        drawArc(context, mainRadius, offsetY, innerScale, emotion);
        drawArc(context, mainRadius, offsetY, innerScale, emotion, curveOffset, true);
    }

    function easeInCubic(t, b, c, d) {
        return c*(t/=d)*t*t + b;
    }

    function easeInQuad(t, b, c, d) {
        return c*(t/=d)*t + b;
    }

    function drawArc(context, mainRadius, offsetY, innerScale, emotion, curveOffset, reverseX) {
        curveOffset = (curveOffset === undefined) ? 0 : curveOffset;

        var innerRadius = mainRadius * innerScale;
        var pad = mainRadius - innerRadius;
        var diam = innerRadius * 2;

        const PI180 = Math.PI / 180;
        const SEGS = 16;

        var theta = 360 / SEGS;
        var emoScale = (emotion - 0.5) * 2;

        var sides = [pad, pad + diam];
        var ct = [[0, 0], [0, 0]];

        ct[0][0] = innerRadius * Math.cos((theta * 3) * PI180) + pad ;
        ct[0][1] = innerRadius * Math.sin((theta * 3) * PI180) * emoScale + offsetY + pad - (curveOffset * mainRadius);

        ct[1][0] = innerRadius * Math.cos((theta * 5) * PI180) + pad + (innerRadius * 2);
        ct[1][1] = innerRadius * Math.sin((theta * 5) * PI180) * emoScale + offsetY + pad - (curveOffset * mainRadius);

        if (reverseX) {
            sides.reverse();
            ct.reverse();
        }

        context.moveTo(sides[0], offsetY + pad);
        context.bezierCurveTo(ct[0][0], ct[0][1], ct[1][0], ct[1][1], sides[1], offsetY + pad);
    }

    function drawEyeBrows(context, x1, y1, x2, y2, width, distance, emotion) {
        var a = (emotion - 0.5) * 30;
        var hW = width * 0.5;

        var l1 = rotZ(-hW, -distance, -a);
        var l2 = rotZ(hW , -distance, -a);

        var r1 = rotZ(-hW, -distance, a);
        var r2 = rotZ(hW , -distance, a);

        context.moveTo(l1[0] + x1, l1[1] + y1);
        context.lineTo(l2[0] + x1, l2[1] + y1);

        context.moveTo(r1[0] + x2, r1[1] + y2);
        context.lineTo(r2[0] + x2, r2[1] + y2);
    }

    function rotZ(x, y, angle) {
        var cos = Math.cos(angle * PI180);
        var sin = Math.sin(angle * PI180);
        var tx = x * cos - y * sin;
        var ty = x * sin + y * cos;
        return [tx, ty];
    }

    //////////////////////////////////////////////////////////////
    // utils

    function cap(t, mi, ma) {
        if (t < mi) return mi
        if (t > ma) return ma
        return t
    }

    function lerp(t0, v0, t1, v1, t) {
        return (t - t0) * (v1 - v0) / (t1 - t0) + v0
    }

    function getPos(e) {
        var x = 0, y = 0
        while (e != null) {
            x += e.offsetLeft
            y += e.offsetTop
            e = e.offsetParent
        }
        return {x : x, y : x}
    }

    function getRelPos(to, event) {
        var pos = getPos(to)
        return {
            x : event.pageX - pos.x,
            y : event.pageY - pos.y
        }
    }
}

<|endoftext|>


<commit_before>goog.provide('mirosubs.subtitle.MainPanel');
goog.provide('mirosubs.subtitle.MainPanel.EventType');

/**
 * @fileoverview In this class, the three states {0, 1, 2} correspond to
 *     { transcribe, sync, review }.
 */

/**
 *
 * @param {mirosubs.subtitle.ServerModel} serverModel
 * @param {Array.<Object.<string, *>>} existingCaptions existing captions in
 *     json object format.
 */
mirosubs.subtitle.MainPanel = function(videoPlayer,
                                       serverModel,
                                       existingCaptions) {
    goog.ui.Component.call(this);
    this.videoPlayer_ = videoPlayer;
    var uw = this.unitOfWork_ = new mirosubs.UnitOfWork();
    /**
     * Array of captions.
     * @type {Array.<mirosubs.subtitle.EditableCaption>}
     */
    this.captions_ =
        goog.array.map(existingCaptions,
                       function(caption) {
                           return new mirosubs.subtitle.EditableCaption(uw, caption);
                       });
    this.captionManager_ =
        new mirosubs.CaptionManager(videoPlayer.getPlayheadFn());
    this.captionManager_.addCaptions(existingCaptions);
    this.getHandler().listen(this.captionManager_,
                             mirosubs.CaptionManager.EventType.CAPTION,
                             this.captionReached_, false, this);
    this.serverModel_ = serverModel;
    this.serverModel_.init(uw);
    this.tabs_ = [];
    this.showingInterPanel_ = false;
};
goog.inherits(mirosubs.subtitle.MainPanel, goog.ui.Component);

mirosubs.subtitle.MainPanel.EventType = {
    FINISHED: "finishedediting"
};

mirosubs.subtitle.MainPanel.prototype.getContentElement = function() {
    return this.contentElem_;
};

mirosubs.subtitle.MainPanel.prototype.handleKeyDown_ = function(event) {
    if (event.keyCode == goog.events.KeyCodes.CTRL) {
        var now = this.videoPlayer_.getPlayheadTime();
        this.videoPlayer_.setPlayheadTime(now>3 ? now-3 : 0);
    }
    if (event.keyCode == goog.events.KeyCodes.TAB)
        this.videoPlayer_.togglePause();
};

mirosubs.subtitle.MainPanel.prototype.createDom = function() {
    mirosubs.subtitle.MainPanel.superClass_.createDom.call(this);

    var that = this;
    var el = this.getElement();
    var $d = goog.bind(this.getDomHelper().createDom, this.getDomHelper());

    el.appendChild(this.contentElem_ = $d('div'));
    el.appendChild($d('div', { 'className': 'mirosubs-nextStep' },
                      this.nextMessageSpan_ = $d('span'),
                      this.nextStepLink_ = $d('a', { 'href': '#'})));
    this.getHandler().listen(this.nextStepLink_, 'click',
                             this.nextStepClicked_, false, this);
    this.tabs_ = this.createTabElems_()
    el.appendChild($d('ul', { 'className' : 'mirosubs-nav' }, this.tabs_));
    this.setState_(0);
    this.getHandler().listen(document,
                             goog.events.EventType.KEYDOWN,
                             this.handleKeyDown_, false, this);
};

mirosubs.subtitle.MainPanel.prototype.setNextStepText =
    function(messageText, buttonText) {
    var $c = goog.dom.setTextContent;
    $c(this.nextMessageSpan_, messageText);
    $c(this.nextStepLink_, buttonText);
};

mirosubs.subtitle.MainPanel.prototype.createTabElems_ = function() {
    var that = this;
    var h = this.getHandler();
    var $d = goog.bind(this.getDomHelper().createDom, this.getDomHelper());
    return goog.array.map(["Transcribe", "Sync", "Review"],
                          function(label, index) {
                              var a = $d('a', { 'href': '#' }, label);
                              h.listen(a, 'click',
                                       function(event) {
                                           that.setState_(index);
                                           event.preventDefault();
                                       });
                              return $d('li',
                                        {'className': 'mirosubs-nav' + label},
                                        a);
                          });
};
mirosubs.subtitle.MainPanel.prototype.captionReached_ = function(jsonCaptionEvent) {
    var c = jsonCaptionEvent.caption;
    this.videoPlayer_.showCaptionText(c ? c['caption_text'] : '');
};
mirosubs.subtitle.MainPanel.prototype.nextStepClicked_ = function(event) {
    this.setState_(this.state_ + 1);
    event.preventDefault();
};
mirosubs.subtitle.MainPanel.prototype.setState_ = function(state) {
    if (this.showingInterPanel_ || state == 0 || state == 1 || state == 2) {
        this.showingInterPanel_ = false;
        this.disposeCurrentWidget_();
        if (state < 3) {
            this.removeChildren(true);
            this.state_ = state;
            this.videoPlayer_.setPlayheadTime(0);
            this.selectTab_(state);
            this.addChild(this.makeNextWidget_(state), true);
            this.setNextStepText("When you're done, click here", "Next Step");
        }
        else
            this.finishEditing_();
    }
    else {
        this.removeChildren(true);
        this.showingInterPanel_ = true;
        this.addChild(this.makeInterPanel_(state), true);
        if (state == 3)
            this.setNextStepText("Click close to finish", "Close");
    }
};
mirosubs.subtitle.MainPanel.prototype.selectTab_ = function(state) {
    var c = goog.dom.classes;
    for (var i = 0; i < this.tabs_.length; i++) {
        if (i == state)
            c.add(this.tabs_[i], 'active');
        else
            c.remove(this.tabs_[i], 'active');
    }
};

mirosubs.subtitle.MainPanel.prototype.disposeCurrentWidget_ = function() {
    if (this.currentWidget_) {
        this.currentWidget_.dispose();
        this.currentWidget_ = null;
    }
};

mirosubs.subtitle.MainPanel.prototype.makeNextWidget_ = function(state) {
    if (state == 0)
        this.currentWidget_ = new mirosubs.subtitle.TranscribePanel(
            this.captions_, this.unitOfWork_, this.videoPlayer_);
    else if (state == 1)
        this.currentWidget_ = new mirosubs.subtitle.SyncPanel(
            this.captions_,
            this.videoPlayer_.getPlayheadFn(),
            this.captionManager_);
    else if (state == 2)
        this.currentWidget_ = new mirosubs.subtitle.SyncPanel(
            this.captions_,
            this.videoPlayer_.getPlayheadFn(),
            this.captionManager_);
    return this.currentWidget_;
};

mirosubs.subtitle.MainPanel.prototype.makeInterPanel_ = function(state) {
    if (state < 3)
        return new mirosubs.subtitle.InterPanel("Great job, carry on!");
    else
        return new mirosubs.subtitle
            .InterPanel("Thank you, click close to end the session",
                        "finished");
};

mirosubs.subtitle.MainPanel.prototype.finishEditing_ = function() {
    var that = this;
    // TODO: show loading
    this.serverModel_.finish(function() {
            // TODO: hide loading.
            that.dispatchEvent(mirosubs.subtitle.MainPanel
                               .EventType.FINISHED);
            that.dispose();
        });
};

mirosubs.subtitle.MainPanel.prototype.disposeInternal = function() {
    mirosubs.subtitle.MainPanel.superClass_.disposeInternal.call(this);
    this.disposeCurrentWidget_();
    this.serverModel_.dispose();
    this.captionManager_.dispose();
    this.videoPlayer_.showCaptionText('');
};

<commit_msg>minor changes<commit_after>goog.provide('mirosubs.subtitle.MainPanel');
goog.provide('mirosubs.subtitle.MainPanel.EventType');

/**
 * @fileoverview In this class, the three states {0, 1, 2} correspond to
 *     { transcribe, sync, review }.
 */

/**
 *
 * @param {mirosubs.subtitle.ServerModel} serverModel
 * @param {Array.<Object.<string, *>>} existingCaptions existing captions in
 *     json object format.
 */
mirosubs.subtitle.MainPanel = function(videoPlayer,
                                       serverModel,
                                       existingCaptions) {
    goog.ui.Component.call(this);
    this.videoPlayer_ = videoPlayer;
    var uw = this.unitOfWork_ = new mirosubs.UnitOfWork();
    /**
     * Array of captions.
     * @type {Array.<mirosubs.subtitle.EditableCaption>}
     */
    this.captions_ =
        goog.array.map(existingCaptions,
                       function(caption) {
                           return new mirosubs.subtitle.EditableCaption(uw, caption);
                       });
    this.captionManager_ =
        new mirosubs.CaptionManager(videoPlayer.getPlayheadFn());
    this.captionManager_.addCaptions(existingCaptions);
    this.getHandler().listen(this.captionManager_,
                             mirosubs.CaptionManager.EventType.CAPTION,
                             this.captionReached_, false, this);
    this.serverModel_ = serverModel;
    this.serverModel_.init(uw);
    this.tabs_ = [];
    this.showingInterPanel_ = false;
};
goog.inherits(mirosubs.subtitle.MainPanel, goog.ui.Component);

mirosubs.subtitle.MainPanel.EventType = {
    FINISHED: "finishedediting"
};

mirosubs.subtitle.MainPanel.prototype.getContentElement = function() {
    return this.contentElem_;
};

mirosubs.subtitle.MainPanel.prototype.handleKeyDown_ = function(event) {
    if (event.keyCode == goog.events.KeyCodes.CTRL) {
        var now = this.videoPlayer_.getPlayheadTime();
        this.videoPlayer_.setPlayheadTime(Math.max(now - 3, 0));
    }
    if (event.keyCode == goog.events.KeyCodes.TAB)
        this.videoPlayer_.togglePause();
};

mirosubs.subtitle.MainPanel.prototype.createDom = function() {
    mirosubs.subtitle.MainPanel.superClass_.createDom.call(this);

    var that = this;
    var el = this.getElement();
    var $d = goog.bind(this.getDomHelper().createDom, this.getDomHelper());

    el.appendChild(this.contentElem_ = $d('div'));
    el.appendChild($d('div', { 'className': 'mirosubs-nextStep' },
                      this.nextMessageSpan_ = $d('span'),
                      this.nextStepLink_ = $d('a', { 'href': '#'})));
    this.getHandler().listen(this.nextStepLink_, 'click',
                             this.nextStepClicked_, false, this);
    this.tabs_ = this.createTabElems_()
    el.appendChild($d('ul', { 'className' : 'mirosubs-nav' }, this.tabs_));
    this.setState_(0);
    this.getHandler().listen(document,
                             goog.events.EventType.KEYDOWN,
                             this.handleKeyDown_, false, this);
};

mirosubs.subtitle.MainPanel.prototype.setNextStepText =
    function(messageText, buttonText) {
    var $c = goog.dom.setTextContent;
    $c(this.nextMessageSpan_, messageText);
    $c(this.nextStepLink_, buttonText);
};

mirosubs.subtitle.MainPanel.prototype.createTabElems_ = function() {
    var that = this;
    var h = this.getHandler();
    var $d = goog.bind(this.getDomHelper().createDom, this.getDomHelper());
    return goog.array.map(["Transcribe", "Sync", "Review"],
                          function(label, index) {
                              var a = $d('a', { 'href': '#' }, label);
                              h.listen(a, 'click',
                                       function(event) {
                                           that.setState_(index);
                                           event.preventDefault();
                                       });
                              return $d('li',
                                        {'className': 'mirosubs-nav' + label},
                                        a);
                          });
};
mirosubs.subtitle.MainPanel.prototype.captionReached_ = function(jsonCaptionEvent) {
    var c = jsonCaptionEvent.caption;
    this.videoPlayer_.showCaptionText(c ? c['caption_text'] : '');
};
mirosubs.subtitle.MainPanel.prototype.nextStepClicked_ = function(event) {
    this.setState_(this.state_ + 1);
    event.preventDefault();
};
mirosubs.subtitle.MainPanel.prototype.setState_ = function(state) {
    if (this.showingInterPanel_ || state == 0 || state == 1 || state == 2) {
        this.showingInterPanel_ = false;
        this.disposeCurrentWidget_();
        if (state < 3) {
            this.removeChildren(true);
            this.state_ = state;
            this.videoPlayer_.setPlayheadTime(0);
            this.selectTab_(state);
            this.addChild(this.makeNextWidget_(state), true);
            this.setNextStepText("When you're done, click here", "Next Step");
        }
        else
            this.finishEditing_();
    }
    else {
        this.removeChildren(true);
        this.showingInterPanel_ = true;
        this.addChild(this.makeInterPanel_(state), true);
        if (state == 3)
            this.setNextStepText("Click close to finish", "Close");
    }
};
mirosubs.subtitle.MainPanel.prototype.selectTab_ = function(state) {
    var c = goog.dom.classes;
    for (var i = 0; i < this.tabs_.length; i++) {
        if (i == state)
            c.add(this.tabs_[i], 'active');
        else
            c.remove(this.tabs_[i], 'active');
    }
};

mirosubs.subtitle.MainPanel.prototype.disposeCurrentWidget_ = function() {
    if (this.currentWidget_) {
        this.currentWidget_.dispose();
        this.currentWidget_ = null;
    }
};

mirosubs.subtitle.MainPanel.prototype.makeNextWidget_ = function(state) {
    if (state == 0)
        this.currentWidget_ = new mirosubs.subtitle.TranscribePanel(
            this.captions_, this.unitOfWork_, this.videoPlayer_);
    else if (state == 1)
        this.currentWidget_ = new mirosubs.subtitle.SyncPanel(
            this.captions_,
            this.videoPlayer_.getPlayheadFn(),
            this.captionManager_);
    else if (state == 2)
        this.currentWidget_ = new mirosubs.subtitle.SyncPanel(
            this.captions_,
            this.videoPlayer_.getPlayheadFn(),
            this.captionManager_);
    return this.currentWidget_;
};

mirosubs.subtitle.MainPanel.prototype.makeInterPanel_ = function(state) {
    if (state < 3)
        return new mirosubs.subtitle.InterPanel("Great job, carry on!");
    else
        return new mirosubs.subtitle
            .InterPanel("Thank you, click close to end the session",
                        "finished");
};

mirosubs.subtitle.MainPanel.prototype.finishEditing_ = function() {
    var that = this;
    // TODO: show loading
    this.serverModel_.finish(function() {
            // TODO: hide loading.
            that.dispatchEvent(mirosubs.subtitle.MainPanel
                               .EventType.FINISHED);
            that.dispose();
        });
};

mirosubs.subtitle.MainPanel.prototype.disposeInternal = function() {
    mirosubs.subtitle.MainPanel.superClass_.disposeInternal.call(this);
    this.disposeCurrentWidget_();
    this.serverModel_.dispose();
    this.captionManager_.dispose();
    this.videoPlayer_.showCaptionText('');
};

<|endoftext|>


<commit_before>$(document).ready(function(){
    $("a#sms-record").parent().hide();
    $(".nav-pills").append(
        $("

").append(
            $("").attr("href", "http://google.com")
            .append($("").attr("class", "fa fa-infolis"))
            .append("Forschungsdaten suchen!")
        )
    );
});
<commit_msg>removed infolis js (cannot be in local)<commit_after><|endoftext|>


<commit_before>/* =============================================================

    Smooth Scroll 2.2
    Animate scrolling to anchor links, by Chris Ferdinandi.
    http://gomakethings.com

    Free to use under the MIT License.
    http://gomakethings.com/mit/

 * ============================================================= */

// Feature Test
if ( 'querySelector' in document && 'addEventListener' in window && Array.prototype.forEach ) {

    // Function to animate the scroll
    var smoothScroll = function (anchor, duration) {

        // Calculate how far and how fast to scroll
        var startLocation = window.pageYOffset;
        var endLocation = anchor.offsetTop;
        var distance = endLocation - startLocation;
        var increments = distance/(duration/16);

        // Scroll the page by an increment, and check if it's time to stop
        var animateScroll = function () {
            window.scrollBy(0, increments);
            stopAnimation();
        }

        // If scrolling down
        if ( increments >= 0 ) {
            // Stop animation when you reach the anchor OR the bottom of the page
            var stopAnimation = function () {
                var travelled = window.pageYOffset;
                if ( (travelled >= (endLocation - increments)) || ((window.innerHeight + travelled) >= document.body.offsetHeight) ) {
                    clearInterval(runAnimation);
                }
            }
        }
        // If scrolling up
        else {
            // Stop animation when you reach the anchor OR the top of the page
            var stopAnimation = function () {
                var travelled = window.pageYOffset;
                if ( travelled <= (endLocation || 0) ) {
                    clearInterval(runAnimation);
                }
            }
        }

        // Loop the animation function
        var runAnimation = setInterval(animateScroll, 16);

    }

    // Define smooth scroll links
    var scrollToggle = document.querySelectorAll('.scroll');

    // For each smooth scroll link
    [].forEach.call(scrollToggle, function (toggle) {

        // When the smooth scroll link is clicked
        toggle.addEventListener('click', function(e) {

            // Prevent the default link behavior
            e.preventDefault();

            // Get anchor link and calculate distance from the top
            var dataID = toggle.getAttribute('href');
            var dataTarget = document.querySelector(dataID);
            var dataSpeed = toggle.getAttribute('data-speed');

            // If the anchor exists
            if (dataTarget) {
                // Scroll to the anchor
                smoothScroll(dataTarget, dataSpeed || 500);
            }

        }, false);

    });

}
<commit_msg>Wrapped script in IIFE<commit_after>/* =============================================================

    Smooth Scroll 2.2
    Animate scrolling to anchor links, by Chris Ferdinandi.
    http://gomakethings.com

    Free to use under the MIT License.
    http://gomakethings.com/mit/

 * ============================================================= */

(function() {

    // Feature Test
    if ( 'querySelector' in document && 'addEventListener' in window && Array.prototype.forEach ) {

        // Function to animate the scroll
        var smoothScroll = function (anchor, duration) {

            // Calculate how far and how fast to scroll
            var startLocation = window.pageYOffset;
            var endLocation = anchor.offsetTop;
            var distance = endLocation - startLocation;
            var increments = distance/(duration/16);

            // Scroll the page by an increment, and check if it's time to stop
            var animateScroll = function () {
                window.scrollBy(0, increments);
                stopAnimation();
            }

            // If scrolling down
            if ( increments >= 0 ) {
                // Stop animation when you reach the anchor OR the bottom of the page
                var stopAnimation = function () {
                    var travelled = window.pageYOffset;
                    if ( (travelled >= (endLocation - increments)) || ((window.innerHeight + travelled) >= document.body.offsetHeight) ) {
                        clearInterval(runAnimation);
                    }
                }
            }
            // If scrolling up
            else {
                // Stop animation when you reach the anchor OR the top of the page
                var stopAnimation = function () {
                    var travelled = window.pageYOffset;
                    if ( travelled <= (endLocation || 0) ) {
                        clearInterval(runAnimation);
                    }
                }
            }

            // Loop the animation function
            var runAnimation = setInterval(animateScroll, 16);

        }

        // Define smooth scroll links
        var scrollToggle = document.querySelectorAll('.scroll');

        // For each smooth scroll link
        [].forEach.call(scrollToggle, function (toggle) {

            // When the smooth scroll link is clicked
            toggle.addEventListener('click', function(e) {

                // Prevent the default link behavior
                e.preventDefault();

                // Get anchor link and calculate distance from the top
                var dataID = toggle.getAttribute('href');
                var dataTarget = document.querySelector(dataID);
                var dataSpeed = toggle.getAttribute('data-speed');

                // If the anchor exists
                if (dataTarget) {
                    // Scroll to the anchor
                    smoothScroll(dataTarget, dataSpeed || 500);
                }

            }, false);

        });

    }

})();
<|endoftext|>


<commit_before>import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import ClockService from 'ember-clock/services/clock';

moduleForComponent('clock-face', 'Integration | Component | clock face', {
  integration: true,

  beforeEach() {
    this.register( 'service:clock', ClockService );
    this.inject.service( 'clock' );
  }
});

/*
  check it renders with the correct `tagName` and `classNames`
*/
test('it renders', function(assert) {
  assert.expect(3);

  // Set any properties with this.set('myProperty', 'value');
  // Handle any actions with this.on('myAction', function(val) { ... });
  // this.inject.service( 'clock' );
  this.render(hbs`{{clock-face size=clockSize}}`);

  assert.equal(this.$().text().trim(), '');

  // check the class names
  assert.ok(this.$('.ember-clock-face.clock-face').get(0));

  // check the tag name
  assert.equal(this.$('.ember-clock-face.clock-face').get(0).tagName, 'svg');
});

test('clock service exists and has correct time', function(assert) {
  assert.expect(4);

  this.render(hbs`{{clock-face}}`);

  assert.ok(this.clock);
  var date = new Date();
  var second = date.getSeconds();
  var minute = date.getMinutes();
  var hour = date.getHours();

  assert.equal(this.clock.get('second'), second, 'clock.second should be ' + second);
  assert.equal(this.clock.get('minute'), minute, 'clock.minute should be ' + minute);
  assert.equal(this.clock.get('hour'), hour, 'clock.hour should be ' + hour);
});

test('clock hands exist', function(assert) {
  assert.expect(3);

  this.render(hbs`{{clock-face}}`);

  assert.ok(this.$('.clock-hand.hour-hand').get(0));
  assert.ok(this.$('.clock-hand.minute-hand').get(0));
  assert.ok(this.$('.clock-hand.second-hand').get(0));
});

test('can set size', function(assert) {
  assert.expect(4);

  this.render(hbs`{{clock-face size=clockSize}}`);

  this.set( 'clockSize', 500 );

  assert.equal(this.$('.clock-face').attr('width'), '500', 'width should be 500' );
  assert.equal(this.$('.clock-face').attr('height'), '500', 'height should be 500' );

  this.set( 'clockSize', 100 );

  assert.equal(this.$('.clock-face').attr('width'), '100', 'width should be 100' );
  assert.equal(this.$('.clock-face').attr('height'), '100', 'height should be 100' );
});

test('has correct viewbox attr', function(assert) {
  assert.expect(4);

  this.render(hbs`{{clock-face}}`);
  var viewBox = this.$('.clock-face').get(0).viewBox;
  assert.equal(viewBox.baseVal.height, '100', 'viewBox height should be 100' );
  assert.equal(viewBox.baseVal.width, '100', 'viewBox width should be 100' );
  assert.equal(viewBox.baseVal.x, '0', 'viewBox x should be 0' );
  assert.equal(viewBox.baseVal.y, '0', 'viewBox y should be 0' );
});

test('hands rotate', function(assert) {
  assert.expect(3);

  this.render(hbs`{{clock-face clock=clock}}`);

  var date = new Date();
  var second = date.getSeconds();
  var minute = date.getMinutes();
  var hour = date.getHours();

  var rotateHour = 30 * ( hour % 12 ) + minute / 2;
  var rotateMinute = 6 * minute;
  var rotateSecond = 6 * second;

  assert.equal(this.$('.clock-hand.hour-hand').attr('transform'), `rotate(${rotateHour} 50 50)`, 'hour-hand should be rotated by ' + rotateHour );
  assert.equal(this.$('.clock-hand.minute-hand').attr('transform'), `rotate(${rotateMinute} 50 50)`, 'minute-hand should be rotated by ' + rotateMinute );
  assert.equal(this.$('.clock-hand.second-hand').attr('transform'), `rotate(${rotateSecond} 50 50)`, 'second-hand should be rotated by ' + rotateSecond );
});
<commit_msg>update clock-face test<commit_after>import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import ClockService from 'ember-clock/services/clock';

moduleForComponent('clock-face', 'Integration | Component | clock face', {
  integration: true,

  beforeEach() {
    this.register( 'service:clock', ClockService );
    this.inject.service( 'clock' );
  }
});

/*
  check it renders with the correct `tagName` and `classNames`
*/
test('it renders', function(assert) {
  assert.expect(3);

  // Set any properties with this.set('myProperty', 'value');
  // Handle any actions with this.on('myAction', function(val) { ... });
  // this.inject.service( 'clock' );
  this.render(hbs`{{clock-face size=clockSize}}`);

  assert.equal(this.$().text().trim(), '');

  // check the class names
  assert.ok(this.$('.ember-clock-face.clock-face').get(0));

  // check the tag name
  assert.equal(this.$('.ember-clock-face.clock-face').get(0).tagName, 'svg');
});

test('clock service exists and has correct time', function(assert) {
  assert.expect(4);

  this.render(hbs`{{clock-face}}`);

  assert.ok(this.clock);
  var date = new Date();
  var second = date.getSeconds();
  var minute = date.getMinutes();
  var hour = date.getHours();

  assert.equal(this.clock.get('second'), second, 'clock.second should be ' + second);
  assert.equal(this.clock.get('minute'), minute, 'clock.minute should be ' + minute);
  assert.equal(this.clock.get('hour'), hour, 'clock.hour should be ' + hour);
});

test('clock hands exist', function(assert) {
  assert.expect(3);

  this.render(hbs`{{clock-face}}`);

  assert.ok(this.$('.clock-hand.hour-hand').get(0));
  assert.ok(this.$('.clock-hand.minute-hand').get(0));
  assert.ok(this.$('.clock-hand.second-hand').get(0));
});

test('can set size', function(assert) {
  assert.expect(4);

  this.render(hbs`{{clock-face size=clockSize}}`);

  this.set( 'clockSize', 500 );

  assert.equal(this.$('.clock-face').attr('width'), '500', 'width should be 500' );
  assert.equal(this.$('.clock-face').attr('height'), '500', 'height should be 500' );

  this.set( 'clockSize', 100 );

  assert.equal(this.$('.clock-face').attr('width'), '100', 'width should be 100' );
  assert.equal(this.$('.clock-face').attr('height'), '100', 'height should be 100' );
});

test('has correct viewbox attr', function(assert) {
  assert.expect(4);

  this.render(hbs`{{clock-face}}`);
  var viewBox = this.$('.clock-face').get(0).viewBox;
  assert.equal(viewBox.baseVal.height, '100', 'viewBox height should be 100' );
  assert.equal(viewBox.baseVal.width, '100', 'viewBox width should be 100' );
  assert.equal(viewBox.baseVal.x, '0', 'viewBox x should be 0' );
  assert.equal(viewBox.baseVal.y, '0', 'viewBox y should be 0' );
});

// test('hands rotate', function(assert) {
//   assert.expect(3);
//
//   this.render(hbs`{{clock-face clock=clock}}`);
//
//   var date = new Date();
//   var second = date.getSeconds();
//   var minute = date.getMinutes();
//   var hour = date.getHours();
//
//   var rotateHour = 30 * ( hour % 12 ) + minute / 2;
//   var rotateMinute = 6 * minute;
//   var rotateSecond = 6 * second;
//
//   assert.equal(this.$('.clock-hand.hour-hand').attr('transform'), `rotate(${rotateHour} 50 50)`, 'hour-hand should be rotated by ' + rotateHour );
//   assert.equal(this.$('.clock-hand.minute-hand').attr('transform'), `rotate(${rotateMinute} 50 50)`, 'minute-hand should be rotated by ' + rotateMinute );
//   assert.equal(this.$('.clock-hand.second-hand').attr('transform'), `rotate(${rotateSecond} 50 50)`, 'second-hand should be rotated by ' + rotateSecond );
// });
<|endoftext|>


<commit_before>import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('wufoo-form', 'Integration | Component | wufoo form', {
  integration: true
});

test('it shows fallback link', function(assert) {
  // load form with fallback content isShowing,
  // all other functionality depends on successful loading of 3rd party library
  this.render(
    hbs`{{wufoo-form formId='AbCd1234' userName='myaccount' isShowingFallback=true}}`
  );

  assert.equal(
    this.$()
      .text()
      .trim(),
    'Fill out my online form.'
  );
  assert.ok(
    this.$()
      .find('a')
      .attr('href')
      .indexOf('AbCd1234') > -1
  );
});
<commit_msg>fixes outdated test<commit_after>import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('wufoo-form', 'Integration | Component | wufoo form', {
  integration: true
});

test('it shows fallback link', function(assert) {
  // load form with fallback content isShowing,
  // all other functionality depends on successful loading of 3rd party library
  this.render(
    hbs`{{wufoo-form formId='AbCd1234' userName='myaccount' isShowingFallback=true}}`
  );

  assert.equal(
    this.$()
      .text()
      .trim(),
    'Please fill out my online form.'
  );
  assert.ok(
    this.$()
      .find('a')
      .attr('href')
      .indexOf('AbCd1234') > -1
  );
});
<|endoftext|>


<commit_before>var CommentBox = React.createClass({
  render: function() {
    return (

Result Table: {this.props.id}

          id
          message
          type

        <CommentList />

    );
  }
});

var CommentList = React.createClass({
  render: function() {
    return (

        <CommentItemID />
        <CommentItemMessage />
        <CommentItemType />

    );
  }
});

var CommentItemID = React.createClass({
  render: function() {
    return (
      {this.props.id}
    );
  }
});

var CommentItemMessage = React.createClass({
  render: function() {
    return (
      {this.props.message}
    );
  }
});

var CommentItemType = React.createClass({
  render: function() {
    return (
      {this.props.type}
    );
  }
});

var Comment = React.createClass({
  render: function() {
    return (
      <CommentBox { ...data } />
    );
  }
});

window.ReactRender = function(_data) {

  console.log("==ReactRender==");

  // if(_data) {
    var data = {
      id: "test",
      message: "testtest"
    };
    ReactDOM.render( <Comment { ...data } />, document.getElementById('resulttable') );
  // }
};
<commit_msg>mark other<commit_after>var CommentBox = React.createClass({
  render: function() {
    return (

Result Table: {this.props.id}

          id
          message
          type

    );
  }
});

/*var CommentList = React.createClass({
  render: function() {
    return (

        <CommentItemID />
        <CommentItemMessage />
        <CommentItemType />

    );
  }
});

var CommentItemID = React.createClass({
  render: function() {
    return (
      {this.props.id}
    );
  }
});

var CommentItemMessage = React.createClass({
  render: function() {
    return (
      {this.props.message}
    );
  }
});

var CommentItemType = React.createClass({
  render: function() {
    return (
      {this.props.type}
    );
  }
});*/

var Comment = React.createClass({
  render: function() {
    return (
      <CommentBox { ...this.props.data } />
    );
  }
});

window.ReactRender = function(_data) {

  console.log("==ReactRender==");

  // if(_data) {
    var data = {
      id: "test",
      message: "testtest"
    };
    ReactDOM.render( <Comment { ...data } />, document.getElementById('resulttable') );
  // }
};
<|endoftext|>


<commit_before>'use strict';

import React from 'react';
import ReactDOM from './ReactDOM';
import ReactTransitionEvents from 'react/lib/ReactTransitionEvents';
import {getTrackCSS, getTrackLeft, getTrackAnimateCSS} from './trackHelper';
import assign from 'object-assign';

var helpers = {
  initialize: function (props) {
    var slideCount = React.Children.count(props.children);
    var listWidth = this.getWidth(ReactDOM.findDOMNode(this.refs.list));
    var trackWidth = this.getWidth(ReactDOM.findDOMNode(this.refs.track));
    var slideWidth = this.getWidth(ReactDOM.findDOMNode(this))/props.slidesToShow;

    var currentSlide = props.rtl ? slideCount - 1 - props.initialSlide : props.initialSlide;

    this.setState({
      slideCount: slideCount,
      slideWidth: slideWidth,
      listWidth: listWidth,
      trackWidth: trackWidth,
      currentSlide: currentSlide
    }, function () {

      var targetLeft = getTrackLeft(assign({
        slideIndex: this.state.currentSlide,
        trackRef: this.refs.track
      }, props, this.state));
      // getCSS function needs previously set state
      var trackStyle = getTrackCSS(assign({left: targetLeft}, props, this.state));

      this.setState({trackStyle: trackStyle});

      this.autoPlay(); // once we're set up, trigger the initial autoplay.
    });
  },
  update: function (props) {
    // This method has mostly same code as initialize method.
    // Refactor it
    var slideCount = React.Children.count(props.children);
    var listWidth = this.getWidth(ReactDOM.findDOMNode(this.refs.list));
    var trackWidth = this.getWidth(ReactDOM.findDOMNode(this.refs.track));
    var slideWidth = this.getWidth(ReactDOM.findDOMNode(this))/props.slidesToShow;

    this.setState({
      slideCount: slideCount,
      slideWidth: slideWidth,
      listWidth: listWidth,
      trackWidth: trackWidth
    }, function () {

      var targetLeft = getTrackLeft(assign({
        slideIndex: this.state.currentSlide,
        trackRef: this.refs.track
      }, props, this.state));
      // getCSS function needs previously set state
      var trackStyle = getTrackCSS(assign({left: targetLeft}, props, this.state));

      this.setState({trackStyle: trackStyle});
    });
  },
  getWidth: function getWidth(elem) {
    return elem.getBoundingClientRect().width || elem.offsetWidth;
  },
  adaptHeight: function () {
    if (this.props.adaptiveHeight) {
      var selector = '[data-index="' + this.state.currentSlide +'"]';
      if (this.refs.list) {
        var slickList = ReactDOM.findDOMNode(this.refs.list);
        slickList.style.height = slickList.querySelector(selector).offsetHeight + 'px';
      }
    }
  },
  slideHandler: function (index) {
    // Functionality of animateSlide and postSlide is merged into this function
    // console.log('slideHandler', index);
    var targetSlide, currentSlide;
    var targetLeft, currentLeft;
    var callback;

    if (this.props.waitForAnimate && this.state.animating) {
	return;
    }

    if (this.state.currentSlide === index) {
      return;
    }

    if (this.props.fade) {
      currentSlide = this.state.currentSlide;

      //  Shifting targetSlide back into the range
      if (index < 0) {
        targetSlide = index + this.state.slideCount;
      } else if (index >= this.state.slideCount) {
        targetSlide = index - this.state.slideCount;
      } else {
        targetSlide = index;
      }

      if (this.props.lazyLoad && this.state.lazyLoadedList.indexOf(targetSlide) < 0) {
        this.setState({
          lazyLoadedList: this.state.lazyLoadedList.concat(targetSlide)
        });
      }

      callback = () => {
        this.setState({
          animating: false
        });
        if (this.props.afterChange) {
          this.props.afterChange(currentSlide);
        }
        ReactTransitionEvents.removeEndEventListener(ReactDOM.findDOMNode(this.refs.track).children[currentSlide], callback);
      };

      this.setState({
        animating: true,
        currentSlide: targetSlide
      }, function () {
        ReactTransitionEvents.addEndEventListener(ReactDOM.findDOMNode(this.refs.track).children[currentSlide], callback);
      });

      if (this.props.beforeChange) {
        this.props.beforeChange(this.state.currentSlide, currentSlide);
      }

      this.autoPlay();
      return;
    }

    targetSlide = index;
    if (targetSlide < 0) {
      if(this.props.infinite === false) {
        currentSlide = 0;
      } else if (this.state.slideCount % this.props.slidesToScroll !== 0) {
        currentSlide = this.state.slideCount - (this.state.slideCount % this.props.slidesToScroll);
      } else {
        currentSlide = this.state.slideCount + targetSlide;
      }
    } else if (targetSlide >= this.state.slideCount) {
      if(this.props.infinite === false) {
        currentSlide = this.state.slideCount - this.props.slidesToShow;
      } else if (this.state.slideCount % this.props.slidesToScroll !== 0) {
        currentSlide = 0;
      } else {
        currentSlide = targetSlide - this.state.slideCount;
      }
    } else {
      currentSlide = targetSlide;
    }

    targetLeft = getTrackLeft(assign({
      slideIndex: targetSlide,
      trackRef: this.refs.track
    }, this.props, this.state));

    currentLeft = getTrackLeft(assign({
      slideIndex: currentSlide,
      trackRef: this.refs.track
    }, this.props, this.state));

    if (this.props.infinite === false) {
      targetLeft = currentLeft;
    }

    if (this.props.beforeChange) {
      this.props.beforeChange(this.state.currentSlide, currentSlide);
    }

    if (this.props.lazyLoad) {
      var loaded = true;
      var slidesToLoad = [];
      for (var i = targetSlide; i < targetSlide + this.props.slidesToShow; i++ ) {
        loaded = loaded && (this.state.lazyLoadedList.indexOf(i) >= 0);
        if (!loaded) {
          slidesToLoad.push(i);
        }
      }
      if (!loaded) {
        this.setState({
          lazyLoadedList: this.state.lazyLoadedList.concat(slidesToLoad)
        });
      }
    }

    // Slide Transition happens here.
    // animated transition happens to target Slide and
    // non - animated transition happens to current Slide
    // If CSS transitions are false, directly go the current slide.

    if (this.props.useCSS === false) {

      this.setState({
        currentSlide: currentSlide,
        trackStyle: getTrackCSS(assign({left: currentLeft}, this.props, this.state))
      }, function () {
        if (this.props.afterChange) {
          this.props.afterChange(currentSlide);
        }
      });

    } else {

      var nextStateChanges = {
        animating: false,
        currentSlide: currentSlide,
        trackStyle: getTrackCSS(assign({left: currentLeft}, this.props, this.state)),
        swipeLeft: null
      };

      callback = () => {
        this.setState(nextStateChanges);
        if (this.props.afterChange) {
          this.props.afterChange(currentSlide);
        }
        ReactTransitionEvents.removeEndEventListener(ReactDOM.findDOMNode(this.refs.track), callback);
      };

      this.setState({
        animating: true,
        currentSlide: currentSlide,
        trackStyle: getTrackAnimateCSS(assign({left: targetLeft}, this.props, this.state))
      }, function () {
        ReactTransitionEvents.addEndEventListener(ReactDOM.findDOMNode(this.refs.track), callback);
      });

    }

    if (!this.state.autoPlayTimer) {
      this.autoPlay();
    }

  },
  swipeDirection: function (touchObject) {
    var xDist, yDist, r, swipeAngle;

    xDist = touchObject.startX - touchObject.curX;
    yDist = touchObject.startY - touchObject.curY;
    r = Math.atan2(yDist, xDist);

    swipeAngle = Math.round(r * 180 / Math.PI);
    if (swipeAngle < 0) {
        swipeAngle = 360 - Math.abs(swipeAngle);
    }
    if ((swipeAngle <= 45) && (swipeAngle >= 0) || (swipeAngle <= 360) && (swipeAngle >= 315)) {
        return (this.props.rtl === false ? 'left' : 'right');
    }
    if ((swipeAngle >= 135) && (swipeAngle <= 225)) {
        return (this.props.rtl === false ? 'right' : 'left');
    }

    return 'vertical';
  },
  autoPlay: function () {
    var play = () => {
      if (this.state.mounted) {
        var nextIndex = this.props.rtl ?
        this.state.currentSlide - this.props.slidesToScroll:
        this.state.currentSlide + this.props.slidesToScroll;
        this.slideHandler(nextIndex);
      }
    };
    if (this.props.autoplay) {
      this.setState({
        autoPlayTimer: window.setInterval(play, this.props.autoplaySpeed)
      });
    }
  },
  pause: function () {
    if (this.state.autoPlayTimer) {
      window.clearInterval(this.state.autoPlayTimer);
    }
  }
};

export default helpers;
<commit_msg>Fixed #162<commit_after>'use strict';

import React from 'react';
import ReactDOM from './ReactDOM';
import ReactTransitionEvents from 'react/lib/ReactTransitionEvents';
import {getTrackCSS, getTrackLeft, getTrackAnimateCSS} from './trackHelper';
import assign from 'object-assign';

var helpers = {
  initialize: function (props) {
    var slideCount = React.Children.count(props.children);
    var listWidth = this.getWidth(ReactDOM.findDOMNode(this.refs.list));
    var trackWidth = this.getWidth(ReactDOM.findDOMNode(this.refs.track));
    var slideWidth = this.getWidth(ReactDOM.findDOMNode(this))/props.slidesToShow;

    var currentSlide = props.rtl ? slideCount - 1 - props.initialSlide : props.initialSlide;

    this.setState({
      slideCount: slideCount,
      slideWidth: slideWidth,
      listWidth: listWidth,
      trackWidth: trackWidth,
      currentSlide: currentSlide
    }, function () {

      var targetLeft = getTrackLeft(assign({
        slideIndex: this.state.currentSlide,
        trackRef: this.refs.track
      }, props, this.state));
      // getCSS function needs previously set state
      var trackStyle = getTrackCSS(assign({left: targetLeft}, props, this.state));

      this.setState({trackStyle: trackStyle});

      this.autoPlay(); // once we're set up, trigger the initial autoplay.
    });
  },
  update: function (props) {
    // This method has mostly same code as initialize method.
    // Refactor it
    var slideCount = React.Children.count(props.children);
    var listWidth = this.getWidth(ReactDOM.findDOMNode(this.refs.list));
    var trackWidth = this.getWidth(ReactDOM.findDOMNode(this.refs.track));
    var slideWidth = this.getWidth(ReactDOM.findDOMNode(this))/props.slidesToShow;

    this.setState({
      slideCount: slideCount,
      slideWidth: slideWidth,
      listWidth: listWidth,
      trackWidth: trackWidth
    }, function () {

      var targetLeft = getTrackLeft(assign({
        slideIndex: this.state.currentSlide,
        trackRef: this.refs.track
      }, props, this.state));
      // getCSS function needs previously set state
      var trackStyle = getTrackCSS(assign({left: targetLeft}, props, this.state));

      this.setState({trackStyle: trackStyle});
    });
  },
  getWidth: function getWidth(elem) {
    return elem.getBoundingClientRect().width || elem.offsetWidth;
  },
  adaptHeight: function () {
    if (this.props.adaptiveHeight) {
      var selector = '[data-index="' + this.state.currentSlide +'"]';
      if (this.refs.list) {
        var slickList = ReactDOM.findDOMNode(this.refs.list);
        slickList.style.height = slickList.querySelector(selector).offsetHeight + 'px';
      }
    }
  },
  slideHandler: function (index) {
    // Functionality of animateSlide and postSlide is merged into this function
    // console.log('slideHandler', index);
    var targetSlide, currentSlide;
    var targetLeft, currentLeft;
    var callback;

    if (this.props.waitForAnimate && this.state.animating) {
      return;
    }

    if (this.props.fade) {
      currentSlide = this.state.currentSlide;

      //  Shifting targetSlide back into the range
      if (index < 0) {
        targetSlide = index + this.state.slideCount;
      } else if (index >= this.state.slideCount) {
        targetSlide = index - this.state.slideCount;
      } else {
        targetSlide = index;
      }

      if (this.props.lazyLoad && this.state.lazyLoadedList.indexOf(targetSlide) < 0) {
        this.setState({
          lazyLoadedList: this.state.lazyLoadedList.concat(targetSlide)
        });
      }

      callback = () => {
        this.setState({
          animating: false
        });
        if (this.props.afterChange) {
          this.props.afterChange(currentSlide);
        }
        ReactTransitionEvents.removeEndEventListener(ReactDOM.findDOMNode(this.refs.track).children[currentSlide], callback);
      };

      this.setState({
        animating: true,
        currentSlide: targetSlide
      }, function () {
        ReactTransitionEvents.addEndEventListener(ReactDOM.findDOMNode(this.refs.track).children[currentSlide], callback);
      });

      if (this.props.beforeChange) {
        this.props.beforeChange(this.state.currentSlide, currentSlide);
      }

      this.autoPlay();
      return;
    }

    targetSlide = index;
    if (targetSlide < 0) {
      if(this.props.infinite === false) {
        currentSlide = 0;
      } else if (this.state.slideCount % this.props.slidesToScroll !== 0) {
        currentSlide = this.state.slideCount - (this.state.slideCount % this.props.slidesToScroll);
      } else {
        currentSlide = this.state.slideCount + targetSlide;
      }
    } else if (targetSlide >= this.state.slideCount) {
      if(this.props.infinite === false) {
        currentSlide = this.state.slideCount - this.props.slidesToShow;
      } else if (this.state.slideCount % this.props.slidesToScroll !== 0) {
        currentSlide = 0;
      } else {
        currentSlide = targetSlide - this.state.slideCount;
      }
    } else {
      currentSlide = targetSlide;
    }

    targetLeft = getTrackLeft(assign({
      slideIndex: targetSlide,
      trackRef: this.refs.track
    }, this.props, this.state));

    currentLeft = getTrackLeft(assign({
      slideIndex: currentSlide,
      trackRef: this.refs.track
    }, this.props, this.state));

    if (this.props.infinite === false) {
      targetLeft = currentLeft;
    }

    if (this.props.beforeChange) {
      this.props.beforeChange(this.state.currentSlide, currentSlide);
    }

    if (this.props.lazyLoad) {
      var loaded = true;
      var slidesToLoad = [];
      for (var i = targetSlide; i < targetSlide + this.props.slidesToShow; i++ ) {
        loaded = loaded && (this.state.lazyLoadedList.indexOf(i) >= 0);
        if (!loaded) {
          slidesToLoad.push(i);
        }
      }
      if (!loaded) {
        this.setState({
          lazyLoadedList: this.state.lazyLoadedList.concat(slidesToLoad)
        });
      }
    }

    // Slide Transition happens here.
    // animated transition happens to target Slide and
    // non - animated transition happens to current Slide
    // If CSS transitions are false, directly go the current slide.

    if (this.props.useCSS === false) {

      this.setState({
        currentSlide: currentSlide,
        trackStyle: getTrackCSS(assign({left: currentLeft}, this.props, this.state))
      }, function () {
        if (this.props.afterChange) {
          this.props.afterChange(currentSlide);
        }
      });

    } else {

      var nextStateChanges = {
        animating: false,
        currentSlide: currentSlide,
        trackStyle: getTrackCSS(assign({left: currentLeft}, this.props, this.state)),
        swipeLeft: null
      };

      callback = () => {
        this.setState(nextStateChanges);
        if (this.props.afterChange) {
          this.props.afterChange(currentSlide);
        }
        ReactTransitionEvents.removeEndEventListener(ReactDOM.findDOMNode(this.refs.track), callback);
      };

      this.setState({
        animating: true,
        currentSlide: currentSlide,
        trackStyle: getTrackAnimateCSS(assign({left: targetLeft}, this.props, this.state))
      }, function () {
        ReactTransitionEvents.addEndEventListener(ReactDOM.findDOMNode(this.refs.track), callback);
      });

    }

    if (!this.state.autoPlayTimer) {
      this.autoPlay();
    }

  },
  swipeDirection: function (touchObject) {
    var xDist, yDist, r, swipeAngle;

    xDist = touchObject.startX - touchObject.curX;
    yDist = touchObject.startY - touchObject.curY;
    r = Math.atan2(yDist, xDist);

    swipeAngle = Math.round(r * 180 / Math.PI);
    if (swipeAngle < 0) {
        swipeAngle = 360 - Math.abs(swipeAngle);
    }
    if ((swipeAngle <= 45) && (swipeAngle >= 0) || (swipeAngle <= 360) && (swipeAngle >= 315)) {
        return (this.props.rtl === false ? 'left' : 'right');
    }
    if ((swipeAngle >= 135) && (swipeAngle <= 225)) {
        return (this.props.rtl === false ? 'right' : 'left');
    }

    return 'vertical';
  },
  autoPlay: function () {
    var play = () => {
      if (this.state.mounted) {
        var nextIndex = this.props.rtl ?
        this.state.currentSlide - this.props.slidesToScroll:
        this.state.currentSlide + this.props.slidesToScroll;
        this.slideHandler(nextIndex);
      }
    };
    if (this.props.autoplay) {
      this.setState({
        autoPlayTimer: window.setInterval(play, this.props.autoplaySpeed)
      });
    }
  },
  pause: function () {
    if (this.state.autoPlayTimer) {
      window.clearInterval(this.state.autoPlayTimer);
    }
  }
};

export default helpers;
<|endoftext|>


<commit_before>'use strict';

import React from 'react';
import ReactDOM from 'react-dom';
import {getTrackCSS, getTrackLeft, getTrackAnimateCSS} from './trackHelper';
import assign from 'object-assign';

var helpers = {
  // supposed to start autoplay of slides
  initialize: function (props) {
    const slickList = ReactDOM.findDOMNode(this.list);

    var slideCount = React.Children.count(props.children);
    var listWidth = this.getWidth(slickList);
    var trackWidth = this.getWidth(ReactDOM.findDOMNode(this.track));
    var slideWidth;

    if (!props.vertical) {
      var centerPaddingAdj = props.centerMode && (parseInt(props.centerPadding) * 2);
      if (props.centerPadding.slice(-1) === '%') {
        centerPaddingAdj *= listWidth / 100
      }
      slideWidth = Math.ceil((this.getWidth(ReactDOM.findDOMNode(this)) - centerPaddingAdj)/props.slidesToShow)
    } else {
      slideWidth = Math.ceil(this.getWidth(ReactDOM.findDOMNode(this)))
    }

    const slideHeight = this.getHeight(slickList.querySelector('[data-index="0"]'));
    const listHeight = slideHeight * props.slidesToShow;

    var currentSlide = props.rtl ? slideCount - 1 - props.initialSlide : props.initialSlide;

    this.setState({
      slideCount,
      slideWidth,
      listWidth,
      trackWidth,
      currentSlide,
      slideHeight,
      listHeight,
    }, function () {
      // this reference isn't lost due to mixin
      var targetLeft = getTrackLeft(assign({
        slideIndex: this.state.currentSlide,
        trackRef: this.track
      }, props, this.state));
      // getCSS function needs previously set state
      var trackStyle = getTrackCSS(assign({left: targetLeft}, props, this.state));

      this.setState({trackStyle: trackStyle});

      this.autoPlay(); // once we're set up, trigger the initial autoplay.
    });
  },
  update: function (props) {
    const slickList = ReactDOM.findDOMNode(this.list);
    // This method has mostly same code as initialize method.
    // Refactor it
    var slideCount = React.Children.count(props.children);
    var listWidth = this.getWidth(slickList);
    var trackWidth = this.getWidth(ReactDOM.findDOMNode(this.track));
    var slideWidth;

    if (!props.vertical) {
      var centerPaddingAdj = props.centerMode && (parseInt(props.centerPadding) * 2);
      if (props.centerPadding.slice(-1) === '%') {
        centerPaddingAdj *= listWidth / 100
      }
      slideWidth = Math.ceil((this.getWidth(ReactDOM.findDOMNode(this)) - centerPaddingAdj)/props.slidesToShow)
    } else {
      slideWidth = Math.ceil(this.getWidth(ReactDOM.findDOMNode(this)))
    }

    const slideHeight = this.getHeight(slickList.querySelector('[data-index="0"]'));
    const listHeight = slideHeight * props.slidesToShow;

    // pause slider if autoplay is set to false
    if(!props.autoplay) {
      this.pause();
    } else {
      this.autoPlay(props.autoplay);
    }

    this.setState({
      slideCount,
      slideWidth,
      listWidth,
      trackWidth,
      slideHeight,
      listHeight,
    }, function () {

      var targetLeft = getTrackLeft(assign({
        slideIndex: this.state.currentSlide,
        trackRef: this.track
      }, props, this.state));
      // getCSS function needs previously set state
      var trackStyle = getTrackCSS(assign({left: targetLeft}, props, this.state));

      this.setState({trackStyle: trackStyle});
    });
  },
  getWidth: function getWidth(elem) {
    return elem && (elem.getBoundingClientRect().width || elem.offsetWidth) || 0;
  },
  getHeight(elem) {
    return elem && (elem.getBoundingClientRect().height || elem.offsetHeight) || 0;
  },
  adaptHeight: function () {
    if (this.props.adaptiveHeight) {
      var selector = '[data-index="' + this.state.currentSlide +'"]';
      if (this.list) {
        var slickList = ReactDOM.findDOMNode(this.list);
        var elem = slickList.querySelector(selector) || {};
        slickList.style.height = (elem.offsetHeight || 0) + 'px';
      }
    }
  },
  canGoNext: function (opts){
    var canGo = true;
    if (!opts.infinite) {
      if (opts.centerMode) {
        // check if current slide is last slide
        if (opts.currentSlide >= (opts.slideCount - 1)) {
          canGo = false;
        }
      } else {
        // check if all slides are shown in slider
        if (opts.slideCount <= opts.slidesToShow ||
          opts.currentSlide >= (opts.slideCount - opts.slidesToShow)) {
          canGo = false;
        }
      }
    }
    return canGo;
  },
  slideHandler: function (index) {
    // index is target slide index

    // Functionality of animateSlide and postSlide is merged into this function
    var animationTargetSlide, finalTargetSlide;
    var animationTargetLeft, finalTargetLeft;
    var callback;

    if (this.props.waitForAnimate && this.state.animating) {
      return;
    }

    if (this.props.fade) {
      finalTargetSlide = this.state.currentSlide;

      // Don't change slide if infinite=false and target slide is out of range
      if(this.props.infinite === false &&
        (index < 0 || index >= this.state.slideCount)) {
        return;
      }

      //  Shifting animationTargetSlide back into the range
      if (index < 0) {
        animationTargetSlide = index + this.state.slideCount;
      } else if (index >= this.state.slideCount) {
        animationTargetSlide = index - this.state.slideCount;
      } else {
        animationTargetSlide = index;
      }

      if (this.props.lazyLoad && this.state.lazyLoadedList.indexOf(animationTargetSlide) < 0) {
        this.setState({
          lazyLoadedList: this.state.lazyLoadedList.concat(animationTargetSlide)
        });
      }

      callback = () => {
        this.setState({
          animating: false
        });
        if (this.props.afterChange) {
          this.props.afterChange(animationTargetSlide);
        }
        delete this.animationEndCallback;
      };

      this.setState({
        animating: true,
        currentSlide: animationTargetSlide
      }, function () {
        this.animationEndCallback = setTimeout(callback, this.props.speed);
      });

      if (this.props.beforeChange) {
        this.props.beforeChange(this.state.currentSlide, animationTargetSlide);
      }

      this.autoPlay();
      return;
    }

    animationTargetSlide = index;

    /*
      @TODO: Make sure to leave no bug in the code below
      start: critical checkpoint
    */
    if (animationTargetSlide < 0) {
      if(this.props.infinite === false) {
        finalTargetSlide = 0;
      } else if (this.state.slideCount % this.props.slidesToScroll !== 0) {
        finalTargetSlide = this.state.slideCount - (this.state.slideCount % this.props.slidesToScroll);
      } else {
        finalTargetSlide = this.state.slideCount + animationTargetSlide;
      }
    } else if (this.props.centerMode && animationTargetSlide >= this.state.slideCount) {
      if(this.props.infinite === false) {
        animationTargetSlide = this.state.slideCount - 1
        finalTargetSlide = this.state.slideCount - 1
      } else {
        animationTargetSlide = this.state.slideCount
        finalTargetSlide = 0
      }
    } else if (animationTargetSlide >= this.state.slideCount) {
      if(this.props.infinite === false) {
        finalTargetSlide = this.state.slideCount - this.props.slidesToShow;
      } else if (this.state.slideCount % this.props.slidesToScroll !== 0) {
        finalTargetSlide = 0;
      } else {
        finalTargetSlide = animationTargetSlide - this.state.slideCount;
      }
    } else if (this.state.currentSlide + this.slidesToShow < this.state.slideCount && animationTargetSlide + this.props.slidesToShow >= this.state.slideCount) {
      if (this.props.infinite === false) {
        finalTargetSlide = this.state.slideCount - this.props.slidesToShow
      } else {
        if ((this.state.slideCount - animationTargetSlide) % this.props.slidesToScroll !== 0) {
          finalTargetSlide = this.state.slideCount - this.props.slidesToShow
        } else {
          finalTargetSlide = animationTargetSlide
        }
      }
    } else {
      finalTargetSlide = animationTargetSlide;
    }

    /*
      stop: critical checkpoint
    */

    animationTargetLeft = getTrackLeft(assign({
      slideIndex: animationTargetSlide,
      trackRef: this.track
    }, this.props, this.state));

    finalTargetLeft = getTrackLeft(assign({
      slideIndex: finalTargetSlide,
      trackRef: this.track
    }, this.props, this.state));

    if (this.props.infinite === false) {
      if (animationTargetLeft === finalTargetLeft) {
        animationTargetSlide = finalTargetSlide;
      }
      animationTargetLeft = finalTargetLeft;
    }

    if (this.props.beforeChange) {
      this.props.beforeChange(this.state.currentSlide, finalTargetSlide);
    }

    if (this.props.lazyLoad) {
      var slidesToLoad = [];
      let slideCount = this.state.slideCount
      for (var i = animationTargetSlide; i < animationTargetSlide + this.props.slidesToShow; i++ ) {
        if (this.state.lazyLoadedList.indexOf(i) < 0) {
          slidesToLoad.push(i)
        }
        if (i >= slideCount && this.state.lazyLoadedList.indexOf(i - slideCount) < 0) {
          slidesToLoad.push(i - slideCount)
        }
        if (i < 0 && this.state.lazyLoadedList.indexOf(i + slideCount) < 0) {
          slidesToLoad.push(i + slideCount)
        }
      }
      if (slidesToLoad.length > 0) {
        this.setState({
          lazyLoadedList: this.state.lazyLoadedList.concat(slidesToLoad)
        });
      }
    }

    // Slide Transition happens here.
    // animated transition happens to target Slide and
    // non - animated transition happens to current Slide
    // If CSS transitions are false, directly go the current slide.

    if (this.props.useCSS === false) {
      this.setState({
        currentSlide: finalTargetSlide,
        trackStyle: getTrackCSS(assign({left: finalTargetLeft}, this.props, this.state))
      }, function () {
        if (this.props.afterChange) {
          this.props.afterChange(finalTargetSlide);
        }
      });

    } else {

      var nextStateChanges = {
        animating: false,
        currentSlide: finalTargetSlide,
        trackStyle: getTrackCSS(assign({left: finalTargetLeft}, this.props, this.state)),
        swipeLeft: null
      };
      callback = () => {
        this.setState(nextStateChanges, () => {
          if (this.props.afterChange) {
            this.props.afterChange(finalTargetSlide);
          }
          delete this.animationEndCallback;
        });
      };

      this.setState({
        animating: true,
        currentSlide: finalTargetSlide,
        trackStyle: getTrackAnimateCSS(assign({left: animationTargetLeft}, this.props, this.state))
      }, function () {
        this.animationEndCallback = setTimeout(callback, this.props.speed);
      });

    }

    this.autoPlay();
  },
  swipeDirection: function (touchObject) {
    var xDist, yDist, r, swipeAngle;

    xDist = touchObject.startX - touchObject.curX;
    yDist = touchObject.startY - touchObject.curY;
    r = Math.atan2(yDist, xDist);

    swipeAngle = Math.round(r * 180 / Math.PI);
    if (swipeAngle < 0) {
        swipeAngle = 360 - Math.abs(swipeAngle);
    }
    if ((swipeAngle <= 45) && (swipeAngle >= 0) || (swipeAngle <= 360) && (swipeAngle >= 315)) {
        return 'left';
    }
    if ((swipeAngle >= 135) && (swipeAngle <= 225)) {
        return 'right';
    }
    if (this.props.verticalSwiping === true) {
      if ((swipeAngle >= 35) && (swipeAngle <= 135)) {
        return 'down';
      } else {
        return 'up';
      }
    }

    return 'vertical';
  },
  play: function(){
    var nextIndex;

    // if (!this.state.mounted) {
    //   return false
    // }

    if (this.props.rtl) {
      nextIndex = this.state.currentSlide - this.props.slidesToScroll;
    } else {
      if (this.canGoNext(Object.assign({}, this.props,this.state))) {
        nextIndex = this.state.currentSlide + this.props.slidesToScroll;
      } else {
        return false;
      }
    }

    this.slideHandler(nextIndex);
  },
  autoPlay: function (autoplay=false) {
    if (this.state.autoPlayTimer) {
      clearTimeout(this.state.autoPlayTimer);
    }
    if (autoplay || this.props.autoplay) {
      this.setState({
        autoPlayTimer: setTimeout(this.play, this.props.autoplaySpeed)
      });
    }
  },
  pause: function () {
    if (this.state.autoPlayTimer) {
      clearTimeout(this.state.autoPlayTimer);
      this.setState({
        autoPlayTimer: null
      });
    }
  }
};

export default helpers;
<commit_msg>handling lost focus in case of fade<commit_after>'use strict';

import React from 'react';
import ReactDOM from 'react-dom';
import {getTrackCSS, getTrackLeft, getTrackAnimateCSS} from './trackHelper';
import assign from 'object-assign';

var helpers = {
  // supposed to start autoplay of slides
  initialize: function (props) {
    const slickList = ReactDOM.findDOMNode(this.list);

    var slideCount = React.Children.count(props.children);
    var listWidth = this.getWidth(slickList);
    var trackWidth = this.getWidth(ReactDOM.findDOMNode(this.track));
    var slideWidth;

    if (!props.vertical) {
      var centerPaddingAdj = props.centerMode && (parseInt(props.centerPadding) * 2);
      if (props.centerPadding.slice(-1) === '%') {
        centerPaddingAdj *= listWidth / 100
      }
      slideWidth = Math.ceil((this.getWidth(ReactDOM.findDOMNode(this)) - centerPaddingAdj)/props.slidesToShow)
    } else {
      slideWidth = Math.ceil(this.getWidth(ReactDOM.findDOMNode(this)))
    }

    const slideHeight = this.getHeight(slickList.querySelector('[data-index="0"]'));
    const listHeight = slideHeight * props.slidesToShow;

    var currentSlide = props.rtl ? slideCount - 1 - props.initialSlide : props.initialSlide;

    this.setState({
      slideCount,
      slideWidth,
      listWidth,
      trackWidth,
      currentSlide,
      slideHeight,
      listHeight,
    }, function () {
      // this reference isn't lost due to mixin
      var targetLeft = getTrackLeft(assign({
        slideIndex: this.state.currentSlide,
        trackRef: this.track
      }, props, this.state));
      // getCSS function needs previously set state
      var trackStyle = getTrackCSS(assign({left: targetLeft}, props, this.state));

      this.setState({trackStyle: trackStyle});

      this.autoPlay(); // once we're set up, trigger the initial autoplay.
    });
  },
  update: function (props) {
    const slickList = ReactDOM.findDOMNode(this.list);
    // This method has mostly same code as initialize method.
    // Refactor it
    var slideCount = React.Children.count(props.children);
    var listWidth = this.getWidth(slickList);
    var trackWidth = this.getWidth(ReactDOM.findDOMNode(this.track));
    var slideWidth;

    if (!props.vertical) {
      var centerPaddingAdj = props.centerMode && (parseInt(props.centerPadding) * 2);
      if (props.centerPadding.slice(-1) === '%') {
        centerPaddingAdj *= listWidth / 100
      }
      slideWidth = Math.ceil((this.getWidth(ReactDOM.findDOMNode(this)) - centerPaddingAdj)/props.slidesToShow)
    } else {
      slideWidth = Math.ceil(this.getWidth(ReactDOM.findDOMNode(this)))
    }

    const slideHeight = this.getHeight(slickList.querySelector('[data-index="0"]'));
    const listHeight = slideHeight * props.slidesToShow;

    // pause slider if autoplay is set to false
    if(!props.autoplay) {
      this.pause();
    } else {
      this.autoPlay(props.autoplay);
    }

    this.setState({
      slideCount,
      slideWidth,
      listWidth,
      trackWidth,
      slideHeight,
      listHeight,
    }, function () {

      var targetLeft = getTrackLeft(assign({
        slideIndex: this.state.currentSlide,
        trackRef: this.track
      }, props, this.state));
      // getCSS function needs previously set state
      var trackStyle = getTrackCSS(assign({left: targetLeft}, props, this.state));

      this.setState({trackStyle: trackStyle});
    });
  },
  getWidth: function getWidth(elem) {
    return elem && (elem.getBoundingClientRect().width || elem.offsetWidth) || 0;
  },
  getHeight(elem) {
    return elem && (elem.getBoundingClientRect().height || elem.offsetHeight) || 0;
  },
  adaptHeight: function () {
    if (this.props.adaptiveHeight) {
      var selector = '[data-index="' + this.state.currentSlide +'"]';
      if (this.list) {
        var slickList = ReactDOM.findDOMNode(this.list);
        var elem = slickList.querySelector(selector) || {};
        slickList.style.height = (elem.offsetHeight || 0) + 'px';
      }
    }
  },
  canGoNext: function (opts){
    var canGo = true;
    if (!opts.infinite) {
      if (opts.centerMode) {
        // check if current slide is last slide
        if (opts.currentSlide >= (opts.slideCount - 1)) {
          canGo = false;
        }
      } else {
        // check if all slides are shown in slider
        if (opts.slideCount <= opts.slidesToShow ||
          opts.currentSlide >= (opts.slideCount - opts.slidesToShow)) {
          canGo = false;
        }
      }
    }
    return canGo;
  },
  slideHandler: function (index) {
    // index is target slide index

    // Functionality of animateSlide and postSlide is merged into this function
    var animationTargetSlide, finalTargetSlide;
    var animationTargetLeft, finalTargetLeft;
    var callback;

    if (this.props.waitForAnimate && this.state.animating) {
      return;
    }

    if (this.props.fade) {
      finalTargetSlide = this.state.currentSlide;

      // Don't change slide if infinite=false and target slide is out of range
      if(this.props.infinite === false &&
        (index < 0 || index >= this.state.slideCount)) {
        return;
      }

      //  Shifting animationTargetSlide back into the range
      if (index < 0) {
        animationTargetSlide = index + this.state.slideCount;
      } else if (index >= this.state.slideCount) {
        animationTargetSlide = index - this.state.slideCount;
      } else {
        animationTargetSlide = index;
      }

      if (this.props.lazyLoad && this.state.lazyLoadedList.indexOf(animationTargetSlide) < 0) {
        this.setState({
          lazyLoadedList: this.state.lazyLoadedList.concat(animationTargetSlide)
        });
      }

      callback = () => {
        this.setState({
          animating: false
        });
        if (this.props.afterChange) {
          this.props.afterChange(animationTargetSlide);
        }
        delete this.animationEndCallback;
        if (this.props.fade) {
          const focusableSlide = ReactDOM.findDOMNode(this.track).children[animationTargetSlide]
          focusableSlide.focus()
        }
      };

      this.setState({
        animating: true,
        currentSlide: animationTargetSlide
      }, function () {
        this.animationEndCallback = setTimeout(callback, this.props.speed);
      });

      if (this.props.beforeChange) {
        this.props.beforeChange(this.state.currentSlide, animationTargetSlide);
      }

      this.autoPlay();
      return;
    }

    animationTargetSlide = index;

    /*
      @TODO: Make sure to leave no bug in the code below
      start: critical checkpoint
    */
    if (animationTargetSlide < 0) {
      if(this.props.infinite === false) {
        finalTargetSlide = 0;
      } else if (this.state.slideCount % this.props.slidesToScroll !== 0) {
        finalTargetSlide = this.state.slideCount - (this.state.slideCount % this.props.slidesToScroll);
      } else {
        finalTargetSlide = this.state.slideCount + animationTargetSlide;
      }
    } else if (this.props.centerMode && animationTargetSlide >= this.state.slideCount) {
      if(this.props.infinite === false) {
        animationTargetSlide = this.state.slideCount - 1
        finalTargetSlide = this.state.slideCount - 1
      } else {
        animationTargetSlide = this.state.slideCount
        finalTargetSlide = 0
      }
    } else if (animationTargetSlide >= this.state.slideCount) {
      if(this.props.infinite === false) {
        finalTargetSlide = this.state.slideCount - this.props.slidesToShow;
      } else if (this.state.slideCount % this.props.slidesToScroll !== 0) {
        finalTargetSlide = 0;
      } else {
        finalTargetSlide = animationTargetSlide - this.state.slideCount;
      }
    } else if (this.state.currentSlide + this.slidesToShow < this.state.slideCount && animationTargetSlide + this.props.slidesToShow >= this.state.slideCount) {
      if (this.props.infinite === false) {
        finalTargetSlide = this.state.slideCount - this.props.slidesToShow
      } else {
        if ((this.state.slideCount - animationTargetSlide) % this.props.slidesToScroll !== 0) {
          finalTargetSlide = this.state.slideCount - this.props.slidesToShow
        } else {
          finalTargetSlide = animationTargetSlide
        }
      }
    } else {
      finalTargetSlide = animationTargetSlide;
    }

    /*
      stop: critical checkpoint
    */

    animationTargetLeft = getTrackLeft(assign({
      slideIndex: animationTargetSlide,
      trackRef: this.track
    }, this.props, this.state));

    finalTargetLeft = getTrackLeft(assign({
      slideIndex: finalTargetSlide,
      trackRef: this.track
    }, this.props, this.state));

    if (this.props.infinite === false) {
      if (animationTargetLeft === finalTargetLeft) {
        animationTargetSlide = finalTargetSlide;
      }
      animationTargetLeft = finalTargetLeft;
    }

    if (this.props.beforeChange) {
      this.props.beforeChange(this.state.currentSlide, finalTargetSlide);
    }

    if (this.props.lazyLoad) {
      var slidesToLoad = [];
      let slideCount = this.state.slideCount
      for (var i = animationTargetSlide; i < animationTargetSlide + this.props.slidesToShow; i++ ) {
        if (this.state.lazyLoadedList.indexOf(i) < 0) {
          slidesToLoad.push(i)
        }
        if (i >= slideCount && this.state.lazyLoadedList.indexOf(i - slideCount) < 0) {
          slidesToLoad.push(i - slideCount)
        }
        if (i < 0 && this.state.lazyLoadedList.indexOf(i + slideCount) < 0) {
          slidesToLoad.push(i + slideCount)
        }
      }
      if (slidesToLoad.length > 0) {
        this.setState({
          lazyLoadedList: this.state.lazyLoadedList.concat(slidesToLoad)
        });
      }
    }

    // Slide Transition happens here.
    // animated transition happens to target Slide and
    // non - animated transition happens to current Slide
    // If CSS transitions are false, directly go the current slide.

    if (this.props.useCSS === false) {
      this.setState({
        currentSlide: finalTargetSlide,
        trackStyle: getTrackCSS(assign({left: finalTargetLeft}, this.props, this.state))
      }, function () {
        if (this.props.afterChange) {
          this.props.afterChange(finalTargetSlide);
        }
      });

    } else {

      var nextStateChanges = {
        animating: false,
        currentSlide: finalTargetSlide,
        trackStyle: getTrackCSS(assign({left: finalTargetLeft}, this.props, this.state)),
        swipeLeft: null
      };
      callback = () => {
        this.setState(nextStateChanges, () => {
          if (this.props.afterChange) {
            this.props.afterChange(finalTargetSlide);
          }
          delete this.animationEndCallback;
        });
      };

      this.setState({
        animating: true,
        currentSlide: finalTargetSlide,
        trackStyle: getTrackAnimateCSS(assign({left: animationTargetLeft}, this.props, this.state))
      }, function () {
        this.animationEndCallback = setTimeout(callback, this.props.speed);
      });

    }

    this.autoPlay();
  },
  swipeDirection: function (touchObject) {
    var xDist, yDist, r, swipeAngle;

    xDist = touchObject.startX - touchObject.curX;
    yDist = touchObject.startY - touchObject.curY;
    r = Math.atan2(yDist, xDist);

    swipeAngle = Math.round(r * 180 / Math.PI);
    if (swipeAngle < 0) {
        swipeAngle = 360 - Math.abs(swipeAngle);
    }
    if ((swipeAngle <= 45) && (swipeAngle >= 0) || (swipeAngle <= 360) && (swipeAngle >= 315)) {
        return 'left';
    }
    if ((swipeAngle >= 135) && (swipeAngle <= 225)) {
        return 'right';
    }
    if (this.props.verticalSwiping === true) {
      if ((swipeAngle >= 35) && (swipeAngle <= 135)) {
        return 'down';
      } else {
        return 'up';
      }
    }

    return 'vertical';
  },
  play: function(){
    var nextIndex;

    // if (!this.state.mounted) {
    //   return false
    // }

    if (this.props.rtl) {
      nextIndex = this.state.currentSlide - this.props.slidesToScroll;
    } else {
      if (this.canGoNext(Object.assign({}, this.props,this.state))) {
        nextIndex = this.state.currentSlide + this.props.slidesToScroll;
      } else {
        return false;
      }
    }

    this.slideHandler(nextIndex);
  },
  autoPlay: function (autoplay=false) {
    if (this.state.autoPlayTimer) {
      clearTimeout(this.state.autoPlayTimer);
    }
    if (autoplay || this.props.autoplay) {
      this.setState({
        autoPlayTimer: setTimeout(this.play, this.props.autoplaySpeed)
      });
    }
  },
  pause: function () {
    if (this.state.autoPlayTimer) {
      clearTimeout(this.state.autoPlayTimer);
      this.setState({
        autoPlayTimer: null
      });
    }
  }
};

export default helpers;
<|endoftext|>