<commit_before>define([
    'aux/events'
], function (Events) {

    /**
     * A module to attach different touch events to an element.
     * @exports touch
     *
     * @requires module:events
     */
    function Touch (options) {
        this.events = new Events();
        this.touchStartX = 0;
        this.touchStartY = 0;
        // Sets the thresholds of interaction types
        this.swipeDistance = 10;
    }

    /**
     * Check if touch has moved position to determine tap.
     * @memberOf module:touch
     *
     * @protected
     * @param {integer} posX Current X position.
     * @param {integer} posY Current Y positon.
     * @return {Boolean} True if position is the same.
     */
    Touch.prototype._isTap = function (posX, posY) {
        return (this.touchStartX === posX) && (this.touchStartY === posY);
    };

    /**
     * Check if touch has moved position to determine swipe.
     * @memberOf module:touch
     *
     * @protected
     * @param {integer} distanceX Absolute distance traveled on X.
     * @param {integer} distanceY Absolute distance traveled on Y.
     * @return {Boolean} True if distance traveled is bigger than threshold.
     */

    Touch.prototype._isSwipe = function (distanceX, distanceY) {
        return ((this.swipeDistance < distanceX) || (this.swipeDistance < distanceY));
    };

    /**
     * Returns pointer horizontal and vertical postion
     * @memberOf module:touch
     *
     * @protected
     * @param {Obejct} event An event object passed from the browser such as touchend or click
     * @return {Boolean} True if position is the same.
     */
    Touch.prototype._getCords = function (event) {
        if (event.changedTouches && event.changedTouches.length) {
            return {
                x: event.changedTouches[0].pageX,
                y: event.changedTouches[0].pageY
            };
        } else {
            return {
                x: event.pageX,
                y: event.pageY
            };
        }
    };

    /**
     * Returns direction of the swipe
     * @memberOf module:touch
     *
     * @protected
     * @param {integer} distanceX Absolute distance traveled on X.
     * @param {integer} distanceY Absolute distance traveled on Y.
     * @param {integer} diffX Distance traveled on X.
     * @param {integer} diffY Distance traveled on Y.
     * @return {Boolean} True if position is the same.
     */
    Touch.prototype._getDirection = function (distanceX, distanceY, diffX, diffY) {
        var swiped;
        if (distanceX > distanceY) {
            if (diffX > 0) {
                swiped = 'left';
            } else {
                swiped = 'right';
            }
        } else {
            if (diffY > 0) {
                swiped = 'up';
            } else {
                swiped = 'down';
            }
        }
        return swiped;
    };

    /**
     * Setup a tap event allowing for both tap or clicking on an element.
     * @memberOf module:touch
     *
     * @public
     * @param {Object} ele Node element to attach touch events to
     * @param {Function} callback When tap event has occurred
     *
     * @example
     * ```js
     * var touch = new Touch(),
     * 	ele = document.createElement('div');
     *
     * touch.tap(ele, function () {
     * 	console.log('I have been tapped');
     * });
     * // When tapping on the div element if will fire the console log
     * // When clicking on the div element it will also fire the console log
     * ```
     */
    Touch.prototype.tap = function (ele, callback) {
        var $this = this,
            startHandler = $this._touchStartHandler(),
            endHandler = $this._touchEndHandler(callback);

        this.events.addListeners(ele, 'click', endHandler);

        this.events.addListeners(ele, 'touchstart', function (rbEvent, event) {
            rbEvent.preventDefault();
            startHandler(rbEvent, event);
        });

        this.events.addListeners(ele, 'mousedown', function (rbEvent, event) {
            startHandler(rbEvent, event);
        });

        this.events.addListeners(ele, 'touchend', function (rbEvent, event) {
            rbEvent.preventDefault();
            endHandler(rbEvent, event);
        });
    };

    /**
     * Setup a swipe event allowing for an event to fire when a swipe has occured on an element
     * NOTE: Allows for, left, right, up and down (multiple can be added using spaces)
     * @memberOf module:touch
     *
     * @public
     * @param  {Object}   ele       The element in which to add the swipe event
     * @param  {Function} callback  When swipe event has occured
     * @param  {String}   direction The direction(s) in which to fire the event
     *
     * @example
     * ```js
     * var touch = new Touch(),
     * 	ele = document.createElement('div');
     *
     * touch.swipe(ele, function () {
     * 	console.log('I have been swipe left');
     * }, 'left right');
     * // When swiping (in either a left or right direction) on the div element it will fire the console log
     * ```
     */
    Touch.prototype.swipe = function (ele, callback, direction) {
        var $this = this;
        this.events.addListeners(ele, 'touchstart', $this._touchStartHandler());
        this.events.addListeners(ele, 'touchend', function (rbEvent, event) {
            rbEvent.preventDefault();
            $this._touchEndHandler(callback, direction, true)(rbEvent, event);
        });
    };

    /**
     * Touch event handler which is called on touch start and movedown.
     * @memberOf module:touch
     *
     * @protected
     * @return {Function} Function for touch event handling
     */
    Touch.prototype._touchStartHandler = function () {
        var $this = this;
        return function (event, data) {
            var cords = $this._getCords(data);
            $this.touchStartX = cords['x'];
            $this.touchStartY = cords['y'];
        };
    };

    /**
     * Touch event handler which is called on touch end and click/tap.
     * @memberOf module:touch
     *
     * @protected
     * @param {Function} callback When a click, tap, swipe event has occurred
     * @param {String} direction The direction(s) in which to fire the event
     * @param {Boolean} swipe To indicate if we are swiping or taping.
     * @return {Function} Function for touch event handling
     */
    Touch.prototype._touchEndHandler = function (callback, direction, swipe) {
        var $this = this;
        return function (event, data) {
            var cords = $this._getCords(data),
                threshold = $this.swipeDistance,
                diffX,
                diffY,
                distanceX,
                distanceY,
                dir;

            diffX = $this.touchStartX - cords['x'];
            diffY =  $this.touchStartY - cords['y'];
            distanceX = Math.abs(diffX);
            distanceY = Math.abs(diffY);

            if (!swipe && $this._isTap(cords['x'], cords['y'])) {
                callback(event, data);
            } else if (swipe && $this._isSwipe(distanceX, distanceY)) {
                dir = $this._getDirection(distanceX, distanceY, diffX, diffY);
                if (direction.indexOf(dir) > -1) {
                    callback(event, data);
                }
            }
        };
    };

    return Touch;
});
<commit_msg>Fix an issue where event data is undefined in IE8<commit_after>define([
    'aux/events'
], function (Events) {

    /**
     * A module to attach different touch events to an element.
     * @exports touch
     *
     * @requires module:events
     */
    function Touch (options) {
        this.events = new Events();
        this.touchStartX = 0;
        this.touchStartY = 0;
        // Sets the thresholds of interaction types
        this.swipeDistance = 10;
    }

    /**
     * Check if touch has moved position to determine tap.
     * @memberOf module:touch
     *
     * @protected
     * @param {integer} posX Current X position.
     * @param {integer} posY Current Y positon.
     * @return {Boolean} True if position is the same.
     */
    Touch.prototype._isTap = function (posX, posY) {
        return (this.touchStartX === posX) && (this.touchStartY === posY);
    };

    /**
     * Check if touch has moved position to determine swipe.
     * @memberOf module:touch
     *
     * @protected
     * @param {integer} distanceX Absolute distance traveled on X.
     * @param {integer} distanceY Absolute distance traveled on Y.
     * @return {Boolean} True if distance traveled is bigger than threshold.
     */

    Touch.prototype._isSwipe = function (distanceX, distanceY) {
        return ((this.swipeDistance < distanceX) || (this.swipeDistance < distanceY));
    };

    /**
     * Returns pointer horizontal and vertical postion
     * @memberOf module:touch
     *
     * @protected
     * @param {Obejct} event An event object passed from the browser such as touchend or click
     * @return {Boolean} True if position is the same.
     */
    Touch.prototype._getCords = function (event) {
        if (event.changedTouches && event.changedTouches.length) {
            return {
                x: event.changedTouches[0].pageX,
                y: event.changedTouches[0].pageY
            };
        } else {
            return {
                x: event.pageX,
                y: event.pageY
            };
        }
    };

    /**
     * Returns direction of the swipe
     * @memberOf module:touch
     *
     * @protected
     * @param {integer} distanceX Absolute distance traveled on X.
     * @param {integer} distanceY Absolute distance traveled on Y.
     * @param {integer} diffX Distance traveled on X.
     * @param {integer} diffY Distance traveled on Y.
     * @return {Boolean} True if position is the same.
     */
    Touch.prototype._getDirection = function (distanceX, distanceY, diffX, diffY) {
        var swiped;
        if (distanceX > distanceY) {
            if (diffX > 0) {
                swiped = 'left';
            } else {
                swiped = 'right';
            }
        } else {
            if (diffY > 0) {
                swiped = 'up';
            } else {
                swiped = 'down';
            }
        }
        return swiped;
    };

    /**
     * Setup a tap event allowing for both tap or clicking on an element.
     * @memberOf module:touch
     *
     * @public
     * @param {Object} ele Node element to attach touch events to
     * @param {Function} callback When tap event has occurred
     *
     * @example
     * ```js
     * var touch = new Touch(),
     * 	ele = document.createElement('div');
     *
     * touch.tap(ele, function () {
     * 	console.log('I have been tapped');
     * });
     * // When tapping on the div element if will fire the console log
     * // When clicking on the div element it will also fire the console log
     * ```
     */
    Touch.prototype.tap = function (ele, callback) {
        var $this = this,
            startHandler = $this._touchStartHandler(),
            endHandler = $this._touchEndHandler(callback);

        this.events.addListeners(ele, 'click', endHandler);

        this.events.addListeners(ele, 'touchstart', function (rbEvent, event) {
            rbEvent.preventDefault();
            startHandler(rbEvent, event);
        });

        this.events.addListeners(ele, 'mousedown', function (rbEvent, event) {
            startHandler(rbEvent, event);
        });

        this.events.addListeners(ele, 'touchend', function (rbEvent, event) {
            rbEvent.preventDefault();
            endHandler(rbEvent, event);
        });
    };

    /**
     * Setup a swipe event allowing for an event to fire when a swipe has occured on an element
     * NOTE: Allows for, left, right, up and down (multiple can be added using spaces)
     * @memberOf module:touch
     *
     * @public
     * @param  {Object}   ele       The element in which to add the swipe event
     * @param  {Function} callback  When swipe event has occured
     * @param  {String}   direction The direction(s) in which to fire the event
     *
     * @example
     * ```js
     * var touch = new Touch(),
     * 	ele = document.createElement('div');
     *
     * touch.swipe(ele, function () {
     * 	console.log('I have been swipe left');
     * }, 'left right');
     * // When swiping (in either a left or right direction) on the div element it will fire the console log
     * ```
     */
    Touch.prototype.swipe = function (ele, callback, direction) {
        var $this = this;
        this.events.addListeners(ele, 'touchstart', $this._touchStartHandler());
        this.events.addListeners(ele, 'touchend', function (rbEvent, event) {
            rbEvent.preventDefault();
            $this._touchEndHandler(callback, direction, true)(rbEvent, event);
        });
    };

    /**
     * Touch event handler which is called on touch start and movedown.
     * @memberOf module:touch
     *
     * @protected
     * @return {Function} Function for touch event handling
     */
    Touch.prototype._touchStartHandler = function () {
        var $this = this;
        return function (event, data) {
            if (typeof data === 'undefined') {
                return;
            }
            var cords = $this._getCords(data);
            $this.touchStartX = cords['x'];
            $this.touchStartY = cords['y'];
        };
    };

    /**
     * Touch event handler which is called on touch end and click/tap.
     * @memberOf module:touch
     *
     * @protected
     * @param {Function} callback When a click, tap, swipe event has occurred
     * @param {String} direction The direction(s) in which to fire the event
     * @param {Boolean} swipe To indicate if we are swiping or taping.
     * @return {Function} Function for touch event handling
     */
    Touch.prototype._touchEndHandler = function (callback, direction, swipe) {
        var $this = this;
        return function (event, data) {
            if (event.type === 'click' && typeof data === 'undefined') {
                callback(event, data);
            }
            if (typeof data === 'undefined') {
                return;
            }
            var cords = $this._getCords(data),
                threshold = $this.swipeDistance,
                diffX,
                diffY,
                distanceX,
                distanceY,
                dir;

            diffX = $this.touchStartX - cords['x'];
            diffY =  $this.touchStartY - cords['y'];
            distanceX = Math.abs(diffX);
            distanceY = Math.abs(diffY);

            if (!swipe && $this._isTap(cords['x'], cords['y'])) {
                callback(event, data);
            } else if (swipe && $this._isSwipe(distanceX, distanceY)) {
                dir = $this._getDirection(distanceX, distanceY, diffX, diffY);
                if (direction.indexOf(dir) > -1) {
                    callback(event, data);
                }
            }
        };
    };

    return Touch;
});
<|endoftext|>


