<commit_before>/*
 *     Copyright (c) 2013-2014 Universidad Politécnica de Madrid
 *
 *     This file is part of Wirecloud Platform.
 *
 *     Wirecloud Platform is free software: you can redistribute it and/or
 *     modify it under the terms of the GNU Affero General Public License as
 *     published by the Free Software Foundation, either version 3 of the
 *     License, or (at your option) any later version.
 *
 *     Wirecloud is distributed in the hope that it will be useful, but WITHOUT
 *     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 *     License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with Wirecloud Platform.  If not, see
 *     <http://www.gnu.org/licenses/>.
 *
 */

/*global Wirecloud*/

(function () {

    "use strict";

    var _canBeDragged = function () {
        return true;
    };

    var _cancel = function () {
        return false;
    };

    /**
     * @param draggableElement {HTMLElement} Element to drag
     * @param handler {HTMLElement} Element where the drag & drop operation must to be started
     * @param data {Object} context
     */
    var Draggable = function Draggable(handler, data, onStart, onDrag, onFinish, canBeDragged, onScroll) {
        var xStart = 0, yStart = 0, xScrollStart = 0, yScrollStart = 0;
        var xScrollDelta, yScrollDelta;
        var dragboardCover;
        var draggable = this;
        var enddrag, drag, startdrag, scroll;
        canBeDragged = canBeDragged ? canBeDragged : _canBeDragged;

        // remove the events
        enddrag = function enddrag(e) {

            // Only attend to left button (or right button for left-handed persons) events
            if (e.type === 'mouseup' && e.button !== 0) {
                return;
            } else if (e.type === 'touchend' && e.touches.length > 0) {
                return;
            }

            document.removeEventListener("mouseup", enddrag, false);
            document.removeEventListener("touchend", enddrag, false);
            document.removeEventListener("mousemove", drag, false);
            document.removeEventListener("touchmove", drag, false);

            if (dragboardCover != null) {
                dragboardCover.parentNode.removeEventListener("scroll", scroll, true);
                dragboardCover.parentNode.removeChild(dragboardCover);
                dragboardCover = null;
            }

            onFinish(draggable, data, e);

            handler.addEventListener("mousedown", startdrag, false);
            handler.addEventListener("touchstart", startdrag, false);

            document.removeEventListener('contextmenu', Wirecloud.Utils.preventDefaultListener); // reenable context menu
            document.removeEventListener('mousedown', Wirecloud.Utils.preventDefaultListener); // reenable text selection
        };

        // fire each time it's dragged
        drag = function drag(e) {
            var clientX, clientY;

            if ('touches' in e) {
                clientX = e.touches[0].clientX;
                clientY = e.touches[0].clientY;
                // Work around chrome bug: https://code.google.com/p/chromium/issues/detail?id=150779
                e.preventDefault();
            } else {
                clientX = e.clientX;
                clientY = e.clientY;
            }
            var xDelta = clientX - xStart - xScrollDelta;
            var yDelta = clientY - yStart - yScrollDelta;

            onDrag(e, draggable, data, xDelta, yDelta);
        };

        // initiate the drag
        startdrag = function startdrag(e) {

            // Only attend to left button (or right button for left-handed persons) events
            if (e.type === 'mousedown' && e.button !== 0) {
                return;
            }

            if (!canBeDragged(draggable, data)) {
                return false;
            }

            e.preventDefault(); // disable text selection caused by this event
            document.addEventListener('contextmenu', Wirecloud.Utils.preventDefaultListener); // disable context menu
            document.addEventListener('mousedown', Wirecloud.Utils.preventDefaultListener); // disable text selection in Firefox
            handler.removeEventListener("mousedown", startdrag, false);
            handler.removeEventListener("touchstart", startdrag, false);

            if ('touches' in e) {
                xStart = e.touches[0].clientX;
                yStart = e.touches[0].clientY;
            } else {
                xStart = e.clientX;
                yStart = e.clientY;
            }

            document.addEventListener("mouseup", enddrag, false);
            document.addEventListener("touchend", enddrag, false);
            document.addEventListener("mousemove", drag, false);
            document.addEventListener("touchmove", drag, false);

            yScrollDelta = 0;
            xScrollDelta = 0;

            var options = onStart(draggable, data, e);
            // TODO
            if (options != null && options.dragboard) {
                var dragboard = options.dragboard;
                dragboardCover = document.createElement("div");
                dragboardCover.className = "cover";
                dragboardCover.addEventListener("mouseup", enddrag, true);
                dragboardCover.addEventListener("touchend", enddrag, true);
                dragboardCover.addEventListener("mousemove", drag, true);
                dragboardCover.addEventListener("touchmove", drag, true);

                dragboardCover.style.zIndex = "1000000";
                dragboardCover.style.position = "absolute";
                dragboardCover.style.top = "0";
                dragboardCover.style.left = "0";
                dragboardCover.style.width = "100%";
                dragboardCover.style.height = dragboard.scrollHeight + "px";

                yScrollStart = parseInt(dragboard.scrollTop, 10);
                xScrollStart = parseInt(dragboard.scrollLeft, 10);

                dragboardCover.addEventListener("scroll", scroll, true);

                dragboard.insertBefore(dragboardCover, dragboard.firstChild);
            }

            e.stopPropagation();
        };

        // fire each time the dragboard is scrolled while dragging
        scroll = function scroll(e) {

            var dragboard = dragboardCover.parentNode;
            dragboardCover.style.height = dragboard.scrollHeight + "px";
            var scrollTop = parseInt(dragboard.scrollTop, 10);

            // yScrollDeltaDiff = diff between old scroll y delta and the new scroll y delta
            var oldYDelta = yScrollDelta;
            yScrollDelta = yScrollStart - scrollTop;
            var yScrollDeltaDiff = yScrollDelta - oldYDelta;

            var scrollLeft = parseInt(dragboard.scrollLeft, 10);
            // xScrollDeltaDiff = diff between old scroll x delta and the new scroll x delta
            var oldXDelta = xScrollDelta;
            xScrollDelta = xScrollStart - scrollLeft;
            var xScrollDeltaDiff = xScrollDelta - oldXDelta;

            onScroll(e, draggable, data, xScrollDeltaDiff, yScrollDeltaDiff);
        };

        // add mousedown event listener
        handler.addEventListener("mousedown", startdrag, false);
        handler.addEventListener("touchstart", startdrag, false);

        /**********
         * Public methods
         **********/

        this.destroy = function destroy() {
            handler.removeEventListener("mousedown", startdrag, false);
            handler.removeEventListener("touchstart", startdrag, false);
            startdrag = null;
            enddrag = null;
            drag = null;
            scroll = null;
            draggable = null;
            data = null;
            handler = null;
        };
    };

    Wirecloud.ui.Draggable = Draggable;<commit_msg>Fix drag & drop scrolling problems<commit_after>/*
 *     Copyright (c) 2013-2015 Universidad Politécnica de Madrid
 *
 *     This file is part of Wirecloud Platform.
 *
 *     Wirecloud Platform is free software: you can redistribute it and/or
 *     modify it under the terms of the GNU Affero General Public License as
 *     published by the Free Software Foundation, either version 3 of the
 *     License, or (at your option) any later version.
 *
 *     Wirecloud is distributed in the hope that it will be useful, but WITHOUT
 *     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 *     License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with Wirecloud Platform.  If not, see
 *     <http://www.gnu.org/licenses/>.
 *
 */

/*global Wirecloud*/

(function () {

    "use strict";

    var _canBeDragged = function () {
        return true;
    };

    var _cancel = function () {
        return false;
    };

    /**
     * @param draggableElement {HTMLElement} Element to drag
     * @param handler {HTMLElement} Element where the drag & drop operation must to be started
     * @param data {Object} context
     */
    var Draggable = function Draggable(handler, data, onStart, onDrag, onFinish, canBeDragged, onScroll) {
        var lastClientX, lastClientY;
        var xStart = 0, yStart = 0, xScrollStart = 0, yScrollStart = 0;
        var xScrollDelta, yScrollDelta;
        var dragboardCover;
        var draggable = this;
        var enddrag, drag, startdrag, scroll;
        canBeDragged = canBeDragged ? canBeDragged : _canBeDragged;

        // remove the events
        enddrag = function enddrag(e) {

            // Only attend to left button (or right button for left-handed persons) events
            if (e.type === 'mouseup' && e.button !== 0) {
                return;
            } else if (e.type === 'touchend' && e.touches.length > 0) {
                return;
            }

            document.removeEventListener("mouseup", enddrag, false);
            document.removeEventListener("touchend", enddrag, false);
            document.removeEventListener("mousemove", drag, false);
            document.removeEventListener("touchmove", drag, false);

            if (dragboardCover != null) {
                dragboardCover.parentNode.removeEventListener("scroll", scroll, true);
                dragboardCover.parentNode.removeChild(dragboardCover);
                dragboardCover = null;
            }

            onFinish(draggable, data, e);

            handler.addEventListener("mousedown", startdrag, false);
            handler.addEventListener("touchstart", startdrag, false);

            document.removeEventListener('contextmenu', Wirecloud.Utils.preventDefaultListener); // reenable context menu
            document.removeEventListener('mousedown', Wirecloud.Utils.preventDefaultListener); // reenable text selection
        };

        // fire each time it's dragged
        drag = function drag(e) {

            if ('touches' in e) {
                lastClientX = e.touches[0].clientX;
                lastClientY = e.touches[0].clientY;
                // Work around chrome bug: https://code.google.com/p/chromium/issues/detail?id=150779
                e.preventDefault();
            } else {
                lastClientX = e.clientX;
                lastClientY = e.clientY;
            }
            var xDelta = lastClientX - xStart - xScrollDelta;
            var yDelta = lastClientY - yStart - yScrollDelta;

            onDrag(e, draggable, data, xDelta, yDelta);
        };

        // initiate the drag
        startdrag = function startdrag(e) {

            // Only attend to left button (or right button for left-handed persons) events
            if (e.type === 'mousedown' && e.button !== 0) {
                return;
            }

            if (!canBeDragged(draggable, data)) {
                return false;
            }

            e.preventDefault(); // disable text selection caused by this event
            document.addEventListener('contextmenu', Wirecloud.Utils.preventDefaultListener); // disable context menu
            document.addEventListener('mousedown', Wirecloud.Utils.preventDefaultListener); // disable text selection in Firefox
            handler.removeEventListener("mousedown", startdrag, false);
            handler.removeEventListener("touchstart", startdrag, false);

            if ('touches' in e) {
                xStart = e.touches[0].clientX;
                yStart = e.touches[0].clientY;
            } else {
                xStart = e.clientX;
                yStart = e.clientY;
            }
            lastClientX = xStart;
            lastClientY = yStart;

            document.addEventListener("mouseup", enddrag, false);
            document.addEventListener("touchend", enddrag, false);
            document.addEventListener("mousemove", drag, false);
            document.addEventListener("touchmove", drag, false);

            yScrollDelta = 0;
            xScrollDelta = 0;

            var options = onStart(draggable, data, e);
            // TODO
            if (options != null && options.dragboard) {
                var dragboard = options.dragboard;
                dragboardCover = document.createElement("div");
                dragboardCover.className = "cover";
                dragboardCover.addEventListener("mouseup", enddrag, true);
                dragboardCover.addEventListener("touchend", enddrag, true);
                dragboardCover.addEventListener("mousemove", drag, true);
                dragboardCover.addEventListener("touchmove", drag, true);

                dragboardCover.style.zIndex = "1000000";
                dragboardCover.style.position = "absolute";
                dragboardCover.style.top = "0";
                dragboardCover.style.left = "0";
                dragboardCover.style.width = "100%";
                dragboardCover.style.height = dragboard.scrollHeight + "px";

                yScrollStart = parseInt(dragboard.scrollTop, 10);
                xScrollStart = parseInt(dragboard.scrollLeft, 10);

                dragboard.addEventListener("scroll", scroll, true);

                dragboard.insertBefore(dragboardCover, dragboard.firstChild);
            }

            e.stopPropagation();
        };

        // fire each time the dragboard is scrolled while dragging
        scroll = function scroll(e) {

            var dragboard = dragboardCover.parentNode;
            dragboardCover.style.height = dragboard.scrollHeight + "px";

            var scrollTop = parseInt(dragboard.scrollTop, 10);
            yScrollDelta = yScrollStart - scrollTop;

            var scrollLeft = parseInt(dragboard.scrollLeft, 10);
            xScrollDelta = xScrollStart - scrollLeft;

            var xDelta = lastClientX - xStart - xScrollDelta;
            var yDelta = lastClientY - yStart - yScrollDelta;

            onDrag(e, draggable, data, xDelta, yDelta);
        };

        // add mousedown event listener
        handler.addEventListener("mousedown", startdrag, false);
        handler.addEventListener("touchstart", startdrag, false);

        /**********
         * Public methods
         **********/

        this.destroy = function destroy() {
            handler.removeEventListener("mousedown", startdrag, false);
            handler.removeEventListener("touchstart", startdrag, false);
            startdrag = null;
            enddrag = null;
            drag = null;
            scroll = null;
            draggable = null;
            data = null;
            handler = null;
        };
    };

    Wirecloud.ui.Draggable = Draggable;
{'fraction_non_alphanumeric': 0.09631602308033733, 'fraction_numerical': 0.006087121932661214, 'mean_word_length': 2.0185645933014356, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5933548', 'n_tokens_mistral': 4164, 'n_tokens_neox': 3913, 'n_words': 1093}