<commit_before>'use strict';

function check(){
    // Check if every button has correct solution on it.
    var win = true;
    var loop_counter = 80;
    do{
        if(document.getElementById(loop_counter).value != puzzle[loop_counter]){
            win = false;
            break;
        }
    }while(loop_counter--);

    window.alert(
      win
        ? 'Correct! You win!'
        : 'Incorrect, try again.'
    );
}

function display_number_select(id){
    // Reset button zIndex values.
    var loop_counter = 80;
    do{
        document.getElementById(loop_counter).style.zIndex = 0;
    }while(loop_counter--);

    if(selected_button === -1
      || selected_button != id){
        selected_button = id;

        // Increase zIndex of selected button.
        document.getElementById(selected_button).style.zIndex = 2;

        // Display number-select behind selected button.
        update_number_select(id);
        document.getElementById('number-select').style.display = 'block';

    }else{
        // Hide number select.
        selected_button = -1;
        document.getElementById('number-select').style.display = 'none';
    }
}

function generate_puzzle(skip){
    if(!skip
      && !window.confirm('Generate new puzzle?')){
        return;
    }

    settings_save();

    document.getElementById('game-div').style.marginTop = parseInt(
      settings_settings['y-margin'],
      10
    ) + 'px';

    var first = 0;
    var second = 0;
    var which = 0;

    // Base sudoku puzzle.
    puzzle = [
      8,7,6, 5,4,3, 2,1,9,
      5,4,3, 2,1,9, 8,7,6,
      2,1,9, 8,7,6, 5,4,3,

      7,6,5, 4,3,2, 1,9,8,
      4,3,2, 1,9,8, 7,6,5,
      1,9,8, 7,6,5, 4,3,2,

      6,5,4, 3,2,1, 9,8,7,
      3,2,1, 9,8,7, 6,5,4,
      9,8,7, 6,5,4, 3,2,1,
    ];

    // Switch all instances of two random numbers 100 times.
    var loop_counter = 99;
    do{
        // Pick two different numbers between 1 and 9.
        first = random_integer({
          'max': 9,
          'todo': 'ceil',
        });
        do{
            second = random_integer({
              'max': 9,
              'todo': 'ceil',
            });
        }while(first === second);

        // Iterate through all buttons and switch those two numbers.
        times = 80;
        do{
            if(puzzle[times] === first){
                puzzle[times] = second;

            }else if(puzzle[times] === second){
                puzzle[times] = first;
            }
        }while(times--);
    }while(loop_counter--);

    // Switch columns between different blocks of 3 columns 100 times.
    loop_counter = 99;
    do{
        // Pick a column number to switch.
        which = random_integer({
          'max': 3,
        });

        // Pick two different blocks of 3 columns to switch the selected column number between.
        first = random_integer({
          'max': 3,
        });
        do{
            second = random_integer({
              'max': 3,
            });
        }while(first === second);

        // Iterate through each value in the selected column.
        // Swap them between the two selected blocks of 3 columns.
        times = 8;
        do{
            var temp = puzzle[9 * times + 3 * first + which];
            puzzle[9 * times + 3 * first + which] = puzzle[9 * times + 3 * second + which];
            puzzle[9 * times + 3 * second + which] = temp;
        }while(times--);
    }while(loop_counter--);

    // Switch columns within a block of 3 columns 100 times.
    loop_counter = 99;
    do{
        // Pick the block of 3 columns in which to switch two columns.
        which = random_integer({
          'max': 3,
        });

        // Pick two different columns to switch.
        first = random_integer({
          'max': 3,
        });
        do{
            second = random_integer({
              'max': 3,
            });
        }while(first === second);

        // Iterate through each value and swap the values between the two selected columns.
        times = 8;
        do{
            var temp = puzzle[9 * times + 3 * which + first];
            puzzle[9 * times + 3 * which + first] = puzzle[9 * times + 3 * which + second];
            puzzle[9 * times + 3 * which + second] = temp;
        }while(times--);
    }while(loop_counter--);

    // Switch random rows within a block of 3 rows 100 times.
    loop_counter = 99;
    do{
        // Pick one of the 3 blocks of 3 rows.
        which = random_integer({
          'max': 3,
        });

        // Pick two different rows.
        first = random_integer({
          'max': 3,
        });
        do{
            second = random_integer({
              'max': 3,
            });
        }while(first === second);

        // Iterate through each value and swap the values between the two selected rows.
        times = 8;
        do{
            var temp = puzzle[which * 27 + first * 9 + times];
            puzzle[which * 27 + first * 9 + times] = puzzle[which * 27 + second * 9 + times];
            puzzle[which * 27 + second * 9 + times] = temp;
        }while(times--);
    }while(loop_counter--);

    // Reset all buttons.
    loop_counter = 80;
    do{
        var element = document.getElementById(loop_counter);
        element.disabled = false;
        element.style.background = '#333';
        element.style.color = '#aaa';
        element.value = '';
    }while(loop_counter--);

    // Add solutions to some random buttons.
    loop_counter = settings_settings['locked'] - 1;
    if(loop_counter >= 0){
        do{
            first = random_integer({
              'max': 81,
            });
            var first_element = document.getElementById(first);
            var element_80 = document.getElementById(80 - first);

            first_element.disabled = true;
            element_80.disabled = true;

            first_element.style.background = '#777';
            element_80.style.background = '#777';

            first_element.style.color = '#000';
            element_80.style.color = '#000';

            first_element.value = puzzle[first];
            element_80.value = puzzle[80 - first];
        }while(loop_counter--);
    }
}

function select_number(number){
    document.getElementById(selected_button).value = number > 0
      ? number
      : '';
    selected_button = -1;
    document.getElementById('number-select').style.display = 'none';
}

function settings_toggle(state){
    state = state == void 0
      ? document.getElementById('settings-button').value === '+'
      : state;

    if(state){
        document.getElementById('settings').style.display = 'inline-block';
        document.getElementById('settings-button').value = '-';

    }else{
        document.getElementById('settings').style.display = 'none';
        document.getElementById('settings-button').value = '+';
    }
}

function update_number_select(id){
    // Make sure the number select box doesn't go past the left/right edges.
    var xpos = document.getElementById(id).offsetLeft - 50 - window.pageXOffset;
    if(xpos < 0){
        xpos = 0;

    }else if(xpos > window.innerWidth - 150){
        xpos = window.innerWidth - 150;
    }

    var number_select = document.getElementById('number-select');
    number_select.style.left = xpos + 'px';

    // There is no worry of the number select box going past the top/bottom edges.
    number_select.style.top  =
      (document.getElementById(id).offsetTop  - 50 - window.pageYOffset)
      + 'px';
}

var puzzle = [];
var selected_button = -1;
var times = 0;

window.onkeydown = function(e){
    var key = e.keyCode || e.which;

    // G: generate a new puzzle.
    if(key === 71){
        generate_puzzle(false);

    // C: check puzzle correctness.
    }else if(key === 67){
        check();

    // ESC: hide number selection, if visible.
    }else if(selected_button != -1
      && key === 27){
        display_number_select(selected_button);

    // +: show settings.
    }else if(key === 187){
        settings_toggle(true);

    // -: hide settings.
    }else if(key === 189){
        settings_toggle(false);
    }
};

window.onload = function(){
    settings_init({
      'prefix': 'Sudoku.htm-',
      'settings': {
        'audio-volume': 1,
        'locked': 15,
        'y-margin': 50,
      },
    });

    document.getElementById('settings').innerHTML =
      '
<input onclick=settings_reset() type=button value=Reset>'
        + '
<input id=audio-volume max=1 min=0 step=0.01 type=range>Audio'
        + '
<input id=locked maxlength=2>*2 > Locked'
        + '
<input id=y-margin>Y Margin';
    settings_update();

    // Create buttons and add to game-div.
    var loop_counter = 80;
    var output = '';

    do{
        output +=
          '<input class=buttons id='
          + loop_counter
          + ' onclick=display_number_select('
          + loop_counter
          + ') style=background:#333 type=button>';
        if(loop_counter % 9 === 0
          && loop_counter !== 0){
            output += '
';
        }
    }while(loop_counter--);
    document.getElementById('game-div').innerHTML = output;

    // Setup margins.
    loop_counter = 8;
    do{
        document.getElementById(3 + 9 * loop_counter).style.marginRight = '5px';
        document.getElementById(27 + loop_counter).style.marginBottom = '5px';
        document.getElementById(54 + loop_counter).style.marginBottom = '5px';
        document.getElementById(6 + 9 * loop_counter).style.marginRight = '5px';
    }while(loop_counter--);

    generate_puzzle(true);

    document.getElementById('check').onclick = check;
    document.getElementById('generate').onclick = function(){
        generate_puzzle(false);
    };
    document.getElementById('settings-button').onclick = function(){
        settings_toggle();
    };

    // Setup select-X onclicks.
    loop_counter = 9;
    do{
        document.getElementById('select-' + loop_counter).onclick = function(){
            var id = this.id;
            select_number(id.substring(id.indexOf('-') + 1));
        };
    }while(loop_counter--);
};

window.onresize
  = window.onscroll = function(e){
    // Update position of number select if visible.
    if(selected_button != -1){
        update_number_select(selected_button);
    }
};
<commit_msg>moved event bindings to onload<commit_after>'use strict';

function check(){
    // Check if every button has correct solution on it.
    var win = true;
    var loop_counter = 80;
    do{
        if(document.getElementById(loop_counter).value != puzzle[loop_counter]){
            win = false;
            break;
        }
    }while(loop_counter--);

    window.alert(
      win
        ? 'Correct! You win!'
        : 'Incorrect, try again.'
    );
}

function display_number_select(id){
    // Reset button zIndex values.
    var loop_counter = 80;
    do{
        document.getElementById(loop_counter).style.zIndex = 0;
    }while(loop_counter--);

    if(selected_button === -1
      || selected_button != id){
        selected_button = id;

        // Increase zIndex of selected button.
        document.getElementById(selected_button).style.zIndex = 2;

        // Display number-select behind selected button.
        update_number_select(id);
        document.getElementById('number-select').style.display = 'block';

    }else{
        // Hide number select.
        selected_button = -1;
        document.getElementById('number-select').style.display = 'none';
    }
}

function generate_puzzle(skip){
    if(!skip
      && !window.confirm('Generate new puzzle?')){
        return;
    }

    settings_save();

    document.getElementById('game-div').style.marginTop = parseInt(
      settings_settings['y-margin'],
      10
    ) + 'px';

    var first = 0;
    var second = 0;
    var which = 0;

    // Base sudoku puzzle.
    puzzle = [
      8,7,6, 5,4,3, 2,1,9,
      5,4,3, 2,1,9, 8,7,6,
      2,1,9, 8,7,6, 5,4,3,

      7,6,5, 4,3,2, 1,9,8,
      4,3,2, 1,9,8, 7,6,5,
      1,9,8, 7,6,5, 4,3,2,

      6,5,4, 3,2,1, 9,8,7,
      3,2,1, 9,8,7, 6,5,4,
      9,8,7, 6,5,4, 3,2,1,
    ];

    // Switch all instances of two random numbers 100 times.
    var loop_counter = 99;
    do{
        // Pick two different numbers between 1 and 9.
        first = random_integer({
          'max': 9,
          'todo': 'ceil',
        });
        do{
            second = random_integer({
              'max': 9,
              'todo': 'ceil',
            });
        }while(first === second);

        // Iterate through all buttons and switch those two numbers.
        times = 80;
        do{
            if(puzzle[times] === first){
                puzzle[times] = second;

            }else if(puzzle[times] === second){
                puzzle[times] = first;
            }
        }while(times--);
    }while(loop_counter--);

    // Switch columns between different blocks of 3 columns 100 times.
    loop_counter = 99;
    do{
        // Pick a column number to switch.
        which = random_integer({
          'max': 3,
        });

        // Pick two different blocks of 3 columns to switch the selected column number between.
        first = random_integer({
          'max': 3,
        });
        do{
            second = random_integer({
              'max': 3,
            });
        }while(first === second);

        // Iterate through each value in the selected column.
        // Swap them between the two selected blocks of 3 columns.
        times = 8;
        do{
            var temp = puzzle[9 * times + 3 * first + which];
            puzzle[9 * times + 3 * first + which] = puzzle[9 * times + 3 * second + which];
            puzzle[9 * times + 3 * second + which] = temp;
        }while(times--);
    }while(loop_counter--);

    // Switch columns within a block of 3 columns 100 times.
    loop_counter = 99;
    do{
        // Pick the block of 3 columns in which to switch two columns.
        which = random_integer({
          'max': 3,
        });

        // Pick two different columns to switch.
        first = random_integer({
          'max': 3,
        });
        do{
            second = random_integer({
              'max': 3,
            });
        }while(first === second);

        // Iterate through each value and swap the values between the two selected columns.
        times = 8;
        do{
            var temp = puzzle[9 * times + 3 * which + first];
            puzzle[9 * times + 3 * which + first] = puzzle[9 * times + 3 * which + second];
            puzzle[9 * times + 3 * which + second] = temp;
        }while(times--);
    }while(loop_counter--);

    // Switch random rows within a block of 3 rows 100 times.
    loop_counter = 99;
    do{
        // Pick one of the 3 blocks of 3 rows.
        which = random_integer({
          'max': 3,
        });

        // Pick two different rows.
        first = random_integer({
          'max': 3,
        });
        do{
            second = random_integer({
              'max': 3,
            });
        }while(first === second);

        // Iterate through each value and swap the values between the two selected rows.
        times = 8;
        do{
            var temp = puzzle[which * 27 + first * 9 + times];
            puzzle[which * 27 + first * 9 + times] = puzzle[which * 27 + second * 9 + times];
            puzzle[which * 27 + second * 9 + times] = temp;
        }while(times--);
    }while(loop_counter--);

    // Reset all buttons.
    loop_counter = 80;
    do{
        var element = document.getElementById(loop_counter);
        element.disabled = false;
        element.style.background = '#333';
        element.style.color = '#aaa';
        element.value = '';
    }while(loop_counter--);

    // Add solutions to some random buttons.
    loop_counter = settings_settings['locked'] - 1;
    if(loop_counter >= 0){
        do{
            first = random_integer({
              'max': 81,
            });
            var first_element = document.getElementById(first);
            var element_80 = document.getElementById(80 - first);

            first_element.disabled = true;
            element_80.disabled = true;

            first_element.style.background = '#777';
            element_80.style.background = '#777';

            first_element.style.color = '#000';
            element_80.style.color = '#000';

            first_element.value = puzzle[first];
            element_80.value = puzzle[80 - first];
        }while(loop_counter--);
    }
}

function select_number(number){
    document.getElementById(selected_button).value = number > 0
      ? number
      : '';
    selected_button = -1;
    document.getElementById('number-select').style.display = 'none';
}

function settings_toggle(state){
    state = state == void 0
      ? document.getElementById('settings-button').value === '+'
      : state;

    if(state){
        document.getElementById('settings').style.display = 'inline-block';
        document.getElementById('settings-button').value = '-';

    }else{
        document.getElementById('settings').style.display = 'none';
        document.getElementById('settings-button').value = '+';
    }
}

function update_number_select(id){
    // Make sure the number select box doesn't go past the left/right edges.
    var xpos = document.getElementById(id).offsetLeft - 50 - window.pageXOffset;
    if(xpos < 0){
        xpos = 0;

    }else if(xpos > window.innerWidth - 150){
        xpos = window.innerWidth - 150;
    }

    var number_select = document.getElementById('number-select');
    number_select.style.left = xpos + 'px';

    // There is no worry of the number select box going past the top/bottom edges.
    number_select.style.top  =
      (document.getElementById(id).offsetTop  - 50 - window.pageYOffset)
      + 'px';
}

var puzzle = [];
var selected_button = -1;
var times = 0;

window.onload = function(){
    settings_init({
      'prefix': 'Sudoku.htm-',
      'settings': {
        'audio-volume': 1,
        'locked': 15,
        'y-margin': 50,
      },
    });

    document.getElementById('settings').innerHTML =
      '
<input onclick=settings_reset() type=button value=Reset>'
        + '
<input id=audio-volume max=1 min=0 step=0.01 type=range>Audio'
        + '
<input id=locked maxlength=2>*2 > Locked'
        + '
<input id=y-margin>Y Margin';
    settings_update();

    // Create buttons and add to game-div.
    var loop_counter = 80;
    var output = '';

    do{
        output +=
          '<input class=buttons id='
          + loop_counter
          + ' onclick=display_number_select('
          + loop_counter
          + ') style=background:#333 type=button>';
        if(loop_counter % 9 === 0
          && loop_counter !== 0){
            output += '
';
        }
    }while(loop_counter--);
    document.getElementById('game-div').innerHTML = output;

    // Setup margins.
    loop_counter = 8;
    do{
        document.getElementById(3 + 9 * loop_counter).style.marginRight = '5px';
        document.getElementById(27 + loop_counter).style.marginBottom = '5px';
        document.getElementById(54 + loop_counter).style.marginBottom = '5px';
        document.getElementById(6 + 9 * loop_counter).style.marginRight = '5px';
    }while(loop_counter--);

    generate_puzzle(true);

    document.getElementById('check').onclick = check;
    document.getElementById('generate').onclick = function(){
        generate_puzzle(false);
    };
    document.getElementById('settings-button').onclick = function(){
        settings_toggle();
    };

    // Setup select-X onclicks.
    loop_counter = 9;
    do{
        document.getElementById('select-' + loop_counter).onclick = function(){
            var id = this.id;
            select_number(id.substring(id.indexOf('-') + 1));
        };
    }while(loop_counter--);

    window.onkeydown = function(e){
        var key = e.keyCode || e.which;

        // G: generate a new puzzle.
        if(key === 71){
            generate_puzzle(false);

        // C: check puzzle correctness.
        }else if(key === 67){
            check();

        // ESC: hide number selection, if visible.
        }else if(selected_button != -1
          && key === 27){
            display_number_select(selected_button);

        // +: show settings.
        }else if(key === 187){
            settings_toggle(true);

        // -: hide settings.
        }else if(key === 189){
            settings_toggle(false);
        }
    };

    window.onresize
      = window.onscroll = function(e){
        // Update position of number select if visible.
        if(selected_button != -1){
            update_number_select(selected_button);
        }
    };
};
<|endoftext|>


<commit_before>/**
 * Defines custom events for touch related gusters.
 * Following events are defined:
 * tap, dbltap, taphold, swipe, swipeleft, swiperight
 * @author aniketn3@gmail.com
 */
/**
 * Tap event definition
 */
(function($, undefn) {
   var undef = undefn, state = {/* id, x, y, target */};

   function clearState() {
      state.id = state.x = state.y = state.moved = state.target = undef;
   }

   function hasMoved(x1, y1, x2, y2) {
      var dx = x1 - x2, dy = y1 - y2;
      return Math.abs(dx) > 30 || Math.abs(dy) > 30;
   }

   function handler(te) {
      var type = te.type, touch, touches = te.touches, cTouches = te.changedTouches, target = te.target;
      switch(type) {
         case "touchstart":
            if(touches.length !== 1) {
               return;
            }
            touch = touches[0];
            state.id = touch.identifier;
            state.x = touch.pageX;
            state.y = touch.pageY;
            state.target = target;
            break;
         case "touchmove":
            touch = cTouches[0];
            if(!state.moved && touch.identifier === state.id) {
               state.moved = hasMoved(state.x, state.y, touch.pageX, touch.pageY);
            }
            break;
         case "touchend":
            if(cTouches.length === 0 || state.moved) {
               clearState();
               return;
            }
            touch = cTouches[0];
            if(touch.identifier === state.id &&
                  !hasMoved(state.x, state.y, touch.pageX, touch.pageY) &&
                  state.target === target) {
               $(target).dispatch("tap");
            }
            break;
         case "touchcancel":
            clearState();
            break;
      }
   }

   $.defineEvent({
      type: "tap",
      setup: function() {
         $(document).on("touchstart", handler).on("touchmove", handler)
            .on("touchend", handler).on("touchcancel", handler);
      },
      destroy: function() {
         $(document).un("touchstart", handler).un("touchmove", handler)
            .un("touchend", handler).un("touchcancel", handler);
      }
   });
})(h5);

/**
 * Double Tap event definition
 */
(function($) {
   var state = {/* last, target */};

   function ontap(te) {
      var now = Date.now(), elapsed = now - (state.last || now), target = te.target;
      if(elapsed > 0 && elapsed < 300 && state.target === target) {
         $(target).dispatch("dbltap");
         state.last = state.target = null;
      }else {
         state.last = now;
         state.target = te.target;
      }
   }

   $.defineEvent({
      type: "dbltap",
      setup: function() {
         $(document).on("tap", ontap);
      },
      destroy: function() {
         $(document).un("tap", ontap);
      }
   });
})(h5);

/**
 * Tap hold event
 */
(function($, undefn) {
      var undef = undefn, state = {/* moved, x, y */}, timer;

   function hasMoved(x1, y1, x2, y2) {
      var dx = x1 - x2, dy = y1 - y2;
      return Math.abs(dx) > 30 || Math.abs(dy) > 30;
   }

   function clearState() {
      state.moved = state.x = state.y = undef;
   }

   function handler(te) {
      var type = te.type, target = te.target;
      switch(type) {
         case "touchstart":
            if(te.touches.length !== 1) {
               return;
            }
            state.x = te.pageX;
            state.y = te.pageY;
            timer = setTimeout(function() {
               if(!state.moved) {
                  $(target).dispatch("taphold");
               }
            }, 700);
            break;
         case "touchmove":
            if(!state.moved) {
               state.moved = hasMoved(state.x, state.y, te.pageX, te.pageY);
            }
            break;
         case "touchend":
         case "touchcancel":
         default:
            clearTimeout(timer);
            clearState();
            break;
      }
   }

   $.defineEvent({
      type: "taphold",
      setup: function() {
         $(document).on("touchstart", handler).on("touchmove", handler).on("touchend", handler)
            .on("touchcancel", handler);
      },
      destroy: function() {
         $(document).un("touchstart", handler).un("touchmove", handler).un("touchend", handler)
            .un("touchcancel", handler);
      }
   });
})(h5);

/**
 * Swipe event
 */
(function($, undefn) {
   var undef = undefn, state = {};

   /**
    * Calculate the delta difference between two points (x1,y1) and (x2,y2)
    * @return A delta object {x: xdelta, y: ydelta} if the difference is more
    * than 30 pixels or null if its less. The values x and y can be -ve
    */
   function getMovement(x1, y1, x2, y2) {
      var dx = x1 - x2, dy = y1 - y2, xa, ya;
      if((xa = Math.abs(dx)) < 30 & (ya = Math.abs(dy)) < 30) {
         return null;
      }
      return {
         x: dx,
         y: dy,
         dir: xa >= ya ? (dx < 0 ? "left" : "right") : (dy < 0 ? "up" : "down")
      };
   }

   function clearState() {
      state.id = state.x = state.y = state.movement = undef;
   }

   function handler(te) {
      var type = te.type, touches = te.touches, touch, target, m, evtData;

      switch(type) {
         case "touchstart":
            touches = te.touches;
            if(touches.length > 1) {
               return;
            }
            touch = touches[0];
            state.id = touch.identifier;
            state.x = touch.pageX;
            state.y = touch.pageY;
            break;
         case "touchmove":
            touches = te.changedTouches;
            touch = touches[0];
            if(touch.identifier === state.id && te.touches.length === 1) {
               state.movement = getMovement(touch.pageX, touch.pageY, state.x, state.y);
            }
            break;
         case "touchend":
            touches = te.changedTouches;
            touch = touches[0];
            if(state.id === touch.identifier && (m = state.movement)) {
               evtData = {movement: m};
               $(te.target).dispatch("swipe", evtData);
               clearState();
            }
            break;
         default:
            clearState();
            break;
      }
   }

   $.defineEvent({
      type: "swipe",
      setup: function() {
         $(document).on("touchstart", handler).on("touchmove", handler).on("touchend", handler)
            .on("touchcancel", handler);
      },
      destroy: function() {
         $(document).un("touchstart", handler).un("touchmove", handler).un("touchend", handler)
            .un("touchcancel", handler);
      }
   });
})(h5);
<commit_msg>Renamed all touch event listener functions to 'handler'<commit_after>/**
 * Defines custom events for touch related gusters.
 * Following events are defined:
 * tap, dbltap, taphold, swipe, swipeleft, swiperight
 * @author aniketn3@gmail.com
 */
/**
 * Tap event definition
 */
(function($, undefn) {
   var undef = undefn, state = {/* id, x, y, target */};

   function clearState() {
      state.id = state.x = state.y = state.moved = state.target = undef;
   }

   function hasMoved(x1, y1, x2, y2) {
      var dx = x1 - x2, dy = y1 - y2;
      return Math.abs(dx) > 30 || Math.abs(dy) > 30;
   }

   function handler(te) {
      var type = te.type, touch, touches = te.touches, cTouches = te.changedTouches, target = te.target;
      switch(type) {
         case "touchstart":
            if(touches.length !== 1) {
               return;
            }
            touch = touches[0];
            state.id = touch.identifier;
            state.x = touch.pageX;
            state.y = touch.pageY;
            state.target = target;
            break;
         case "touchmove":
            touch = cTouches[0];
            if(!state.moved && touch.identifier === state.id) {
               state.moved = hasMoved(state.x, state.y, touch.pageX, touch.pageY);
            }
            break;
         case "touchend":
            if(cTouches.length === 0 || state.moved) {
               clearState();
               return;
            }
            touch = cTouches[0];
            if(touch.identifier === state.id &&
                  !hasMoved(state.x, state.y, touch.pageX, touch.pageY) &&
                  state.target === target) {
               $(target).dispatch("tap");
            }
            break;
         case "touchcancel":
            clearState();
            break;
      }
   }

   $.defineEvent({
      type: "tap",
      setup: function() {
         $(document).on("touchstart", handler).on("touchmove", handler)
            .on("touchend", handler).on("touchcancel", handler);
      },
      destroy: function() {
         $(document).un("touchstart", handler).un("touchmove", handler)
            .un("touchend", handler).un("touchcancel", handler);
      }
   });
})(h5);

/**
 * Double Tap event definition
 */
(function($) {
   var state = {/* last, target */};

   function handler(te) {
      var now = Date.now(), elapsed = now - (state.last || now), target = te.target;
      if(elapsed > 0 && elapsed < 300 && state.target === target) {
         $(target).dispatch("dbltap");
         state.last = state.target = null;
      }else {
         state.last = now;
         state.target = te.target;
      }
   }

   $.defineEvent({
      type: "dbltap",
      setup: function() {
         $(document).on("tap", handler);
      },
      destroy: function() {
         $(document).un("tap", handler);
      }
   });
})(h5);

/**
 * Tap hold event
 */
(function($, undefn) {
      var undef = undefn, state = {/* moved, x, y */}, timer;

   function hasMoved(x1, y1, x2, y2) {
      var dx = x1 - x2, dy = y1 - y2;
      return Math.abs(dx) > 30 || Math.abs(dy) > 30;
   }

   function clearState() {
      state.moved = state.x = state.y = undef;
   }

   function handler(te) {
      var type = te.type, target = te.target;
      switch(type) {
         case "touchstart":
            if(te.touches.length !== 1) {
               return;
            }
            state.x = te.pageX;
            state.y = te.pageY;
            timer = setTimeout(function() {
               if(!state.moved) {
                  $(target).dispatch("taphold");
               }
            }, 700);
            break;
         case "touchmove":
            if(!state.moved) {
               state.moved = hasMoved(state.x, state.y, te.pageX, te.pageY);
            }
            break;
         case "touchend":
         case "touchcancel":
         default:
            clearTimeout(timer);
            clearState();
            break;
      }
   }

   $.defineEvent({
      type: "taphold",
      setup: function() {
         $(document).on("touchstart", handler).on("touchmove", handler).on("touchend", handler)
            .on("touchcancel", handler);
      },
      destroy: function() {
         $(document).un("touchstart", handler).un("touchmove", handler).un("touchend", handler)
            .un("touchcancel", handler);
      }
   });
})(h5);

/**
 * Swipe event
 */
(function($, undefn) {
   var undef = undefn, state = {};

   /**
    * Calculate the delta difference between two points (x1,y1) and (x2,y2)
    * @return A delta object {x: xdelta, y: ydelta} if the difference is more
    * than 30 pixels or null if its less. The values x and y can be -ve
    */
   function getMovement(x1, y1, x2, y2) {
      var dx = x1 - x2, dy = y1 - y2, xa, ya;
      if((xa = Math.abs(dx)) < 30 & (ya = Math.abs(dy)) < 30) {
         return null;
      }
      return {
         x: dx,
         y: dy,
         dir: xa >= ya ? (dx < 0 ? "left" : "right") : (dy < 0 ? "up" : "down")
      };
   }

   function clearState() {
      state.id = state.x = state.y = state.movement = undef;
   }

   function handler(te) {
      var type = te.type, touches = te.touches, touch, target, m, evtData;

      switch(type) {
         case "touchstart":
            touches = te.touches;
            if(touches.length > 1) {
               return;
            }
            touch = touches[0];
            state.id = touch.identifier;
            state.x = touch.pageX;
            state.y = touch.pageY;
            break;
         case "touchmove":
            touches = te.changedTouches;
            touch = touches[0];
            if(touch.identifier === state.id && te.touches.length === 1) {
               state.movement = getMovement(touch.pageX, touch.pageY, state.x, state.y);
            }
            break;
         case "touchend":
            touches = te.changedTouches;
            touch = touches[0];
            if(state.id === touch.identifier && (m = state.movement)) {
               evtData = {movement: m};
               $(te.target).dispatch("swipe", evtData);
               clearState();
            }
            break;
         default:
            clearState();
            break;
      }
   }

   $.defineEvent({
      type: "swipe",
      setup: function() {
         $(document).on("touchstart", handler).on("touchmove", handler).on("touchend", handler)
            .on("touchcancel", handler);
      },
      destroy: function() {
         $(document).un("touchstart", handler).un("touchmove", handler).un("touchend", handler)
            .un("touchcancel", handler);
      }
   });
})(h5);

<|endoftext|>


<commit_before>import Resources from './resources';

/**
 *
 * @param apiHandler
 * @returns {Object}
 */
export default function createApiInstance({apiHandler}) {
    return {
        account: new Resources.AccountsResource({apiHandler}),
        apiKeys: new Resources.ApiKeysResource({apiHandler}),
        bankAccounts: new Resources.BankAccountsResource({apiHandler}),
        blacklists: new Resources.BlacklistsResource({apiHandler}),
        checkoutPages: new Resources.CheckoutPagesResource({apiHandler}),
        coupons: new Resources.CouponsResource({apiHandler}),
        customers: new Resources.CustomersResource({apiHandler}),
        customerAuthentication: new Resources.CustomerAuthenticationResource({apiHandler}),
        customEvents: new Resources.CustomEventsResource({apiHandler}),
        customFields: new Resources.CustomFieldsResource({apiHandler}),
        credentialHashes: new Resources.CredentialHashesResource({apiHandler}),
        disputes: new Resources.DisputesResource({apiHandler}),
        events: new Resources.EventsResource({apiHandler}),
        files: new Resources.FilesResource({apiHandler}),
        gatewayAccounts: new Resources.GatewayAccountsResource({apiHandler}),
        invoices: new Resources.InvoicesResource({apiHandler}),
        layouts: new Resources.LayoutsResource({apiHandler}),
        lists: new Resources.ListsResource({apiHandler}),
        notes: new Resources.NotesResource({apiHandler}),
        organizations: new Resources.OrganizationsResource({apiHandler}),
        paymentCards: new Resources.PaymentCardsResource({apiHandler}),
        paymentTokens: new Resources.PaymentTokensResource({apiHandler}),
        paypalAccounts: new Resources.PayPalAccountsResource({apiHandler}),
        plans: new Resources.PlansResource({apiHandler}),
        previews: new Resources.PreviewsResource({apiHandler}),
        products: new Resources.ProductsResource({apiHandler}),
        profile: new Resources.ProfileResource({apiHandler}),
        sessions: new Resources.SessionsResource({apiHandler}),
        shippingZones: new Resources.ShippingZonesResource({apiHandler}),
        status: new Resources.StatusResource({apiHandler}),
        subscriptions: new Resources.SubscriptionsResource({apiHandler}),
        tracking: new Resources.TrackingResource({apiHandler}),
        transactions: new Resources.TransactionsResource({apiHandler}),
        threeDSecure: new Resources.ThreeDSecureResource({apiHandler}),
        users: new Resources.UsersResource({apiHandler}),
        webhooks: new Resources.WebhooksResource({apiHandler}),
        websites: new Resources.WebsitesResource({apiHandler}),

        //expose apiHandler methods to the API instance
        addRequestInterceptor: apiHandler.addRequestInterceptor,
        removeRequestInterceptor: apiHandler.removeRequestInterceptor,
        addResponseInterceptor: apiHandler.addResponseInterceptor,
        removeResponseInterceptor: apiHandler.removeResponseInterceptor,
        setTimeout: apiHandler.setTimeout,
        setProxyAgent: apiHandler.setProxyAgent,
        setSessionToken: apiHandler.setSessionToken,
        setApiConsumer: apiHandler.setApiConsumer,
        setEndpoints: apiHandler.setEndpoints,
        getCancellationToken: apiHandler.getCancellationToken
    };
}
<commit_msg>remove 'new' key word<commit_after>import Resources from './resources';

/**
 *
 * @param apiHandler
 * @returns {Object}
 */
export default function createApiInstance({apiHandler}) {
    return {
        account: Resources.AccountsResource({apiHandler}),
        apiKeys: Resources.ApiKeysResource({apiHandler}),
        bankAccounts: Resources.BankAccountsResource({apiHandler}),
        blacklists: Resources.BlacklistsResource({apiHandler}),
        checkoutPages: Resources.CheckoutPagesResource({apiHandler}),
        coupons: Resources.CouponsResource({apiHandler}),
        customers: Resources.CustomersResource({apiHandler}),
        customerAuthentication: Resources.CustomerAuthenticationResource({apiHandler}),
        customEvents: Resources.CustomEventsResource({apiHandler}),
        customFields: Resources.CustomFieldsResource({apiHandler}),
        credentialHashes: Resources.CredentialHashesResource({apiHandler}),
        disputes: Resources.DisputesResource({apiHandler}),
        events: Resources.EventsResource({apiHandler}),
        files: Resources.FilesResource({apiHandler}),
        gatewayAccounts: Resources.GatewayAccountsResource({apiHandler}),
        invoices:  Resources.InvoicesResource({apiHandler}),
        layouts: Resources.LayoutsResource({apiHandler}),
        lists: Resources.ListsResource({apiHandler}),
        notes: Resources.NotesResource({apiHandler}),
        organizations: Resources.OrganizationsResource({apiHandler}),
        paymentCards: Resources.PaymentCardsResource({apiHandler}),
        paymentTokens: Resources.PaymentTokensResource({apiHandler}),
        paypalAccounts: Resources.PayPalAccountsResource({apiHandler}),
        plans: Resources.PlansResource({apiHandler}),
        previews: Resources.PreviewsResource({apiHandler}),
        products: Resources.ProductsResource({apiHandler}),
        profile: Resources.ProfileResource({apiHandler}),
        sessions: Resources.SessionsResource({apiHandler}),
        shippingZones: Resources.ShippingZonesResource({apiHandler}),
        status: Resources.StatusResource({apiHandler}),
        subscriptions: Resources.SubscriptionsResource({apiHandler}),
        tracking: Resources.TrackingResource({apiHandler}),
        transactions: Resources.TransactionsResource({apiHandler}),
        threeDSecure: Resources.ThreeDSecureResource({apiHandler}),
        users: Resources.UsersResource({apiHandler}),
        webhooks: Resources.WebhooksResource({apiHandler}),
        websites: Resources.WebsitesResource({apiHandler}),

        //expose apiHandler methods to the API instance
        addRequestInterceptor: apiHandler.addRequestInterceptor,
        removeRequestInterceptor: apiHandler.removeRequestInterceptor,
        addResponseInterceptor: apiHandler.addResponseInterceptor,
        removeResponseInterceptor: apiHandler.removeResponseInterceptor,
        setTimeout: apiHandler.setTimeout,
        setProxyAgent: apiHandler.setProxyAgent,
        setSessionToken: apiHandler.setSessionToken,
        setApiConsumer: apiHandler.setApiConsumer,
        setEndpoints: apiHandler.setEndpoints,
        getCancellationToken: apiHandler.getCancellationToken
    };
}
<|endoftext|>


<commit_before>(function(Factlink, $, _, easyXDM, window, undefined) {

$.ajax({
  url: FactlinkConfig.api + '/templates/indicator',
  dataType: 'jsonp',
  crossDomain: true,
  type: 'GET',
  jsonp: 'callback',
  success: function(data) {
    Factlink.tmpl.indicator = _.template(data);

    Factlink.el.trigger('factlink.tmpl.indicator');
  }
});

$.ajax({
  url: FactlinkConfig.api + '/templates/_channel_li',
  dataType: 'jsonp',
  crossDomain: true,
  type: 'GET',
  jsonp: 'callback',
  success: function(data) {
    Factlink.tmpl.channel_li = _.template(data);

    Factlink.el.trigger('factlink.tmpl.channel_li');
  }
});

Factlink.getTemplate = function(str, callback) {
  if ( Factlink.tmpl[str] !== undefined ) {
    callback(Factlink.tmpl[str]);
  } else {
    Factlink.el.bind('factlink.tmpl.' + str, function() {
      callback(Factlink.tmpl[str]);
    });
  }
};

$.ajax({
  url: FactlinkConfig.api + '/templates/' + ( FactlinkConfig.modus === "default" ? "create" : "addToFact" ) + ".html",
  dataType: 'jsonp',
  crossDomain: true,
  type: 'GET',
  jsonp: 'callback',
  success: function( data ) {
    Factlink.prepare = new Factlink.Prepare(_.template(data));
  }
});

})(window.Factlink, Factlink.$, Factlink._, Factlink.easyXDM, Factlink.global);
<commit_msg>simplified template retrieval<commit_after>(function(Factlink, $, _, easyXDM, window, undefined) {

var requesting = {};

Factlink.getTemplate = function(str, callback) {
  if ( Factlink.tmpl[str] !== undefined ) {
    callback(Factlink.tmpl[str]);
  } else {
    Factlink.el.bind('factlink.tmpl.' + str, function() {
      if (callback) { callback(Factlink.tmpl[str]); }
    });
    if (! requesting[str] ){
      requesting[str] = true;
      $.ajax({
        url: FactlinkConfig.api + '/templates/'+str,
        dataType: 'jsonp',
        crossDomain: true,
        type: 'GET',
        jsonp: 'callback',
        success: function(data) {
          Factlink.tmpl[str] = _.template(data);
          Factlink.el.trigger('factlink.tmpl.'+str);
        }
      });
    }
  }
};

Factlink.getTemplate('indicator');
Factlink.getTemplate('create',function(template){
  Factlink.prepare = new Factlink.Prepare(template);
});

})(window.Factlink, Factlink.$, Factlink._, Factlink.easyXDM, Factlink.global);
<|endoftext|>


<commit_before>/**
 * Created by Dean on 6/22/2015.
 */

var QUESTIFY = (function (QUESTIFY) {
	"use strict";
	function createCompoundAction (preCondition, postCondition, subActions) {
		var that = QUESTIFY.createAtomicAction(preCondition, postCondition);

		that.subActions = subActions;

		that.isFinished = function() {
			if (!(that.finished === true)) { return false; }
			for (var a = 0, al = subActions.length; a < al; a++) {
				if (!subActions[a].isFinished()) {
					return false;
				}
			}
			return true;
		};

		that.withArguments = function(pre, post) {
			var newValue = {};
			newValue.preCondition = this.preCondition;
			newValue.postCondition = this.postCondition;
			newValue.preConditionMet = this.preConditionMet;
			newValue.postConditionMet = this.postConditionMet;
			newValue.start = this.start;
			newValue.finish = this.finish;
			newValue.isStarted = this.isStarted;
			newValue.isFinished = this.isFinished;
			newValue.started = false;
			newValue.finished = false;

			newValue.preConditionArguments = pre;
			newValue.postConditionArguments = post;

			newValue.subActions = this.subActions;

			return newValue;
		};

		return that;
	}

	QUESTIFY.createCompoundAction = createCompoundAction;

	return QUESTIFY;
}(QUESTIFY || {}));<commit_msg>Renamed subActions to actions<commit_after>/**
 * Created by Dean on 6/22/2015.
 */

var QUESTIFY = (function (QUESTIFY) {
	"use strict";
	function createCompoundAction (preCondition, postCondition, subActions) {
		var that = QUESTIFY.createAtomicAction(preCondition, postCondition);

		that.actions = actions;

		that.isFinished = function() {
			if (!(that.finished === true)) { return false; }
			for (var a = 0, al = subActions.length; a < al; a++) {
				if (!subActions[a].isFinished()) {
					return false;
				}
			}
			return true;
		};

		that.withArguments = function(pre, post) {
			var newValue = {};
			newValue.preCondition = this.preCondition;
			newValue.postCondition = this.postCondition;
			newValue.preConditionMet = this.preConditionMet;
			newValue.postConditionMet = this.postConditionMet;
			newValue.start = this.start;
			newValue.finish = this.finish;
			newValue.isStarted = this.isStarted;
			newValue.isFinished = this.isFinished;
			newValue.started = false;
			newValue.finished = false;

			newValue.preConditionArguments = pre;
			newValue.postConditionArguments = post;

			newValue.actions = this.actions;

			return newValue;
		};

		return that;
	}

	QUESTIFY.createCompoundAction = createCompoundAction;

	return QUESTIFY;
}(QUESTIFY || {}));<|endoftext|>


<commit_before>(function (clique, Backbone, _, d3, cola) {
    "use strict";

    var fill = function (d) {
        if (d.key === this.focused) {
            return "crimson";
        } else if (d.root) {
            return "gold";
        } else {
            return "limegreen";
        }
    };

    clique.view.Cola = Backbone.View.extend({
        initialize: function (options) {
            clique.util.require(this.model, "model");
            clique.util.require(this.el, "el");

            options = options || {};

            this.nodeRadius = options.nodeRadius || 7.5;

            this.transitionTime = 500;

            this.cola = cola.d3adaptor()
                .linkDistance(options.linkDistance || 100)
                .avoidOverlaps(true)
                .size([this.$el.width(), this.$el.height()])
                .start();

            this.selection = new clique.model.Selection();

            this.$el.html(clique.template.cola());
            this.listenTo(this.model, "change", _.debounce(this.render, 100));
            this.listenTo(this.selection, "focused", function (focused) {
                this.focused = focused;
                this.nodes.style("fill", _.bind(fill, this));
            });
        },

        render: function () {
            var nodeData = this.model.get("nodes"),
                linkData = this.model.get("links"),
                drag,
                me = d3.select(this.el),
                that = this;

            this.cola
                .nodes(nodeData)
                .links(linkData);

            this.nodes = me.select("g.nodes")
                .selectAll("circle.node")
                .data(nodeData, _.property("key"));

            drag = this.cola.drag()
                .on("drag", _.bind(function () {
                    this.dragging = true;
                }, this));

            this.nodes.datum(function (d) {
                d.fixed = true;
                return d;
            });

            this.nodes.enter()
                .append("circle")
                .classed("node", true)
                .attr("r", 0)
                .style("fill", "limegreen")
                .on("mousedown.signal", _.bind(function () {
                    d3.event.stopPropagation();
                }, this))
                .on("click", function (d) {
                    var me = d3.select(this),
                        selected;

                    if (!that.dragging) {
                        if (d3.event.shiftKey) {
                            // If the shift key is pressed, then simply toggle
                            // the presence of the clicked node in the current
                            // selection.
                            selected = !me.classed("selected");
                        } else if (d3.event.ctrlKey) {
                            // If the control key is pressed, then move the
                            // focus to the clicked node, adding it to the
                            // selection first if necessary.
                            if (!me.classed("selected")) {
                                me.classed("selected", true);
                                that.selection.add(d.key);
                            }

                            that.selection.focusKey(d.key);
                            return;
                        } else {
                            // If the shift key isn't pressed, then clear the
                            // selection before doing anything else.
                            _.each(that.selection.items(), function (key) {
                                that.selection.remove(key);
                            });

                            d3.select(that.el)
                                .selectAll("circle.node")
                                .classed("selected", false);
                            selected = true;
                        }

                        me.classed("selected", selected);

                        if (selected) {
                            that.selection.add(d.key);
                        } else {
                            that.selection.remove(d.key);
                        }
                    }
                    that.dragging = false;
                })
                .call(drag)
                .transition()
                .duration(this.transitionTime)
                .attr("r", this.nodeRadius);

            this.nodes.style("fill", _.bind(fill, this));

            this.nodes.exit()
                .each(_.bind(function (d) {
                    this.selection.remove(d.key);
                }, this))
                .transition()
                .duration(this.transitionTime)
                .attr("r", 0)
                .style("opacity", 0)
                .remove();

            this.links = me.select("g.links")
                .selectAll("line.link")
                .data(linkData, function (d) {
                    return JSON.stringify([d.source.key, d.target.key]);
                });

            this.links.enter()
                .append("line")
                .classed("link", true)
                .style("stroke-width", 0)
                .style("stroke", "black")
                .transition()
                .duration(this.transitionTime)
                .style("stroke-width", 1);

            this.links.exit()
                .transition()
                .duration(this.transitionTime)
                .style("stroke-width", 0)
                .style("opacity", 0)
                .remove();

            this.cola.on("tick", _.bind(function () {
                var width = this.$el.width(),
                    height = this.$el.height(),
                    clamp = function (value, low, high) {
                        return value < low ? low : (value > high ? high : value);
                    },
                    clampX = _.partial(clamp, _, this.nodeRadius, width - this.nodeRadius),
                    clampY = _.partial(clamp, _, this.nodeRadius, height - this.nodeRadius);

                this.nodes
                    .attr("cx", _.compose(clampX, _.property("x")))
                    .attr("cy", _.compose(clampY, _.property("y")));

                this.links
                    .attr("x1", _.compose(clampX, function (d) {
                        return d.source.x;
                    }))
                    .attr("y1", _.compose(clampY, function (d) {
                        return d.source.y;
                    }))
                    .attr("x2", _.compose(clampX, function (d) {
                        return d.target.x;
                    }))
                    .attr("y2", _.compose(clampY, function (d) {
                        return d.target.y;
                    }));
            }, this));

            // Attach some selection actions to the background.
            (function () {
                var dragging = false,
                    active = false,
                    shift = false,
                    origin,
                    selector,
                    start = {
                        x: null,
                        y: null
                    },
                    endBrush,
                    between = function (val, low, high) {
                        var tmp;

                        if (low > high) {
                            tmp = high;
                            high = low;
                            low = tmp;
                        }

                        return low < val && val < high;
                    };

                me.on("mousedown", function () {
                    active = true;
                    dragging = false;

                    shift = d3.event.shiftKey;

                    origin = that.$el.offset();

                    start.x = d3.event.pageX - origin.left;
                    start.y = d3.event.pageY - origin.top;

                    // Record whether the nodes were selected or not at the time
                    // of the action (if shift is pressed) - this allows for the
                    // current selection to be "sticky" for this operation.
                    that.nodes.datum(function (d) {
                        d.keep = shift && d3.select(this).classed("selected");
                        return d;
                    });
                });

                me.on("mousemove", function () {
                    var x,
                        y;

                    if (!active) {
                        return;
                    }

                    if (!dragging) {
                        dragging = true;

                        // Instantiate an SVG rect to act as the selector range.
                        selector = me.append("rect")
                            .classed("selector", true)
                            .attr("x", start.x)
                            .attr("y", start.y)
                            .attr("width", 0)
                            .attr("height", 0)
                            .style("opacity", 0.1)
                            .style("fill", "black");
                    }

                    x = d3.event.pageX - origin.left;
                    y = d3.event.pageY - origin.top;

                    // Resize the rect to reflect the current mouse position
                    if (x > start.x) {
                        selector.attr("width", x - start.x);
                    } else {
                        selector.attr("width", start.x - x)
                            .attr("x", x);
                    }

                    if (y > start.y) {
                        selector.attr("height", y - start.y);
                    } else {
                        selector.attr("height", start.y - y)
                            .attr("y", y);
                    }

                    // Compute which nodes are inside the rect
                    _.each(that.model.get("nodes"), function (node) {
                        node.selected = node.keep || between(node.x, start.x, x) && between(node.y, start.y, y);

                        if (node.selected) {
                            that.selection.add(node.key);
                        } else if (!shift) {
                            that.selection.remove(node.key);
                        }
                    });

                    // Update the view.
                    that.nodes
                        .classed("selected", _.property("selected"))
                        .style("fill", _.bind(fill, that));
                });

                endBrush = function () {
                    if (dragging) {
                        me.selectAll(".selector")
                            .remove();
                        selector = null;
                    } else if (active) {
                        // If this was merely a click (no dragging), then also
                        // unselect everything.
                        _.each(that.model.get("nodes"), function (node) {
                            that.selection.remove(node.key);
                        });

                        // Update the view.
                        that.nodes
                            .classed("selected", function () {
                                return shift ? d3.select(this).classed("selected") : false;
                            })
                            .style("fill", _.bind(fill, that));
                    }

                    dragging = false;
                    active = false;
                };

                // On mouseup, regardless of where the mouse is (as taken care
                // of by the second handler below), go ahead and terminate the
                // brushing movement.
                me.on("mouseup", endBrush);
                d3.select(document)
                    .on("mouseup", endBrush);
            }());

            this.cola.start();

            _.delay( _.bind(function () {
                this.nodes.datum(function (d) {
                    d.fixed = false;
                    return d;
                });
            }, this), this.transitionTime + 5);
        }
    });
}(window.clique, window.Backbone, window._, window.d3, window.cola));
<commit_msg>Changing brush-select to invert the selected property on its selection (rather than add unconditionally)<commit_after>(function (clique, Backbone, _, d3, cola) {
    "use strict";

    var fill = function (d) {
        if (d.key === this.focused) {
            return "crimson";
        } else if (d.root) {
            return "gold";
        } else {
            return "limegreen";
        }
    };

    clique.view.Cola = Backbone.View.extend({
        initialize: function (options) {
            clique.util.require(this.model, "model");
            clique.util.require(this.el, "el");

            options = options || {};

            this.nodeRadius = options.nodeRadius || 7.5;

            this.transitionTime = 500;

            this.cola = cola.d3adaptor()
                .linkDistance(options.linkDistance || 100)
                .avoidOverlaps(true)
                .size([this.$el.width(), this.$el.height()])
                .start();

            this.selection = new clique.model.Selection();

            this.$el.html(clique.template.cola());
            this.listenTo(this.model, "change", _.debounce(this.render, 100));
            this.listenTo(this.selection, "focused", function (focused) {
                this.focused = focused;
                this.nodes.style("fill", _.bind(fill, this));
            });
        },

        render: function () {
            var nodeData = this.model.get("nodes"),
                linkData = this.model.get("links"),
                drag,
                me = d3.select(this.el),
                that = this;

            this.cola
                .nodes(nodeData)
                .links(linkData);

            this.nodes = me.select("g.nodes")
                .selectAll("circle.node")
                .data(nodeData, _.property("key"));

            drag = this.cola.drag()
                .on("drag", _.bind(function () {
                    this.dragging = true;
                }, this));

            this.nodes.datum(function (d) {
                d.fixed = true;
                return d;
            });

            this.nodes.enter()
                .append("circle")
                .classed("node", true)
                .attr("r", 0)
                .style("fill", "limegreen")
                .on("mousedown.signal", _.bind(function () {
                    d3.event.stopPropagation();
                }, this))
                .on("click", function (d) {
                    var me = d3.select(this),
                        selected;

                    if (!that.dragging) {
                        if (d3.event.shiftKey) {
                            // If the shift key is pressed, then simply toggle
                            // the presence of the clicked node in the current
                            // selection.
                            selected = !me.classed("selected");
                        } else if (d3.event.ctrlKey) {
                            // If the control key is pressed, then move the
                            // focus to the clicked node, adding it to the
                            // selection first if necessary.
                            if (!me.classed("selected")) {
                                me.classed("selected", true);
                                that.selection.add(d.key);
                            }

                            that.selection.focusKey(d.key);
                            return;
                        } else {
                            // If the shift key isn't pressed, then clear the
                            // selection before doing anything else.
                            _.each(that.selection.items(), function (key) {
                                that.selection.remove(key);
                            });

                            d3.select(that.el)
                                .selectAll("circle.node")
                                .classed("selected", false);
                            selected = true;
                        }

                        me.classed("selected", selected);

                        if (selected) {
                            that.selection.add(d.key);
                        } else {
                            that.selection.remove(d.key);
                        }
                    }
                    that.dragging = false;
                })
                .call(drag)
                .transition()
                .duration(this.transitionTime)
                .attr("r", this.nodeRadius);

            this.nodes.style("fill", _.bind(fill, this));

            this.nodes.exit()
                .each(_.bind(function (d) {
                    this.selection.remove(d.key);
                }, this))
                .transition()
                .duration(this.transitionTime)
                .attr("r", 0)
                .style("opacity", 0)
                .remove();

            this.links = me.select("g.links")
                .selectAll("line.link")
                .data(linkData, function (d) {
                    return JSON.stringify([d.source.key, d.target.key]);
                });

            this.links.enter()
                .append("line")
                .classed("link", true)
                .style("stroke-width", 0)
                .style("stroke", "black")
                .transition()
                .duration(this.transitionTime)
                .style("stroke-width", 1);

            this.links.exit()
                .transition()
                .duration(this.transitionTime)
                .style("stroke-width", 0)
                .style("opacity", 0)
                .remove();

            this.cola.on("tick", _.bind(function () {
                var width = this.$el.width(),
                    height = this.$el.height(),
                    clamp = function (value, low, high) {
                        return value < low ? low : (value > high ? high : value);
                    },
                    clampX = _.partial(clamp, _, this.nodeRadius, width - this.nodeRadius),
                    clampY = _.partial(clamp, _, this.nodeRadius, height - this.nodeRadius);

                this.nodes
                    .attr("cx", _.compose(clampX, _.property("x")))
                    .attr("cy", _.compose(clampY, _.property("y")));

                this.links
                    .attr("x1", _.compose(clampX, function (d) {
                        return d.source.x;
                    }))
                    .attr("y1", _.compose(clampY, function (d) {
                        return d.source.y;
                    }))
                    .attr("x2", _.compose(clampX, function (d) {
                        return d.target.x;
                    }))
                    .attr("y2", _.compose(clampY, function (d) {
                        return d.target.y;
                    }));
            }, this));

            // Attach some selection actions to the background.
            (function () {
                var dragging = false,
                    active = false,
                    shift = false,
                    origin,
                    selector,
                    start = {
                        x: null,
                        y: null
                    },
                    endBrush,
                    between = function (val, low, high) {
                        var tmp;

                        if (low > high) {
                            tmp = high;
                            high = low;
                            low = tmp;
                        }

                        return low < val && val < high;
                    };

                me.on("mousedown", function () {
                    active = true;
                    dragging = false;

                    shift = d3.event.shiftKey;

                    origin = that.$el.offset();

                    start.x = d3.event.pageX - origin.left;
                    start.y = d3.event.pageY - origin.top;

                    // Record whether the nodes were selected or not at the time
                    // of the action (if shift is pressed) - this allows for the
                    // current selection to be "sticky" for this operation.
                    if (shift) {
                        that.nodes.datum(function (d) {
                            d.orig = d3.select(this).classed("selected");
                            return d;
                        });
                    }
                });

                me.on("mousemove", function () {
                    var x,
                        y;

                    if (!active) {
                        return;
                    }

                    if (!dragging) {
                        dragging = true;

                        // Instantiate an SVG rect to act as the selector range.
                        selector = me.append("rect")
                            .classed("selector", true)
                            .attr("x", start.x)
                            .attr("y", start.y)
                            .attr("width", 0)
                            .attr("height", 0)
                            .style("opacity", 0.1)
                            .style("fill", "black");
                    }

                    x = d3.event.pageX - origin.left;
                    y = d3.event.pageY - origin.top;

                    // Resize the rect to reflect the current mouse position
                    if (x > start.x) {
                        selector.attr("width", x - start.x);
                    } else {
                        selector.attr("width", start.x - x)
                            .attr("x", x);
                    }

                    if (y > start.y) {
                        selector.attr("height", y - start.y);
                    } else {
                        selector.attr("height", start.y - y)
                            .attr("y", y);
                    }

                    // Compute which nodes are inside the rect
                    _.each(that.model.get("nodes"), function (node) {
                        var inside = between(node.x, start.x, x) && between(node.y, start.y, y);

                        if (shift) {
                            // If shift-brushing, then invert the selection
                            // state from the original.
                            node.selected = inside ? !node.orig : node.orig;
                        } else {
                            // If brushing (no shift pressed), then select
                            // everything inside the box and deselect everything
                            // outside.
                            node.selected = inside;
                        }

                        if (node.selected) {
                            that.selection.add(node.key);
                        } else if (!shift) {
                            that.selection.remove(node.key);
                        }
                    });

                    // Update the view.
                    that.nodes
                        .classed("selected", _.property("selected"))
                        .style("fill", _.bind(fill, that));
                });

                endBrush = function () {
                    if (dragging) {
                        me.selectAll(".selector")
                            .remove();
                        selector = null;
                    } else if (active) {
                        // If this was merely a click (no dragging), then also
                        // unselect everything.
                        _.each(that.model.get("nodes"), function (node) {
                            that.selection.remove(node.key);
                        });

                        // Update the view.
                        that.nodes
                            .classed("selected", function () {
                                return shift ? d3.select(this).classed("selected") : false;
                            })
                            .style("fill", _.bind(fill, that));
                    }

                    dragging = false;
                    active = false;
                };

                // On mouseup, regardless of where the mouse is (as taken care
                // of by the second handler below), go ahead and terminate the
                // brushing movement.
                me.on("mouseup", endBrush);
                d3.select(document)
                    .on("mouseup", endBrush);
            }());

            this.cola.start();

            _.delay( _.bind(function () {
                this.nodes.datum(function (d) {
                    d.fixed = false;
                    return d;
                });
            }, this), this.transitionTime + 5);
        }
    });
}(window.clique, window.Backbone, window._, window.d3, window.cola));
<|endoftext|>


<commit_before>
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt

cur_frm.fields_dict['sample_no'].get_query=function(doc,cdt,cdn)
{
	return{
		query:"test.doctype.sample_allocation.sample_allocation.get_sample_no",
	}
}

cur_frm.fields_dict.test_name.get_query = function(doc, cdt, cdn){
	return{
		query:"test.doctype.sample_allocation.sample_allocation.get_test_name",
		filters:{'sample_allocation_id': doc.sample_allocation_lab}
	}
}

//Add selected test to the sample allocation table iff that test is allocated in sample allocation to lab
cur_frm.cscript.add_test = function(doc,cdt,cdn){
	if (doc.test_name && doc.sample_allocation_lab){
		get_server_fields('get_sample_no','','',doc,cdt,cdn,1,function(r,rt){refresh_field('sample_allocation_detail')});

	}
	else
		msgprint("To add entries in the child table both the fields,Test Name & Sample Allocation To Lab Name must be specify");
}

cur_frm.cscript.sample_no = function(doc,cdt,cdn){
	if(doc.sample_no){
		get_server_fields('get_sample_details',doc.sample_no,'',doc,cdt,cdn,1,function(r,rt){refresh_field('sample_allocation_detail')});
		refresh_field('s_priority');
		refresh_field('bottle_no');
		refresh_field('test_group');
	}

}
<commit_msg>[sample generation]<commit_after>
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt

cur_frm.fields_dict['sample_no'].get_query=function(doc,cdt,cdn)
{
	return{
		query:"test.doctype.sample_allocation.sample_allocation.get_sample_no",
	}
}

cur_frm.fields_dict.test_name.get_query = function(doc, cdt, cdn){
	return{
		query:"test.doctype.sample_allocation.sample_allocation.get_test_name",
		filters:{'sample_allocation_id': doc.sample_allocation_lab}
	}
}

//Add selected test to the sample allocation table iff that test is allocated in sample allocation to lab
cur_frm.cscript.add_test = function(doc,cdt,cdn){
	if (doc.test_name && doc.sample_allocation_lab){
		get_server_fields('get_sample_no','','',doc,cdt,cdn,1,function(r,rt){refresh_field('sample_allocation_detail')});

	}
	else
		msgprint("To add entries in the child table both the fields,Test Name & Sample Allocation To Lab Name must be specify");
}

cur_frm.cscript.sample_no = function(doc,cdt,cdn){
	if(doc.sample_no){
		get_server_fields('get_sample_details',doc.sample_no,'',doc,cdt,cdn,1,function(r,rt){refresh_field('sample_allocation_detail')});
		refresh_field('s_priority');
		refresh_field('bottle_no');
		refresh_field('test_group');
	}

}
<|endoftext|>


<commit_before>/**
 * Mobile dropdowns
 * Toggles dropdowns using css class 'open' instead of pseudo class :hover
 * Usage:
 *

 *     ...
 *

 *
 * possible values for CONDITION
 * "touch"                        : use 'open'-class if device is touch-device AND media size is 'md' or 'lg'
 * "toggle-xs-sm-or-touch" : use 'open'-class if device is "touch" (as above) OR media size is 'xs' or 'sm'
 *
 */
(function( $, pm )
{
    // TODO: handle external dependency to Modernizr
    pm.directive( 'MobileDropdown', function( MediaSizeService )
    {
        var sizes                 = {xs: "xs", sm: "sm"};
        var toggleClass           = "open";
        var resizeOrTouchSelector = '.dropdown.open > a[data-plenty-enable="toggle-xs-sm-or-touch"]';
        var aTouchSelector        = '.dropdown.open > a[data-plenty-enable="touch"]';
        var activeDropdown        = null;

        if ( isIntervalNotFitting() )
        {
            $( aTouchSelector ).parent().removeClass( 'open' );
        }

        return {
            initMobileDropdown: initMobileDropdown,
            mobileMenu        : mobileMenu,
            openDropdown      : openDropdown
        };

        function initMobileDropdown()
        {
            $( window ).on( 'orientationchange', function()
            {
                if ( isFittingOrNotInterval() )
                {
                    $( resizeOrTouchSelector ).parent().removeClass( toggleClass );
                }

                if ( isIntervalNotFitting() )
                {
                    $( aTouchSelector ).parent().removeClass( toggleClass );
                }
            } );

            $( window ).on( 'sizeChange', function( newValue )
            {
                if ( newValue != sizes.xs && newValue != sizes.sm && !Modernizr.touch )
                {
                    $( resizeOrTouchSelector ).parent().removeClass( toggleClass );
                }
            } );
        }

        function openDropdown( elem, mediaSizes, touch )
        {
            var $elem = $( elem );
            var activeParent;

            if ( MediaSizeService.isInterval( mediaSizes )
                || (touch == "touch" && Modernizr.touch)
                || (!Modernizr.touch && touch != "touch") )
            {

                if ( activeDropdown )
                {
                    activeDropdown.parent().removeClass( toggleClass );
                }
                if ( !activeDropdown || activeDropdown[0] != $elem[0] )
                {
                    activeDropdown = $elem;
                    activeParent   = activeDropdown.parent();
                    if ( !activeParent.hasClass( toggleClass ) )
                    {
                        activeParent.addClass( toggleClass );
                    }
                }
            }
        }

        function mobileMenu( elem, condition )
        {
            var $elem       = $( elem );
            var $elemParent = $elem.parent();

            $( 'html' ).click( function()
            {
                $( resizeOrTouchSelector ).not( $elem ).parent().removeClass( toggleClass );
            } );

            if ( condition == "toggle-xs-sm-or-touch" )
            {
                $elem.click( function( e )
                {
                    if ( isFittingOrNotInterval() )
                    {
                        $( resizeOrTouchSelector ).not( $elem ).parent().removeClass( toggleClass );
                        $elemParent.toggleClass( toggleClass );
                        return false;
                    }
                } );
            }

            // dropdown enabled touch
            else if ( condition == "touch" )
            {
                $elem.click( function()
                {
                    if ( isIntervalNotFitting() )
                    { // otherwise already has mobile navigation
                        $( aTouchSelector ).not( $elem ).parent().removeClass( toggleClass );
                        $elemParent.addClass( toggleClass );
                        return false;
                    }
                } );
            }
        }

        pm.directive( '*', function( i, elem, MediaSizeService )
        {

            $( elem ).click( function( e )
            {
                if ( isFittingOrNotInterval() )
                {
                    var dropdown = $( resizeOrTouchSelector ).parent();
                    if ( dropdown.length > 0 && !dropdown.is( e.target ) && dropdown.has( e.target ).length <= 0 )
                    {
                        dropdown.removeClass( toggleClass );
                    }
                }

                if ( isIntervalNotFitting() )
                {
                    var dropdown = $( aTouchSelector ).parent();
                    if ( dropdown.length > 0 && !dropdown.is( e.target ) && dropdown.has( e.target ).length <= 0 )
                    {
                        dropdown.removeClass( toggleClass );
                    }
                }
            } );
        }, ['MediaSizeService'] );

        function isIntervalNotFitting()
        {
            return (!MediaSizeService.isInterval( "xs, sm" ) && Modernizr.touch);
        }

        function isFittingOrNotInterval()
        {
            return (MediaSizeService.isInterval( "xs, sm" ) || isIntervalNotFitting());
        }

    }, ['MediaSizeService'] );
}( jQuery, PlentyFramework ));<commit_msg>dropdown works 50%<commit_after>/**
 * Mobile dropdowns
 * Toggles dropdowns using css class 'open' instead of pseudo class :hover
 * Usage:
 *

 *     ...
 *

 *
 * possible values for CONDITION
 * "touch"                        : use 'open'-class if device is touch-device AND media size is 'md' or 'lg'
 * "toggle-xs-sm-or-touch" : use 'open'-class if device is "touch" (as above) OR media size is 'xs' or 'sm'
 *
 */
(function( $, pm )
{
    // TODO: handle external dependency to Modernizr
    pm.directive( 'MobileDropdown', function( MediaSizeService )
    {
        var sizes                 = {xs: "xs", sm: "sm"};
        var toggleClass           = "open";
        var resizeOrTouchSelector = '.dropdown.open > a[data-plenty-enable="toggle-xs-sm-or-touch"]';
        var aTouchSelector        = '.dropdown.open > a[data-plenty-enable="touch"]';
        var activeDropdown        = null;

        if ( isIntervalNotFitting() )
        {
            $( aTouchSelector ).parent().removeClass( 'open' );
        }

        return {
            initMobileDropdown: initMobileDropdown,
            mobileMenu        : mobileMenu,
            openDropdown      : openDropdown
        };

        function initMobileDropdown()
        {
            $( window ).on( 'orientationchange', function()
            {
                if ( isFittingOrNotInterval() )
                {
                    $( resizeOrTouchSelector ).parent().removeClass( toggleClass );
                }

                if ( isIntervalNotFitting() )
                {
                    $( aTouchSelector ).parent().removeClass( toggleClass );
                }
            } );

            $( window ).on( 'sizeChange', function( newValue )
            {
                if ( newValue != sizes.xs && newValue != sizes.sm && !Modernizr.touch )
                {
                    $( resizeOrTouchSelector ).parent().removeClass( toggleClass );
                }
            } );

            $( 'html' ).click( function()
            {
                if ( !!activeDropdown )
                {
                    activeDropdown.parent().removeClass( toggleClass );
                    activeDropdown = null;
                }
            } );
        }

        function openDropdown( elem, mediaSizes )
        {
            var $elem = $( elem );
            var activeParent;

            if ( Modernizr.touch && MediaSizeService.isInterval( 'md, lg' )
                || MediaSizeService.isInterval( mediaSizes ) )
            {
                if ( !!activeDropdown && activeDropdown[0] == $elem[0] )
                {
                    activeDropdown.parent().removeClass( toggleClass );
                    activeDropdown = null;
                }
                else
                {
                    if ( !!activeDropdown && activeDropdown[0] != $elem[0] )
                    {
                        activeDropdown.parent().removeClass( toggleClass );
                    }
                    activeDropdown = $elem;
                    activeParent   = activeDropdown.parent();
                    activeParent.click( function( event )
                    {
                        event.stopPropagation();
                    } );
                    if ( !activeParent.hasClass( toggleClass ) )
                    {
                        activeParent.addClass( toggleClass );
                    }
                }
            }
        }

        function mobileMenu( elem, condition )
        {
            var $elem       = $( elem );
            var $elemParent = $elem.parent();

            if ( condition == "toggle-xs-sm-or-touch" )
            {
                $elem.click( function( e )
                {
                    if ( isFittingOrNotInterval() )
                    {
                        $( resizeOrTouchSelector ).not( $elem ).parent().removeClass( toggleClass );
                        $elemParent.toggleClass( toggleClass );
                        return false;
                    }
                } );
            }

            // dropdown enabled touch
            else if ( condition == "touch" )
            {
                $elem.click( function()
                {
                    if ( isIntervalNotFitting() )
                    { // otherwise already has mobile navigation
                        $( aTouchSelector ).not( $elem ).parent().removeClass( toggleClass );
                        $elemParent.addClass( toggleClass );
                        return false;
                    }
                } );
            }
        }

        pm.directive( '*', function( i, elem, MediaSizeService )
        {

            $( elem ).click( function( e )
            {
                if ( isFittingOrNotInterval() )
                {
                    var dropdown = $( resizeOrTouchSelector ).parent();
                    if ( dropdown.length > 0 && !dropdown.is( e.target ) && dropdown.has( e.target ).length <= 0 )
                    {
                        dropdown.removeClass( toggleClass );
                    }
                }

                if ( isIntervalNotFitting() )
                {
                    var dropdown = $( aTouchSelector ).parent();
                    if ( dropdown.length > 0 && !dropdown.is( e.target ) && dropdown.has( e.target ).length <= 0 )
                    {
                        dropdown.removeClass( toggleClass );
                    }
                }
            } );
        }, ['MediaSizeService'] );

        function isIntervalNotFitting()
        {
            return (!MediaSizeService.isInterval( "xs, sm" ) && Modernizr.touch);
        }

        function isFittingOrNotInterval()
        {
            return (MediaSizeService.isInterval( "xs, sm" ) || isIntervalNotFitting());
        }

    }, ['MediaSizeService'] );
}( jQuery, PlentyFramework ));<|endoftext|>