<commit_before>const Core = require('./core');

class Discord extends Core {
  constructor() {
    super();
    this.dnsResolver = { resolve: function(address) {return {address: address} } };
  }

  async run(state) {
    console.log('SENDING HTTP Request');
    this.usedTcp = true;
    console.log(this.options);
    const raw = await this.request({
      uri: 'https://discordapp.com/api/guilds/' + this.options.address + '/widget.json',
    });
    const json = JSON.parse(raw);
    state.name = json.name;
    if (json.instant_invite) {
      state.connect = json.instant_invite;
    } else {
      state.connect = 'https://discordapp.com/channels/' + this.options.address
    }
    state.players = json.members.map(v => {
      return {
        name: v.username + '#' + v.discriminator,
        username: v.username,
        discriminator: v.discriminator,
        team: v.status
      }
    });
    state.raw = json;
  }
}

module.exports = Discord;
<commit_msg>Remove extra logging<commit_after>const Core = require('./core');

class Discord extends Core {
  constructor() {
    super();
    this.dnsResolver = { resolve: function(address) {return {address: address} } };
  }

  async run(state) {
    this.usedTcp = true;
    const raw = await this.request({
      uri: 'https://discordapp.com/api/guilds/' + this.options.address + '/widget.json',
    });
    const json = JSON.parse(raw);
    state.name = json.name;
    if (json.instant_invite) {
      state.connect = json.instant_invite;
    } else {
      state.connect = 'https://discordapp.com/channels/' + this.options.address
    }
    state.players = json.members.map(v => {
      return {
        name: v.username + '#' + v.discriminator,
        username: v.username,
        discriminator: v.discriminator,
        team: v.status
      }
    });
    state.raw = json;
  }
}

module.exports = Discord;
<|endoftext|>


<commit_before>'use strict';

angular.module('metadatamanagementApp')
  .controller('VariableDetailController', function(DialogService, $translate,
    blockUI, $scope, $stateParams, $filter, VariableResource, $rootScope) {
    /* paged frequencies */
    $scope.frequencies = [];
    /* all frequencies */
    $scope.allFrequencies = [];

    $scope.tableFlag = 'expand';
    /* params for table */
    $scope.query = {
      order: 'value',
      limit: 5,
      count: 0,
      allLabel: {},
      page: 1
    };
    /* options for pager */
    $scope.options = {};

    /* see https://github.com/angular-ui/ui-router/issues/582 */
    VariableResource.get({id: $stateParams.id})
    .$promise.then(function(variable) {
      $scope.variable = variable;
      console.log(variable);
      if ($scope.variable.distribution.validResponses) {
        $scope.frequencies = $scope.variable.distribution.validResponses
        .concat($scope.variable.distribution.missings);
        if ($scope.frequencies.length > 8) {
          $scope.frequencies.splice(3, 0, {
            value: '...',
            label: {
              de: '...',
              en: '...'
            },
            absoluteFrequency: '...',
            validRelativeFrequency: '...',
            relativeFrequency: '...'
          });
        }
      } else {
        $scope.frequencies = $scope.variable.distribution.missings;
      }
    });

    $scope.showRows = function() {
      if ($scope.tableFlag === 'expand') {
        var hiddenRows = angular.element('.ng-hide');
        $scope.tableFlag = 'collapse';
        for (var i = 0; i < hiddenRows.length; i++) {
          angular.element('#' + hiddenRows[i]
            .getAttribute('id')).addClass('ng-show').removeClass('ng-hide');
        }
        angular.element('#row3').addClass('ng-hide').removeClass('ng-show');
      }else {
        var displayedRows = angular.element('.ng-show');
        $scope.tableFlag = 'expand';
        for (var j = 0; j < displayedRows.length; j++) {
          angular.element('#' + displayedRows[j]
            .getAttribute('id')).addClass('ng-hide').removeClass('ng-show');
        }
        angular.element('#row3').addClass('ng-show').removeClass('ng-hide');
      }
    };
    /* function to start blockUI */
    $scope.startBlockUI = function() {
      blockUI.start();
    };
    /* function to stop blockUI */
    $scope.stopBlockUI = function() {
      blockUI.stop();
    };
    /* function to open dialog for variables */
    $scope.showSurveys = function() {
      blockUI.start();
      DialogService.showDialog($scope.variable.surveyIds, 'survey',
        ['label', 'name'], $rootScope.currentLanguage);
    };
    /* function to open dialog for data-sets */
    $scope.showDataSets = function() {
      blockUI.start();
      DialogService.showDialog($scope.variable.dataSetIds, 'data-set',
        ['label', 'name'], $rootScope.currentLanguage);
    };
  });
<commit_msg>#616 added logic for table<commit_after>'use strict';

angular.module('metadatamanagementApp')
  .controller('VariableDetailController', function(DialogService, $translate,
    blockUI, $scope, $stateParams, $filter, VariableResource, $rootScope) {
    /* paged frequencies */
    $scope.frequencies = [];
    /* all frequencies */
    $scope.allFrequencies = [];

    $scope.tableFlag = 'expand';
    /* params for table */
    $scope.query = {
      order: 'value',
      limit: 5,
      count: 0,
      allLabel: {},
      page: 1
    };
    /* options for pager */
    $scope.options = {};

    /* see https://github.com/angular-ui/ui-router/issues/582 */
    VariableResource.get({id: $stateParams.id})
    .$promise.then(function(variable) {
      $scope.variable = variable;
      console.log(variable);
      if ($scope.variable.distribution.validResponses) {
        $scope.frequencies = $scope.variable.distribution.validResponses
        .concat($scope.variable.distribution.missings);
        if ($scope.frequencies.length > 8) {
          $scope.frequencies.splice(3, 0, {
            value: '...',
            label: {
              de: '...',
              en: '...'
            },
            absoluteFrequency: '...',
            validRelativeFrequency: '...',
            relativeFrequency: '...'
          });
        }
      } else {
        $scope.frequencies = $scope.variable.distribution.missings;
      }
    });

    $scope.showRows = function() {
      if($scope.frequencies.length > 8) {
        if ($scope.tableFlag === 'expand') {
          var hiddenRows = angular.element('.ng-hide');
          $scope.tableFlag = 'collapse';
          for (var i = 0; i < hiddenRows.length; i++) {
            angular.element('#' + hiddenRows[i]
            .getAttribute('id')).addClass('ng-show').removeClass('ng-hide');
          }
          angular.element('#row3').addClass('ng-hide').removeClass('ng-show');
        }else {
          var displayedRows = angular.element('.ng-show');
          $scope.tableFlag = 'expand';
          for (var j = 0; j < displayedRows.length; j++) {
            angular.element('#' + displayedRows[j]
            .getAttribute('id')).addClass('ng-hide').removeClass('ng-show');
          }
          angular.element('#row3').addClass('ng-show').removeClass('ng-hide');
        }
      }
    };
    /* function to start blockUI */
    $scope.startBlockUI = function() {
      blockUI.start();
    };
    /* function to stop blockUI */
    $scope.stopBlockUI = function() {
      blockUI.stop();
    };
    /* function to open dialog for variables */
    $scope.showSurveys = function() {
      blockUI.start();
      DialogService.showDialog($scope.variable.surveyIds, 'survey',
        ['label', 'name'], $rootScope.currentLanguage);
    };
    /* function to open dialog for data-sets */
    $scope.showDataSets = function() {
      blockUI.start();
      DialogService.showDialog($scope.variable.dataSetIds, 'data-set',
        ['label', 'name'], $rootScope.currentLanguage);
    };
  });
<|endoftext|>


<commit_before>jQuery(document).ready(function($) {

    var vie = new VIE();
    vie.EntityManager.entities.bind('add', function(model) {
        if (typeof model.id == 'string') {
            model.url = vie_phpcr_path + model.id.substring(1, model.id.length - 1);
            model.toJSON = model.toJSONLD;
        }
    });

    vie.use(new vie.RdfaService);

    vie.namespaces.add('sioc', 'http://rdfs.org/sioc/ns#');

    // Load all RDFa entities into VIE
    vie.RDFaEntities.getInstances();

    // Make all RDFa entities editable

    jQuery('[typeof][about]').each(function() {
        jQuery(this).vieSemanticHallo({
            vie: vie,
            plugins: {
                'dcterms:title': {
                    'hallooverlay': {},
                    'hallotoolbarlinebreak': {}
                },
                'default': {
                    'halloimage': { 'searchUrl': 'liip/vie/assets/search/', 'vie': vie },
                    'hallolink': {},
                    'halloheadings': {},
                    'halloformat': {'formattings': {'strikeThrough': false, 'underline': false}},
                    'hallolists': {'lists': {'ordered': false}},
                    'hallojustify': {},
                    'halloreundo': {},
                    'hallotoolbarlinebreak': { 'breakAfter': ['hallolink'] },
                    'hallooverlay': {}
                }
            },
            floating: false,
            offset: {
                'x': 0,
                'y': "top"
            },
            showAlways: true
        });
    });

    $(this).bind('hallodeactivated', vieSaveContent);
    $(this).bind('startPreventSave', function() {
        preventSave = true;
    });
    $(this).bind('stopPreventSave', function() {
        preventSave = false;
    });

    $(window).resize(function(){
        if(!$('.inEditMode')[0] == undefined ){
            $('.halloToolbar').css('left', $('.inEditMode')[0].offsetLeft);
        }
    });

    $('[contenteditable]').not('.inEditMode').hover(function(){
        $(document).trigger('startPreventSave');
        if(!$(this).hasClass('inEditMode')){
            var editButton = $('
edit
').addClass('editButton');
            $(this).append(editButton);
        }
    }, function(){
        $(document).trigger('stopPreventSave');
        $('.editButton').remove();
    });

    var preventSave = false;
    function vieSaveContent() {
        if (preventSave) {
            setTimeout(vieSaveContent, 5000);
            return;
        }

        // Go through all Backbone model instances loaded for the page
        vie.EntityManager.entities.each(function(objectInstance) {

            if (!VIE.HalloEditable.refreshFromEditables(objectInstance)) {
                // No changes to this object, skip
                return true;
            }
            $(document).trigger("vieSaveStart");

            // Set the modified properties to the model instance
            objectInstance.save(null, {
                success: function(savedModel, response) {
                    $(document).trigger("vieSaveSuccess");
                    console.log(savedModel.id + " was saved");
                },
                error: function(response) {
                    console.log("Save failed");
                    console.log(response);
                }
            });
        });
    }
});
<commit_msg>Removing old RDFaEntities<commit_after>jQuery(document).ready(function($) {

    var vie = new VIE();
    vie.EntityManager.entities.bind('add', function(model) {
        if (typeof model.id == 'string') {
            model.url = vie_phpcr_path + model.id.substring(1, model.id.length - 1);
            model.toJSON = model.toJSONLD;
        }
    });

    vie.use(new vie.RdfaService);

    vie.namespaces.add('sioc', 'http://rdfs.org/sioc/ns#');

    jQuery('[typeof][about]').each(function() {
        jQuery(this).vieSemanticHallo({
            vie: vie,
            plugins: {
                'dcterms:title': {
                    'hallooverlay': {},
                    'hallotoolbarlinebreak': {}
                },
                'default': {
                    'halloimage': { 'searchUrl': 'liip/vie/assets/search/', 'vie': vie },
                    'hallolink': {},
                    'halloheadings': {},
                    'halloformat': {'formattings': {'strikeThrough': false, 'underline': false}},
                    'hallolists': {'lists': {'ordered': false}},
                    'hallojustify': {},
                    'halloreundo': {},
                    'hallotoolbarlinebreak': { 'breakAfter': ['hallolink'] },
                    'hallooverlay': {}
                }
            },
            floating: false,
            offset: {
                'x': 0,
                'y': "top"
            },
            showAlways: true
        });
    });

    $(this).bind('hallodeactivated', vieSaveContent);
    $(this).bind('startPreventSave', function() {
        preventSave = true;
    });
    $(this).bind('stopPreventSave', function() {
        preventSave = false;
    });

    $(window).resize(function(){
        if(!$('.inEditMode')[0] == undefined ){
            $('.halloToolbar').css('left', $('.inEditMode')[0].offsetLeft);
        }
    });

    $('[contenteditable]').not('.inEditMode').hover(function(){
        $(document).trigger('startPreventSave');
        if(!$(this).hasClass('inEditMode')){
            var editButton = $('
edit
').addClass('editButton');
            $(this).append(editButton);
        }
    }, function(){
        $(document).trigger('stopPreventSave');
        $('.editButton').remove();
    });

    var preventSave = false;
    function vieSaveContent() {
        if (preventSave) {
            setTimeout(vieSaveContent, 5000);
            return;
        }

        // Go through all Backbone model instances loaded for the page
        vie.EntityManager.entities.each(function(objectInstance) {

            if (!VIE.HalloEditable.refreshFromEditables(objectInstance)) {
                // No changes to this object, skip
                return true;
            }
            $(document).trigger("vieSaveStart");

            // Set the modified properties to the model instance
            objectInstance.save(null, {
                success: function(savedModel, response) {
                    $(document).trigger("vieSaveSuccess");
                    console.log(savedModel.id + " was saved");
                },
                error: function(response) {
                    console.log("Save failed");
                    console.log(response);
                }
            });
        });
    }
});
<|endoftext|>


<commit_before>// # document ready
$(document).ready(function() {
    if (!window.console) window.console = {};
    if (!window.console.log) window.console.log = function() {};

    slideDeactivate();
    $("#sender").keyup(callback);

    updater.start();
});

// # updater
var updater = {
    socket: null,
    slidePage: 1,
    notes: null,
    action: null,
    retry_attempts: 0,
    max_retry_attempts: 120,

    // * start
    start: function() {
        var protocol = ("https:" == location.protocol) ? "wss:" : "ws:"
        var url = protocol + "//" + location.host + "/ws";
        updater.socket = new WebSocket(url);

        if (!Date.now) {
            Date.now = function() {return new Date().getTime();}
        }

        var timestamp = Math.floor(Date.now() / 1000);
        var sourceUrl = "https://gist.githubusercontent.com/shiraco/6351869970d3f1a6c144/raw/" + "?timestamp=" + timestamp;

        $.get(sourceUrl, function(res) {
            sourceMd = res;

        }).done(function(sourceMd) {
            sourceHtml = marked(sourceMd);
            var pages = sourceHtml.split("
");
            slideTotalPages = pages.length;

            // * create notes
            updater.notes = pages.map(function(element, index, array) {
                elements = element.split("
???
");
                elements.push(""); // 末尾に追加
                elements.shift(); // 先頭削除
                note = elements.shift(); // 先頭取得

                // note = note.replace(/
([\s\S]?)<\/p>/g, RegExp.$1);
                // note = note.replace(/
([\s\S]?)<\/ul>/g, RegExp.$1);
                note = note.replace(/
/g, "");
                note = note.replace(/<\/p>/g, "");
                note = note.replace(/
/g, "");
                note = note.replace(/<\/ul>/g, "");
                note = note.replace(/
/g, "");

                notes = note.split("
");
                notes = notes.map(function(element, index, array) {
                    return $.trim(element);
                });
                notes = notes.filter(function(e) {return e !== "";}); // 空要素削除

                return notes;
            });

            updater.showSlideNav(updater.slidePage);
            updater.showSayText();

            slideActivate();

        });

        // * socket open
        updater.socket.onopen = function() {
            console.log("onopen");
        };

        // * socket onmessage
        updater.socket.onmessage = function(event) {
            var json = JSON.parse(event.data);
            console.log("onmessage: " + json["keyCode"]);

            updater.retry_attempts = 0;

            updater.showMessage(updater.action);
            updater.showSlideNav(updater.slidePage);
            updater.showSayText();
        };

        // * socket close
        updater.socket.onclose = function(event) {
            console.log("onclose. reason: %s", event.reason);

            if (updater.retry_attempts < updater.max_retry_attempts) {
                // Connection has closed so try to reconnect.
                updater.retry_attempts++;
                slideDeactivate();
                updater.socket = null;
                updater.start();
                console.log("retry_attempts: ", updater.retry_attempts);

            } else {
                console.log("websocket closed by over max_retry_attempts: ", updater.retry_attempts);

            }
        };

        // * socket onerror
        updater.socket.onerror = function(event) {
            console.log("onerror");
            slideDeactivate();

        }

    },

    // * update message
    showMessage: function(message) {
        var node = $("#message");
        node.hide();
        node.text(message);
        node.fadeIn("slow");
    },

    // * update slide-nav
    showSlideNav: function(message) {
        var node = $("#slide-nav");
        node.text(message);
    },

    // * update robot-say-collection
    showSayText: function() {
        var node = $("#robot-say-collection");
        node.empty();

        disabled = !robot.enable;

        sayTexts = updater.notes[updater.slidePage - 1];
        sayTexts.forEach(function(element, index, array) {
            console.log(index + ":" + element + ", disabled:" + disabled);
            node.append("
" +
                        "  " + element + "" +
                        "  <button id='saySlideText" + index + "-btn' class='secondary-content btn-floating center-align keyup white-text waves-effect waves-light robot-input' onclick='animatedSayClicked(\"#saySlideText" + index + "\");'>Say</button>" +
                        "
");
            $("#saySlideText" + index + "-btn").prop("disabled", disabled);

        });
    }

};

// # callback
var callback = function(e) {
    // console.log(e.type, e);
    var text = e.type;
    var code = e.which ? e.which : e.keyCode;
    if (13 === code) {
        text += ": ENTER";

    } else {
        text += ": keycode " + code;
    }
    console.log("callback: " + text);
};

// # button activate & deactivate
// * activate
function slideActivate() {
    console.log("Slide activate");
    disabled = false;
    $(".slide-input").prop("disabled", disabled);
}

// * deactivate
function slideDeactivate() {
    console.log("Slide deactivate");
    disabled = true;
    $(".slide-input").prop("disabled", disabled);
}

// # button clicked
// * leftButtonClicked()
function leftButtonClicked() {
    var code = 37;  // Left
    updater.action = "Previous Slide";
    $("#sender").trigger(
        $.Event("keyup", {keyCode: code, which: code})
    );
    if (updater.slidePage > 1) {
        updater.slidePage--;
        newCommand(code, updater.slidePage);
        updater.action = updater.action + ": " + updater.slidePage;
    }
    return false;
}

// * rightButtonClicked
function rightButtonClicked() {
    var code = 39;  // Right
    updater.action = "Next Slide";
    $("#sender").trigger(
        $.Event("keyup", {keyCode: code, which: code})
    );
    if (updater.slidePage < slideTotalPages) {
        updater.slidePage++;
        newCommand(code, updater.slidePage);
        updater.action = updater.action + ": " + updater.slidePage;
    }
    return false;
}

// * commmon command
function newCommand(keyCode, slidePage) {
    var message = {keyCode: keyCode, slidePage: slidePage};

    // send command
    updater.socket.send(JSON.stringify(message));
}

// * animated say clicked
function animatedSayClicked(value) {
    var node = $(value);
    animatedSay(node.text());
    node.parent().remove();
}
<commit_msg>remove callback function<commit_after>// # document ready
$(document).ready(function() {
    if (!window.console) window.console = {};
    if (!window.console.log) window.console.log = function() {};

    slideDeactivate();
    updater.start();
});

// # updater
var updater = {
    socket: null,
    slidePage: 1,
    notes: null,
    action: null,
    retry_attempts: 0,
    max_retry_attempts: 120,

    // * start
    start: function() {
        var protocol = ("https:" == location.protocol) ? "wss:" : "ws:"
        var url = protocol + "//" + location.host + "/ws";
        updater.socket = new WebSocket(url);

        if (!Date.now) {
            Date.now = function() {return new Date().getTime();}
        }

        var timestamp = Math.floor(Date.now() / 1000);
        var sourceUrl = "https://gist.githubusercontent.com/shiraco/6351869970d3f1a6c144/raw/" + "?timestamp=" + timestamp;

        $.get(sourceUrl, function(res) {
            sourceMd = res;

        }).done(function(sourceMd) {
            sourceHtml = marked(sourceMd);
            var pages = sourceHtml.split("
");
            slideTotalPages = pages.length;

            // * create notes
            updater.notes = pages.map(function(element, index, array) {
                elements = element.split("
???
");
                elements.push(""); // 末尾に追加
                elements.shift(); // 先頭削除
                note = elements.shift(); // 先頭取得

                // note = note.replace(/
([\s\S]?)<\/p>/g, RegExp.$1);
                // note = note.replace(/
([\s\S]?)<\/ul>/g, RegExp.$1);
                note = note.replace(/
/g, "");
                note = note.replace(/<\/p>/g, "");
                note = note.replace(/
/g, "");
                note = note.replace(/<\/ul>/g, "");
                note = note.replace(/
/g, "");

                notes = note.split("
");
                notes = notes.map(function(element, index, array) {
                    return $.trim(element);
                });
                notes = notes.filter(function(e) {return e !== "";}); // 空要素削除

                return notes;
            });

            updater.showSlideNav(updater.slidePage);
            updater.showSayText();

            slideActivate();

        });

        // * socket open
        updater.socket.onopen = function() {
            console.log("onopen");
        };

        // * socket onmessage
        updater.socket.onmessage = function(event) {
            var json = JSON.parse(event.data);
            console.log("onmessage: " + json["keyCode"]);

            updater.retry_attempts = 0;

            updater.showMessage(updater.action);
            updater.showSlideNav(updater.slidePage);
            updater.showSayText();
        };

        // * socket close
        updater.socket.onclose = function(event) {
            console.log("onclose. reason: %s", event.reason);

            if (updater.retry_attempts < updater.max_retry_attempts) {
                // Connection has closed so try to reconnect.
                updater.retry_attempts++;
                slideDeactivate();
                updater.socket = null;
                updater.start();
                console.log("retry_attempts: ", updater.retry_attempts);

            } else {
                console.log("websocket closed by over max_retry_attempts: ", updater.retry_attempts);

            }
        };

        // * socket onerror
        updater.socket.onerror = function(event) {
            console.log("onerror");
            slideDeactivate();

        }

    },

    // * update message
    showMessage: function(message) {
        var node = $("#message");
        node.hide();
        node.text(message);
        node.fadeIn("slow");
    },

    // * update slide-nav
    showSlideNav: function(message) {
        var node = $("#slide-nav");
        node.text(message);
    },

    // * update robot-say-collection
    showSayText: function() {
        var node = $("#robot-say-collection");
        node.empty();

        disabled = !robot.enable;

        sayTexts = updater.notes[updater.slidePage - 1];
        sayTexts.forEach(function(element, index, array) {
            console.log(index + ":" + element + ", disabled:" + disabled);
            node.append("
" +
                        "  " + element + "" +
                        "  <button id='saySlideText" + index + "-btn' class='secondary-content btn-floating center-align keyup white-text waves-effect waves-light robot-input' onclick='animatedSayClicked(\"#saySlideText" + index + "\");'>Say</button>" +
                        "
");
            $("#saySlideText" + index + "-btn").prop("disabled", disabled);

        });
    }

};

// # button activate & deactivate
// * activate
function slideActivate() {
    console.log("Slide activate");
    disabled = false;
    $(".slide-input").prop("disabled", disabled);
}

// * deactivate
function slideDeactivate() {
    console.log("Slide deactivate");
    disabled = true;
    $(".slide-input").prop("disabled", disabled);
}

// # button clicked
// * leftButtonClicked()
function leftButtonClicked() {
    var code = 37;  // Left
    updater.action = "Previous Slide";

    if (updater.slidePage > 1) {
        updater.slidePage--;
        newCommand(code, updater.slidePage);
        updater.action = updater.action + ": " + updater.slidePage;
    }
    return false;
}

// * rightButtonClicked
function rightButtonClicked() {
    var code = 39;  // Right
    updater.action = "Next Slide";

    if (updater.slidePage < slideTotalPages) {
        updater.slidePage++;
        newCommand(code, updater.slidePage);
        updater.action = updater.action + ": " + updater.slidePage;
    }
    return false;
}

// * commmon command
function newCommand(keyCode, slidePage) {
    var message = {keyCode: keyCode, slidePage: slidePage};

    // send command
    updater.socket.send(JSON.stringify(message));
}

// * animated say clicked
function animatedSayClicked(value) {
    var node = $(value);
    animatedSay(node.text());
    node.parent().remove();
}
<|endoftext|>


<commit_before>var React = require('react');
var _ = require('lodash');
var ReactPropTypes = React.PropTypes;
var PillSelector = require('./PillSelector.react');
var QBerModal = require('./QBerModal.react');
var Caret = require('./Caret.react');

function findByURI(source, uri) {
    return source.filter(function( obj ) {
        return obj.uri === uri;
    })[ 0 ];
}

var ValueDefinitionTable = React.createClass({

  // This React class only works if a list of 'values' is passed through its properties.
  propTypes: {
    variable: ReactPropTypes.object.isRequired,
    schemes: ReactPropTypes.object.isRequired
  },

  getInitialState: function() {
    return {
      'visible': true,
      'modal_visible': false,
      'selected_code_value': undefined,
      'selected_code_uri': undefined
    };
  },

  /**
   * @return {object}
   */
  render: function() {
    console.log("ValueDefinitionTable props:");
    console.log(this.props);

    // This section should be hidden by default
    // and shown when we do have variables in our dataset
    if (this.props.variable.values === undefined || this.props.variable.values.length < 1) {
      return null;
    }

    var table;
    if (this.state.visible) {
      var values = this.props.variable.values;
      var values_rows = [];

      // The button is enabled if there's a variable, and the variable is of category community or coded
      var button_disabled = (this.props.variable && (this.props.variable.category == 'community' || this.props.variable.category == 'coded' )) ? false: true;

      for (var key in values) {
        var mapped_uri = values[key].uri;
        var mapped_uri_icon;
        if (mapped_uri){
          mapped_uri_icon = ;
        }
        var browse_mapped_uri;
        if (mapped_uri){
          browse_mapped_uri = "http://data.clariah-sdh.eculture.labs.vu.nl/browse?uri="+encodeURIComponent(mapped_uri);
        }
        values_rows.push(

                            { values[key].label }

                            {mapped_uri_icon}

                              {mapped_uri}

                             { values[key].count }

);
      }

      var modal;
      // We only prepare the modal if we have a community or coded variable
      if (this.props.variable && (this.props.variable.category == 'community' || this.props.variable.category == 'coded' )){
        var title = Select corresponding code for {this.state.selected_code_value};

        var scheme = _.find(this.props.schemes, {'uri': this.props.variable.codelist.uri});

        var sorted_values;
        // If we have a stored scheme, sort the concepts by label
        if(scheme !== undefined) {
          console.log(scheme);
          sorted_values = _.sortBy(scheme.concepts,'label');
        } else {
          // Otherwise, we simply sort the values of the variable (i.e. the defaults)
          sorted_values = _.sortBy(this.props.variable.values,'label');
        }

        // Codelist present
        modal = <QBerModal visible={this.state.modal_visible}
                   title={title}
                   value={this.state.selected_code_value}
                   selection={(this.state.selected_code_value !== undefined && this.props.variable.codelist.mappings !== undefined) ? this.props.variable.codelist.mappings[this.state.selected_code_value] : undefined}
                   options={sorted_values}
                   doSelect={this._handleSelected}
                   doClose={this._handleToggleModal} />;

      }

      table =

                    {values_rows}

                {modal}

;
    }

    return (

              Frequency Table
              <Caret visible={this.state.visible}/>

              {table}

    );
  },

  _filter: function(option){
    return (option.label.search(regexp) > -1) ? '': (option.uri.search(regexp) > -1) ? '': 'none';
  },

  _handleSelected: function(code_uri){
    // The code uri is the selected uri in the QBerModal PillSelector.
    console.log("Selected new code:");
    console.log(code_uri);
    // values is the list of code values for this variable
    var values = this.props.variable.values;
    // The selected code value, is the currently visible code value
    var selected_code_value = this.state.selected_code_value;

    // Get the index of the selected code value, and increment it by 1 (the next code value)
    var next_index = _.findIndex(values, 'label', this.state.selected_code_value) + 1;

    // Set index to 0 if the resulting index is outside the values array (looping)
    if (next_index == values.length){
      next_index = 0;
    }

    // Copy the current state
    var new_state = this.state;
    // Set the selected code value to the next id in the values array (i.e. the code at the next index)
    new_state.selected_code_value = values[next_index].label;
    // Update the state
    this.setState(new_state);

    // Call the externally defined function that handles the mappings between (external) values and the source values.
    this.props.doMapping(selected_code_value, code_uri);
  },

  _handleToggleModal: function(e){
    var new_state = this.state;
    new_state.selected_code_value = e.currentTarget.getAttribute('value');
    new_state.modal_visible = !this.state.modal_visible;
    this.setState(new_state);
  },

  /**
   * Event handler for the visible/invisible click
   */
  _onToggle: function() {
    var new_state = this.state;
    new_state.visible = !this.state.visible;
    this.setState(new_state);
  },
});

module.exports = ValueDefinitionTable;
<commit_msg>Passing correct selection to ValueDefinitionTable<commit_after>var React = require('react');
var _ = require('lodash');
var ReactPropTypes = React.PropTypes;
var PillSelector = require('./PillSelector.react');
var QBerModal = require('./QBerModal.react');
var Caret = require('./Caret.react');

function findByURI(source, uri) {
    return source.filter(function( obj ) {
        return obj.uri === uri;
    })[ 0 ];
}

var ValueDefinitionTable = React.createClass({

  // This React class only works if a list of 'values' is passed through its properties.
  propTypes: {
    variable: ReactPropTypes.object.isRequired,
    schemes: ReactPropTypes.object.isRequired
  },

  getInitialState: function() {
    return {
      'visible': true,
      'modal_visible': false,
      'selected_code_value': undefined,
      'selected_code_uri': undefined
    };
  },

  /**
   * @return {object}
   */
  render: function() {
    console.log("ValueDefinitionTable props:");
    console.log(this.props);

    // This section should be hidden by default
    // and shown when we do have variables in our dataset
    if (this.props.variable.values === undefined || this.props.variable.values.length < 1) {
      return null;
    }

    var table;
    if (this.state.visible) {
      var values = this.props.variable.values;
      var values_rows = [];

      // The button is enabled if there's a variable, and the variable is of category community or coded
      var button_disabled = (this.props.variable && (this.props.variable.category == 'community' || this.props.variable.category == 'coded' )) ? false: true;

      for (var key in values) {
        var mapped_uri = values[key].uri;
        var mapped_uri_icon;
        if (mapped_uri){
          mapped_uri_icon = ;
        }
        var browse_mapped_uri;
        if (mapped_uri){
          browse_mapped_uri = "http://data.clariah-sdh.eculture.labs.vu.nl/browse?uri="+encodeURIComponent(mapped_uri);
        }
        values_rows.push(

                            { values[key].label }

                            {mapped_uri_icon}

                              {mapped_uri}

                             { values[key].count }

);
      }

      var modal;
      // We only prepare the modal if we have a community or coded variable
      if (this.props.variable && (this.props.variable.category == 'community' || this.props.variable.category == 'coded' )){
        var title = Select corresponding code for {this.state.selected_code_value};

        var scheme = _.find(this.props.schemes, {'uri': this.props.variable.codelist.uri});

        var sorted_values;
        // If we have a stored scheme, sort the concepts by label
        if(scheme !== undefined) {
          console.log(scheme);
          sorted_values = _.sortBy(scheme.concepts,'label');
        } else {
          // Otherwise, we simply sort the values of the variable (i.e. the defaults)
          sorted_values = _.sortBy(this.props.variable.values,'label');
        }

        // Codelist present
        modal = <QBerModal visible={this.state.modal_visible}
                   title={title}
                   value={this.state.selected_code_value}
                   selection={this.state.selected_code_value}
                   options={sorted_values}
                   doSelect={this._handleSelected}
                   doClose={this._handleToggleModal} />;

      }

      table =

                    {values_rows}

                {modal}

;
    }

    return (

              Frequency Table
              <Caret visible={this.state.visible}/>

              {table}

    );
  },

  _filter: function(option){
    return (option.label.search(regexp) > -1) ? '': (option.uri.search(regexp) > -1) ? '': 'none';
  },

  _handleSelected: function(code_uri){
    // The code uri is the selected uri in the QBerModal PillSelector.
    console.log("Selected new code:");
    console.log(code_uri);
    // values is the list of code values for this variable
    var values = this.props.variable.values;
    // The selected code value, is the currently visible code value
    var selected_code_value = this.state.selected_code_value;

    // Get the index of the selected code value, and increment it by 1 (the next code value)
    var next_index = _.findIndex(values, 'label', this.state.selected_code_value) + 1;

    // Set index to 0 if the resulting index is outside the values array (looping)
    if (next_index == values.length){
      next_index = 0;
    }

    // Copy the current state
    var new_state = this.state;
    // Set the selected code value to the next id in the values array (i.e. the code at the next index)
    new_state.selected_code_value = values[next_index].label;
    // Update the state
    this.setState(new_state);

    // Call the externally defined function that handles the mappings between (external) values and the source values.
    this.props.doMapping(selected_code_value, code_uri);
  },

  _handleToggleModal: function(e){
    var new_state = this.state;
    new_state.selected_code_value = e.currentTarget.getAttribute('value');
    new_state.modal_visible = !this.state.modal_visible;
    this.setState(new_state);
  },

  /**
   * Event handler for the visible/invisible click
   */
  _onToggle: function() {
    var new_state = this.state;
    new_state.visible = !this.state.visible;
    this.setState(new_state);
  },
});

module.exports = ValueDefinitionTable;
<|endoftext|>


<commit_before>define(function(require) {
    'use strict';

    var TooltipView = require('foreground/view/tooltip/tooltipView');
    var Tooltip = require('foreground/model/tooltip');

    var TooltipRegion = Marionette.Region.extend({
        initialize: function() {
            this.listenTo(Streamus.channels.tooltip.commands, 'show:tooltip', this._showTooltip);
            this.listenTo(Streamus.channels.tooltip.commands, 'hide:tooltip', this._hideTooltip);
        },

        _showTooltip: function(options) {
            var tooltipView = new TooltipView({
                model: new Tooltip({
                    text: options.text
                })
            });

            this.show(tooltipView);

            //  Let the DOM update so that offsetWidth and offsetHeight return correct values
            requestAnimationFrame(function() {
                var tooltipWidth = tooltipView.el.offsetWidth;
                var tooltipHeight = tooltipView.el.offsetHeight;

                //  Figure out the desired offset of the tooltip based on its dimensions, location, and the dimensions of its target
                var offset = this._getAdjustedOffset(options.targetBoundingClientRect, tooltipWidth, tooltipHeight);
                tooltipView.showAtOffset(offset);
            }.bind(this));
        },

        _hideTooltip: function() {
            //  TODO: I'd prefer doing this logic on the region itself, but making the region a panel conflicts with :hover once visible.
            if (!_.isUndefined(this.currentView)) {
                this.currentView.hide();
            }
        },

        //  Perform math in an attempt to center the tooltip along the bottom of a given element.
        //  If it can't go along the bottom then flip it and place it along the top.
        //  If it can't fit in the center then shift it to the left or right until it fits.
        _getAdjustedOffset: function(boundingClientRect, tooltipWidth, tooltipHeight) {
            var adjustY = 8;
            var targetHeight = boundingClientRect.height;
            var targetWidth = boundingClientRect.width;
            var targetOffset = {
                top: boundingClientRect.top + targetHeight + adjustY,
                left: boundingClientRect.left + targetWidth / 2 - tooltipWidth / 2
            };

            //  Note that these methods have side-effects on the targetOffset object.
            this._shiftLeftOffset(targetOffset, window.innerWidth, targetWidth, tooltipWidth);
            this._flipInvertTopOffset(targetOffset, window.innerHeight, adjustY, targetHeight, tooltipHeight);

            return targetOffset;
        },

        //  Credit to jquery.qtip2, http://qtip2.com/, for providing a lot of this math.
        //  I've stripped the given math **way** down to just my specific use case.

        //  Perform math to figure out whether the element needs to be shifted left/right and, if so, how much it needs to shift.
        _shiftLeftOffset: function(targetOffset, viewportLength, targetLength, tooltipLength) {
            var initialOffset = targetOffset['left'];
            var myLength = -tooltipLength / 2;
            var overflow1 = -initialOffset;
            var overflow2 = initialOffset + tooltipLength - viewportLength;
            var offset = -myLength;

            // Adjust position but keep it within viewport dimensions
            targetOffset['left'] += overflow1 > 0 ? overflow1 : overflow2 > 0 ? -overflow2 : 0;
            targetOffset['left'] = Math.max(
                initialOffset - offset,
                Math.min(
                    Math.max(
                        viewportLength,
                        initialOffset + offset
                    ),
                    targetOffset['left'],
                    // Make sure we don't adjust complete off the element when using 'center'
                    initialOffset - myLength
                )
            );
        },

        //  Perform math to figure out whether the element fits beneath the target. If not, flip it to the top.
        _flipInvertTopOffset: function(targetOffset, viewportLength, adjust, targetLength, tooltipLength) {
            var initialOffset = targetOffset['top'];
            var overflow1 = -initialOffset;
            var overflow2 = initialOffset + tooltipLength - viewportLength;
            var offset = tooltipLength + targetLength;

            if (overflow1 > 0 && overflow2 > 0) {
                // Check for overflow on the left/top
                targetOffset['top'] -= offset + adjust;
            }
            else if (overflow2 > 0) {
                // Check for overflow on the left/top
                targetOffset['top'] -= offset + (adjust * 2);
            }
        }
    });

    return TooltipRegion;
});<commit_msg>Fixing linting issues<commit_after>define(function(require) {
    'use strict';

    var TooltipView = require('foreground/view/tooltip/tooltipView');
    var Tooltip = require('foreground/model/tooltip');

    var TooltipRegion = Marionette.Region.extend({
        initialize: function() {
            this.listenTo(Streamus.channels.tooltip.commands, 'show:tooltip', this._showTooltip);
            this.listenTo(Streamus.channels.tooltip.commands, 'hide:tooltip', this._hideTooltip);
        },

        _showTooltip: function(options) {
            var tooltipView = new TooltipView({
                model: new Tooltip({
                    text: options.text
                })
            });

            this.show(tooltipView);

            //  Let the DOM update so that offsetWidth and offsetHeight return correct values
            requestAnimationFrame(function() {
                var tooltipWidth = tooltipView.el.offsetWidth;
                var tooltipHeight = tooltipView.el.offsetHeight;

                //  Figure out the desired offset of the tooltip based on its dimensions, location, and the dimensions of its target
                var offset = this._getAdjustedOffset(options.targetBoundingClientRect, tooltipWidth, tooltipHeight);
                tooltipView.showAtOffset(offset);
            }.bind(this));
        },

        _hideTooltip: function() {
            //  TODO: I'd prefer doing this logic on the region itself, but making the region a panel conflicts with :hover once visible.
            if (!_.isUndefined(this.currentView)) {
                this.currentView.hide();
            }
        },

        //  Perform math in an attempt to center the tooltip along the bottom of a given element.
        //  If it can't go along the bottom then flip it and place it along the top.
        //  If it can't fit in the center then shift it to the left or right until it fits.
        _getAdjustedOffset: function(boundingClientRect, tooltipWidth, tooltipHeight) {
            var adjustY = 8;
            var targetHeight = boundingClientRect.height;
            var targetWidth = boundingClientRect.width;
            var targetOffset = {
                top: boundingClientRect.top + targetHeight + adjustY,
                left: boundingClientRect.left + targetWidth / 2 - tooltipWidth / 2
            };

            //  Note that these methods have side-effects on the targetOffset object.
            this._shiftLeftOffset(targetOffset, window.innerWidth, targetWidth, tooltipWidth);
            this._flipInvertTopOffset(targetOffset, window.innerHeight, adjustY, targetHeight, tooltipHeight);

            return targetOffset;
        },

        //  Credit to jquery.qtip2, http://qtip2.com/, for providing a lot of this math.
        //  I've stripped the given math **way** down to just my specific use case.

        //  Perform math to figure out whether the element needs to be shifted left/right and, if so, how much it needs to shift.
        _shiftLeftOffset: function(targetOffset, viewportLength, targetLength, tooltipLength) {
            var initialOffset = targetOffset.left;
            var myLength = -tooltipLength / 2;
            var overflow1 = -initialOffset;
            var overflow2 = initialOffset + tooltipLength - viewportLength;
            var offset = -myLength;

            // Adjust position but keep it within viewport dimensions
            targetOffset.left += overflow1 > 0 ? overflow1 : overflow2 > 0 ? -overflow2 : 0;
            targetOffset.left = Math.max(
                initialOffset - offset,
                Math.min(
                    Math.max(
                        viewportLength,
                        initialOffset + offset
                    ),
                    targetOffset.left,
                    // Make sure we don't adjust complete off the element when using 'center'
                    initialOffset - myLength
                )
            );
        },

        //  Perform math to figure out whether the element fits beneath the target. If not, flip it to the top.
        _flipInvertTopOffset: function(targetOffset, viewportLength, adjust, targetLength, tooltipLength) {
            var initialOffset = targetOffset.top;
            var overflow1 = -initialOffset;
            var overflow2 = initialOffset + tooltipLength - viewportLength;
            var offset = tooltipLength + targetLength;

            if (overflow1 > 0 && overflow2 > 0) {
                // Check for overflow on the left/top
                targetOffset.top -= offset + adjust;
            }
            else if (overflow2 > 0) {
                // Check for overflow on the left/top
                targetOffset.top -= offset + (adjust * 2);
            }
        }
    });

    return TooltipRegion;
});<|endoftext|>


<commit_before>function (doc) {
    // !code util/mvp.js
    if(isChildVisitForm(doc)) {
        var indicators = get_indicators(doc);

        if (indicators.child_dob && indicators.child_dob.value) {
            var meta = doc.form.meta,
                indicator_entries = {},
                age = get_age_from_dob(indicators.child_dob.value, meta.timeEnd),
                visit_date = new Date(meta.timeEnd),
                case_id = get_case_id(doc);

            if (age > 180*MS_IN_DAY && age < 1770*MS_IN_DAY && indicators.muac.value) {
                // MUAC reading taken during visit
                indicator_entries["muac_reading"] = 1;
                try {
                    var muac_value = parseFloat(indicators.muac.value);
                    if (muac_value < 125.0) {
                        indicator_entries["muac_wasting"] = 1;
                    }
                } catch (err) {
                    log("MUAC value could not be obtained");
                }

                if (doc.form.last_muac) {
                    var last_muac = new Date(doc.form.last_muac);
                    if (last_muac <= visit_date) {
                        var difference = visit_date.getTime() - last_muac.getTime();
                        if (difference <= 90*MS_IN_DAY){
                            indicator_entries["routine_muac"] = case_id;
                        }
                    }
                }
            }
            emit_special(doc, visit_date, indicator_entries, [doc._id]);
        }

    }
}
<commit_msg>updates for A2-10 and A2-11 indicators<commit_after>function (doc) {
    // !code util/mvp.js
    if(isChildVisitForm(doc)) {
        var indicators = get_indicators(doc);

        if (indicators.child_dob && indicators.child_dob.value &&
            indicators.last_muac && indicators.last_muac.value) {
            var meta = doc.form.meta,
                indicator_entries = {},
                age = get_age_from_dob(indicators.child_dob.value, meta.timeEnd),
                last_muac_date = new Date(indicators.last_muac.value),
                case_id = get_case_id(doc);

            if (age > 180*MS_IN_DAY && age < 1770*MS_IN_DAY) {
                if (indicators.cur_muac && indicators.cur_muac.value) {
                    try {
                        var cur_muac = parseFloat(indicators.cur_muac.value);
                        indicator_entries["muac_reading"] = case_id;
                        if (cur_muac < 125.0) {
                            indicator_entries["muac_wasting"] = case_id;
                        }
                    } catch (e) {
                        // do nothing
                    }
                }
                indicator_entries["routine_muac"] = case_id;
            }
            emit_special(doc, last_muac_date, indicator_entries, [doc._id]);
        }

    }
}
<|endoftext|>


<commit_before>process.mixin(require('./helpers'));

describe('An element node', function() {
  var doc = null;
  var elem = null;

  beforeEach(function() {
    doc = new libxml.Document();
    elem = doc.node('name1');
  });

  it('can be created', function() {
    assertEqual('name1', elem.name());
  });

  it('can be created with a callback', function() {
    doc = new libxml.Document();
    var elem = false;
    doc.node('name2', function(n) { elem = n; });
    assertEqual('name2', elem.name());
  });

  it('can be created as the document root', function() {
    assertEqual('name1', doc.root().name());
  });

  it('can be built by nesting', function() {
    var doc = new libxml.Document();
    var levels = 0;
    doc.node('root', function(n) {
      levels++;
      assertEqual('root', n.name());
      n.node('child', function(n) {
        levels++;
        assertEqual('child', n.name());
        var grandchild = n.node('grandchild', function() { levels++; });
        assertEqual('grandchild', grandchild.name());
      });
    });
    assertEqual(3, levels);
  });

  it('can have content assigned after creation', function() {
    assertEqual(null, elem.text());
    elem.text('content');
    assertEqual('content', elem.text());
  });

  it('can undergo a namechange after creation', function() {
    assertEqual('name1', elem.name());
    elem.name('newname');
    assertEqual('newname', elem.name());
  });

  it('can have a child added to it', function() {
    var newChild = new libxml.Element(elem.doc(), 'new-child');
    elem.addChild(newChild);
    assert(doc.get('/name1/new-child'));
  });

  it('can describe its path', function() {
    var gchild = null, sibling = null;
    var doc = new libxml.Document(function(n) {
      n.node('root', function(n) {
        n.node('child', function(n) {
          gchild = n.node('grandchild');
        });
        sibling = n.node('child');
      });
    });
    assertEqual('/root/child[1]/grandchild', gchild.path());
    assertEqual('/root/child[2]', sibling.path());
  });

  it('knows that its type is "element"', function() {
    assert('element', elem.type());
  });

  it('can print itself using #toString', function() {
    assertEqual('<name1/>', elem.toString());
    elem.node('child');
    assertEqual('<name1><child/></name1>', elem.toString());
  });

  it('can remove itself from the document', function() {
    var child = elem.node('child');
    assert(doc.get('/name1/child'));

    child.remove();
    assert(!doc.get('/name1/child'));
  });

  it('can be moved from one place to another', function() {
    var child = elem.node('child');
    assert(doc.get('/name1/child'));

    child.remove();
    var name2 = elem.node('name2');
    name2.node(child);
    assert(!doc.get('/name1/child'));
    assert(doc.get('/name1/name2/child'));
  });
});
<commit_msg>tests for add prev/next element methods<commit_after>process.mixin(require('./helpers'));

describe('An element node', function() {
  var doc = null;
  var elem = null;

  beforeEach(function() {
    doc = new libxml.Document();
    elem = doc.node('name1');
  });

  it('can be created', function() {
    assertEqual('name1', elem.name());
  });

  it('can be created with a callback', function() {
    doc = new libxml.Document();
    var elem = false;
    doc.node('name2', function(n) { elem = n; });
    assertEqual('name2', elem.name());
  });

  it('can be created as the document root', function() {
    assertEqual('name1', doc.root().name());
  });

  it('can be built by nesting', function() {
    var doc = new libxml.Document();
    var levels = 0;
    doc.node('root', function(n) {
      levels++;
      assertEqual('root', n.name());
      n.node('child', function(n) {
        levels++;
        assertEqual('child', n.name());
        var grandchild = n.node('grandchild', function() { levels++; });
        assertEqual('grandchild', grandchild.name());
      });
    });
    assertEqual(3, levels);
  });

  it('can have content assigned after creation', function() {
    assertEqual(null, elem.text());
    elem.text('content');
    assertEqual('content', elem.text());
  });

  it('can undergo a namechange after creation', function() {
    assertEqual('name1', elem.name());
    elem.name('newname');
    assertEqual('newname', elem.name());
  });

  it('can have a child added to it', function() {
    var newChild = new libxml.Element(elem.doc(), 'new-child');
    elem.addChild(newChild);
    assert(doc.get('/name1/new-child'));
  });

  it('can describe its path', function() {
    var gchild = null, sibling = null;
    var doc = new libxml.Document(function(n) {
      n.node('root', function(n) {
        n.node('child', function(n) {
          gchild = n.node('grandchild');
        });
        sibling = n.node('child');
      });
    });
    assertEqual('/root/child[1]/grandchild', gchild.path());
    assertEqual('/root/child[2]', sibling.path());
  });

  it('knows that its type is "element"', function() {
    assert('element', elem.type());
  });

  it('can print itself using #toString', function() {
    assertEqual('<name1/>', elem.toString());
    elem.node('child');
    assertEqual('<name1><child/></name1>', elem.toString());
  });

  it('can remove itself from the document', function() {
    var child = elem.node('child');
    assert(doc.get('/name1/child'));

    child.remove();
    assert(!doc.get('/name1/child'));
  });

  it('can be moved from one place to another', function() {
    var child = elem.node('child');
    assert(doc.get('/name1/child'));

    child.remove();
    var name2 = elem.node('name2');
    name2.node(child);
    assert(!doc.get('/name1/child'));
    assert(doc.get('/name1/name2/child'));
  });

  it('can add a previous sibling', function() {
    var child1 = elem.node('child1');
    var child2 = elem.node('child2');
    assertEqual(elem.childNodes().length, 2);
    var prevSibling = new libxml.Element(elem.doc(), 'prev-sibling');
    var addedSibling = child2.addPrevSibling(prevSibling);
    var children = elem.childNodes();
    assertEqual(3, children.length);
    assertEqual('prev-sibling', children[1].name());
  });

  it('can add a next sibling', function() {
    var child1 = elem.node('child1');
    var child2 = elem.node('child2');
    assertEqual(elem.childNodes().length, 2);
    var nextSibling = new libxml.Element(elem.doc(), 'next-sibling');
    var addedSibling = child1.addNextSibling(nextSibling);
    var children = elem.childNodes();
    assertEqual(3, children.length);
    assertEqual('next-sibling', children[1].name());
  });
});
<|endoftext|>


<commit_before>"use strict";

describe('symlink |', function () {

    var fse = require('fs-extra');
    var pathUtil = require('path');
    var helper = require('./support/spec_helper');
    var jetpack = require('..');

    beforeEach(helper.beforeEach);
    afterEach(helper.afterEach);

    describe('*nix specyfic |', function () {

        if (process.platform === 'win32') {
            return;
        }

        it("can create a symlink", function (done) {

            var preparations = function () {
                helper.clearWorkingDir();
            };

            var expectations = function () {
                expect(fse.lstatSync('symlink').isSymbolicLink()).toBe(true);
                expect(fse.readlinkSync('symlink')).toBe('some/path');
            };

            // SYNC
            preparations();
            jetpack.symlink('some/path', 'symlink');
            expectations();

            // ASYNC
            preparations();
            jetpack.symlinkAsync('some/path', 'symlink')
            .then(function () {
                expectations();
                done();
            });
        });

        it("can create nonexistent parent directories", function (done) {

            var preparations = function () {
                helper.clearWorkingDir();
            };

            var expectations = function () {
                expect(fse.lstatSync('a/b/symlink').isSymbolicLink()).toBe(true);
            };

            // SYNC
            preparations();
            jetpack.symlink('whatever', 'a/b/symlink');
            expectations();

            // ASYNC
            preparations();
            jetpack.symlinkAsync('whatever', 'a/b/symlink')
            .then(function () {
                expectations();
                done();
            });
        });

        it("respects internal CWD of jetpack instance", function (done) {

            var preparations = function () {
                helper.clearWorkingDir();
                fse.mkdirsSync('a/b');
            };

            var expectations = function () {
                expect(fse.lstatSync('a/b/symlink').isSymbolicLink()).toBe(true);
            };

            var jetContext = jetpack.cwd('a/b');

            // SYNC
            preparations();
            jetContext.symlink('whatever', 'symlink');
            expectations();

            // ASYNC
            preparations();
            jetContext.symlinkAsync('whatever', 'symlink')
            .then(function () {
                expectations();
                done();
            });
        });

    });

});
<commit_msg>Normalize symlink specs to pass on Windows<commit_after>"use strict";

describe('symlink |', function () {

    var fse = require('fs-extra');
    var pathUtil = require('path');
    var helper = require('./support/spec_helper');
    var jetpack = require('..');

    beforeEach(helper.beforeEach);
    afterEach(helper.afterEach);

    it("can create a symlink", function (done) {

        var preparations = function () {
            helper.clearWorkingDir();
        };

        var expectations = function () {
            expect(fse.lstatSync('symlink').isSymbolicLink()).toBe(true);
            expect(fse.readlinkSync('symlink')).toBe('some_path');
        };

        // SYNC
        preparations();
        jetpack.symlink('some_path', 'symlink');
        expectations();

        // ASYNC
        preparations();
        jetpack.symlinkAsync('some_path', 'symlink')
        .then(function () {
            expectations();
            done();
        });
    });

    it("can create nonexistent parent directories", function (done) {

        var preparations = function () {
            helper.clearWorkingDir();
        };

        var expectations = function () {
            expect(fse.lstatSync('a/b/symlink').isSymbolicLink()).toBe(true);
        };

        // SYNC
        preparations();
        jetpack.symlink('whatever', 'a/b/symlink');
        expectations();

        // ASYNC
        preparations();
        jetpack.symlinkAsync('whatever', 'a/b/symlink')
        .then(function () {
            expectations();
            done();
        });
    });

    it("respects internal CWD of jetpack instance", function (done) {

        var preparations = function () {
            helper.clearWorkingDir();
            fse.mkdirsSync('a/b');
        };

        var expectations = function () {
            expect(fse.lstatSync('a/b/symlink').isSymbolicLink()).toBe(true);
        };

        var jetContext = jetpack.cwd('a/b');

        // SYNC
        preparations();
        jetContext.symlink('whatever', 'symlink');
        expectations();

        // ASYNC
        preparations();
        jetContext.symlinkAsync('whatever', 'symlink')
        .then(function () {
            expectations();
            done();
        });
    });

});
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * The examples provided by Facebook are for non-commercial testing and
 * evaluation purposes only.
 *
 * Facebook reserves all rights not expressly granted.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
 * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  *
 *
 * @providesModule SwipeableRow
 * @flow
 */
'use strict';

const Animated = require('Animated');
const PanResponder = require('PanResponder');
const React = require('React');
const StyleSheet = require('StyleSheet');
const TimerMixin = require('react-timer-mixin');
const View = require('View');

const {PropTypes} = React;

const emptyFunction = require('fbjs/lib/emptyFunction');

// NOTE: Eventually convert these consts to an input object of configurations

// Position of the left of the swipable item when closed
const CLOSED_LEFT_POSITION = 0;
// Minimum swipe distance before we recognize it as such
const HORIZONTAL_SWIPE_DISTANCE_THRESHOLD = 10;
// Minimum swipe speed before we fully animate the user's action (open/close)
const HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD = 0.3;
// Factor to divide by to get slow speed; i.e. 4 means 1/4 of full speed
const SLOW_SPEED_SWIPE_FACTOR = 4;
// Time, in milliseconds, of how long the animated swipe should be
const SWIPE_DURATION = 200;

/**
 * On SwipeableListView mount, the 1st item will bounce to show users it's
 * possible to swipe
 */
const ON_MOUNT_BOUNCE_DELAY = 700;
const ON_MOUNT_BOUNCE_DURATION = 400;

// Distance left of closed position to bounce back when right-swiping from closed
const RIGHT_SWIPE_BOUNCE_BACK_DISTANCE = 50;
const RIGHT_SWIPE_BOUNCE_BACK_DURATION = 400;
/**
 * Max distance of right swipe to allow (right swipes do functionally nothing).
 * Must be multiplied by SLOW_SPEED_SWIPE_FACTOR because gestureState.dx tracks
 * how far the finger swipes, and not the actual animation distance.
*/
const RIGHT_SWIPE_THRESHOLD = 30 * SLOW_SPEED_SWIPE_FACTOR;

/**
 * Creates a swipable row that allows taps on the main item and a custom View
 * on the item hidden behind the row. Typically this should be used in
 * conjunction with SwipeableListView for additional functionality, but can be
 * used in a normal ListView. See the renderRow for SwipeableListView to see how
 * to use this component separately.
 */
const SwipeableRow = React.createClass({
  _panResponder: {},
  _previousLeft: CLOSED_LEFT_POSITION,

  mixins: [TimerMixin],

  propTypes: {
    children: PropTypes.any,
    isOpen: PropTypes.bool,
    maxSwipeDistance: PropTypes.number.isRequired,
    onOpen: PropTypes.func.isRequired,
    onSwipeEnd: PropTypes.func.isRequired,
    onSwipeStart: PropTypes.func.isRequired,
    // Should bounce the row on mount
    shouldBounceOnMount: PropTypes.bool,
    /**
     * A ReactElement that is unveiled when the user swipes
     */
    slideoutView: PropTypes.node.isRequired,
    /**
     * The minimum swipe distance required before fully animating the swipe. If
     * the user swipes less than this distance, the item will return to its
     * previous (open/close) position.
     */
    swipeThreshold: PropTypes.number.isRequired,
  },

  getInitialState(): Object {
    return {
      currentLeft: new Animated.Value(this._previousLeft),
      /**
       * In order to render component A beneath component B, A must be rendered
       * before B. However, this will cause "flickering", aka we see A briefly
       * then B. To counter this, _isSwipeableViewRendered flag is used to set
       * component A to be transparent until component B is loaded.
       */
      isSwipeableViewRendered: false,
      rowHeight: (null: ?number),
    };
  },

  getDefaultProps(): Object {
    return {
      isOpen: false,
      maxSwipeDistance: 0,
      onOpen: emptyFunction,
      onSwipeEnd: emptyFunction,
      onSwipeStart: emptyFunction,
      swipeThreshold: 30,
    };
  },

  componentWillMount(): void {
    this._panResponder = PanResponder.create({
      onStartShouldSetPanResponder: (event, gestureState) => true,
      // Don't capture child's start events
      onStartShouldSetPanResponderCapture: (event, gestureState) => false,
      onMoveShouldSetPanResponder: (event, gestureState) => false,
      onMoveShouldSetPanResponderCapture: this._handleMoveShouldSetPanResponderCapture,
      onPanResponderGrant: this._handlePanResponderGrant,
      onPanResponderMove: this._handlePanResponderMove,
      onPanResponderRelease: this._handlePanResponderEnd,
      onPanResponderTerminationRequest: this._onPanResponderTerminationRequest,
      onPanResponderTerminate: this._handlePanResponderEnd,
    });
  },

  componentDidMount(): void {
    if (this.props.shouldBounceOnMount) {
      /**
       * Do the on mount bounce after a delay because if we animate when other
       * components are loading, the animation will be laggy
       */
      this.setTimeout(() => {
        this._animateBounceBack(ON_MOUNT_BOUNCE_DURATION);
      }, ON_MOUNT_BOUNCE_DELAY);
    }
  },

  componentWillReceiveProps(nextProps: Object): void {
    /**
     * We do not need an "animateOpen(noCallback)" because this animation is
     * handled internally by this component.
     */
    if (this.props.isOpen && !nextProps.isOpen) {
      this._animateToClosedPosition();
    }
  },

  shouldComponentUpdate(nextProps: Object, nextState: Object): boolean {
    if (this.props.shouldBounceOnMount && !nextProps.shouldBounceOnMount) {
      // No need to rerender if SwipeableListView is disabling the bounce flag
      return false;
    }

    return true;
  },

  render(): ReactElement<any> {
    // The view hidden behind the main view
    let slideOutView;
    if (this.state.isSwipeableViewRendered) {
      slideOutView = (
        <View style={[
          styles.slideOutContainer,
          {height: this.state.rowHeight},
          ]}>
          {this.props.slideoutView}
        </View>
      );
    }

    // The swipeable item
    const swipeableView = (
      <Animated.View
        onLayout={this._onSwipeableViewLayout}
        style={[
          styles.swipeableContainer,
          {
            transform: [{translateX: this.state.currentLeft}],
          },
        ]}>
        {this.props.children}
      </Animated.View>
    );

    return (
      <View
        {...this._panResponder.panHandlers}>
        {slideOutView}
        {swipeableView}
      </View>
    );
  },

  _onSwipeableViewLayout(event: Object): void {
    this.setState({
      isSwipeableViewRendered: true,
      rowHeight: event.nativeEvent.layout.height,
    });
  },

  _handleMoveShouldSetPanResponderCapture(
    event: Object,
    gestureState: Object,
  ): boolean {
    // Decides whether a swipe is responded to by this component or its child
    return gestureState.dy < 10 && this._isValidSwipe(gestureState);
  },

  _handlePanResponderGrant(event: Object, gestureState: Object): void {

  },

  _handlePanResponderMove(event: Object, gestureState: Object): void {
    if (this._isSwipingExcessivelyRightFromClosedPosition(gestureState)) {
      return;
    }

    this.props.onSwipeStart();

    if (this._isSwipingRightFromClosed(gestureState)) {
      this._swipeSlowSpeed(gestureState);
    } else {
      this._swipeFullSpeed(gestureState);
    }
  },

  _isSwipingRightFromClosed(gestureState: Object): boolean {
    return this._previousLeft === CLOSED_LEFT_POSITION && gestureState.dx > 0;
  },

  _swipeFullSpeed(gestureState: Object): void {
    this.state.currentLeft.setValue(this._previousLeft + gestureState.dx);
  },

  _swipeSlowSpeed(gestureState: Object): void {
    this.state.currentLeft.setValue(
      this._previousLeft + gestureState.dx / SLOW_SPEED_SWIPE_FACTOR,
    );
  },

  _isSwipingExcessivelyRightFromClosedPosition(gestureState: Object): boolean {
    /**
     * We want to allow a BIT of right swipe, to allow users to know that
     * swiping is available, but swiping right does not do anything
     * functionally.
     */
    return (
      this._isSwipingRightFromClosed(gestureState) &&
      gestureState.dx > RIGHT_SWIPE_THRESHOLD
    );
  },

  _onPanResponderTerminationRequest(
    event: Object,
    gestureState: Object,
  ): boolean {
    return false;
  },

  _animateTo(
    toValue: number,
    duration: number = SWIPE_DURATION,
    callback: Function = emptyFunction,
  ): void {
    Animated.timing(
      this.state.currentLeft,
      {
        duration,
        toValue,
      },
    ).start(() => {
      this._previousLeft = toValue;
      callback();
    });
  },

  _animateToOpenPosition(): void {
    this._animateTo(-this.props.maxSwipeDistance);
  },

  _animateToClosedPosition(duration: number = SWIPE_DURATION): void {
    this._animateTo(CLOSED_LEFT_POSITION, duration);
  },

  _animateToClosedPositionDuringBounce(): void {
    this._animateToClosedPosition(RIGHT_SWIPE_BOUNCE_BACK_DURATION);
  },

  _animateBounceBack(duration: number): void {
    /**
     * When swiping right, we want to bounce back past closed position on release
     * so users know they should swipe right to get content.
     */
    this._animateTo(
      -RIGHT_SWIPE_BOUNCE_BACK_DISTANCE,
      duration,
      this._animateToClosedPositionDuringBounce,
    );
  },

  // Ignore swipes due to user's finger moving slightly when tapping
  _isValidSwipe(gestureState: Object): boolean {
    return Math.abs(gestureState.dx) > HORIZONTAL_SWIPE_DISTANCE_THRESHOLD;
  },

  _shouldAnimateRemainder(gestureState: Object): boolean {
    /**
     * If user has swiped past a certain distance, animate the rest of the way
     * if they let go
     */
    return (
      Math.abs(gestureState.dx) > this.props.swipeThreshold ||
      gestureState.vx > HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD
    );
  },

  _handlePanResponderEnd(event: Object, gestureState: Object): void {
    const horizontalDistance = gestureState.dx;

    if (this._isSwipingRightFromClosed(gestureState)) {
      this.props.onOpen();
      this._animateBounceBack(RIGHT_SWIPE_BOUNCE_BACK_DURATION);
    } else if (this._shouldAnimateRemainder(gestureState)) {
      if (horizontalDistance < 0) {
        // Swiped left
        this.props.onOpen();
        this._animateToOpenPosition();
      } else {
        // Swiped right
        this._animateToClosedPosition();
      }
    } else {
      if (this._previousLeft === CLOSED_LEFT_POSITION) {
        this._animateToClosedPosition();
      } else {
        this._animateToOpenPosition();
      }
    }

    this.props.onSwipeEnd();
  },
});

const styles = StyleSheet.create({
  slideOutContainer: {
    bottom: 0,
    left: 0,
    position: 'absolute',
    right: 0,
    top: 0,
  },
  swipeableContainer: {
    flex: 1,
  },
});

module.exports = SwipeableRow;
<commit_msg>Provide RTL support for SwipeableRow<commit_after>/**
 * Copyright (c) 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * The examples provided by Facebook are for non-commercial testing and
 * evaluation purposes only.
 *
 * Facebook reserves all rights not expressly granted.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
 * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  *
 *
 * @providesModule SwipeableRow
 * @flow
 */
'use strict';

const Animated = require('Animated');
const PanResponder = require('PanResponder');
const React = require('React');
const StyleSheet = require('StyleSheet');
const TimerMixin = require('react-timer-mixin');
const View = require('View');

const {PropTypes} = React;

const emptyFunction = require('fbjs/lib/emptyFunction');

const I18nManager = require('NativeModules').I18nManager || {};
const IS_RTL = I18nManager.isRTL;

// NOTE: Eventually convert these consts to an input object of configurations

// Position of the left of the swipable item when closed
const CLOSED_LEFT_POSITION = 0;
// Minimum swipe distance before we recognize it as such
const HORIZONTAL_SWIPE_DISTANCE_THRESHOLD = 10;
// Minimum swipe speed before we fully animate the user's action (open/close)
const HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD = 0.3;
// Factor to divide by to get slow speed; i.e. 4 means 1/4 of full speed
const SLOW_SPEED_SWIPE_FACTOR = 4;
// Time, in milliseconds, of how long the animated swipe should be
const SWIPE_DURATION = 200;

/**
 * On SwipeableListView mount, the 1st item will bounce to show users it's
 * possible to swipe
 */
const ON_MOUNT_BOUNCE_DELAY = 700;
const ON_MOUNT_BOUNCE_DURATION = 400;

// Distance left of closed position to bounce back when right-swiping from closed
const RIGHT_SWIPE_BOUNCE_BACK_DISTANCE = 50;
const RIGHT_SWIPE_BOUNCE_BACK_DURATION = 400;
/**
 * Max distance of right swipe to allow (right swipes do functionally nothing).
 * Must be multiplied by SLOW_SPEED_SWIPE_FACTOR because gestureState.dx tracks
 * how far the finger swipes, and not the actual animation distance.
*/
const RIGHT_SWIPE_THRESHOLD = 30 * SLOW_SPEED_SWIPE_FACTOR;

/**
 * Creates a swipable row that allows taps on the main item and a custom View
 * on the item hidden behind the row. Typically this should be used in
 * conjunction with SwipeableListView for additional functionality, but can be
 * used in a normal ListView. See the renderRow for SwipeableListView to see how
 * to use this component separately.
 */
const SwipeableRow = React.createClass({
  _panResponder: {},
  _previousLeft: CLOSED_LEFT_POSITION,

  mixins: [TimerMixin],

  propTypes: {
    children: PropTypes.any,
    isOpen: PropTypes.bool,
    maxSwipeDistance: PropTypes.number.isRequired,
    onOpen: PropTypes.func.isRequired,
    onSwipeEnd: PropTypes.func.isRequired,
    onSwipeStart: PropTypes.func.isRequired,
    // Should bounce the row on mount
    shouldBounceOnMount: PropTypes.bool,
    /**
     * A ReactElement that is unveiled when the user swipes
     */
    slideoutView: PropTypes.node.isRequired,
    /**
     * The minimum swipe distance required before fully animating the swipe. If
     * the user swipes less than this distance, the item will return to its
     * previous (open/close) position.
     */
    swipeThreshold: PropTypes.number.isRequired,
  },

  getInitialState(): Object {
    return {
      currentLeft: new Animated.Value(this._previousLeft),
      /**
       * In order to render component A beneath component B, A must be rendered
       * before B. However, this will cause "flickering", aka we see A briefly
       * then B. To counter this, _isSwipeableViewRendered flag is used to set
       * component A to be transparent until component B is loaded.
       */
      isSwipeableViewRendered: false,
      rowHeight: (null: ?number),
    };
  },

  getDefaultProps(): Object {
    return {
      isOpen: false,
      maxSwipeDistance: 0,
      onOpen: emptyFunction,
      onSwipeEnd: emptyFunction,
      onSwipeStart: emptyFunction,
      swipeThreshold: 30,
    };
  },

  componentWillMount(): void {
    this._panResponder = PanResponder.create({
      onStartShouldSetPanResponder: (event, gestureState) => true,
      // Don't capture child's start events
      onStartShouldSetPanResponderCapture: (event, gestureState) => false,
      onMoveShouldSetPanResponder: (event, gestureState) => false,
      onMoveShouldSetPanResponderCapture: this._handleMoveShouldSetPanResponderCapture,
      onPanResponderGrant: this._handlePanResponderGrant,
      onPanResponderMove: this._handlePanResponderMove,
      onPanResponderRelease: this._handlePanResponderEnd,
      onPanResponderTerminationRequest: this._onPanResponderTerminationRequest,
      onPanResponderTerminate: this._handlePanResponderEnd,
    });
  },

  componentDidMount(): void {
    if (this.props.shouldBounceOnMount) {
      /**
       * Do the on mount bounce after a delay because if we animate when other
       * components are loading, the animation will be laggy
       */
      this.setTimeout(() => {
        this._animateBounceBack(ON_MOUNT_BOUNCE_DURATION);
      }, ON_MOUNT_BOUNCE_DELAY);
    }
  },

  componentWillReceiveProps(nextProps: Object): void {
    /**
     * We do not need an "animateOpen(noCallback)" because this animation is
     * handled internally by this component.
     */
    if (this.props.isOpen && !nextProps.isOpen) {
      this._animateToClosedPosition();
    }
  },

  shouldComponentUpdate(nextProps: Object, nextState: Object): boolean {
    if (this.props.shouldBounceOnMount && !nextProps.shouldBounceOnMount) {
      // No need to rerender if SwipeableListView is disabling the bounce flag
      return false;
    }

    return true;
  },

  render(): ReactElement<any> {
    // The view hidden behind the main view
    let slideOutView;
    if (this.state.isSwipeableViewRendered) {
      slideOutView = (
        <View style={[
          styles.slideOutContainer,
          {height: this.state.rowHeight},
          ]}>
          {this.props.slideoutView}
        </View>
      );
    }

    // The swipeable item
    const swipeableView = (
      <Animated.View
        onLayout={this._onSwipeableViewLayout}
        style={[
          styles.swipeableContainer,
          {
            transform: [{translateX: this.state.currentLeft}],
          },
        ]}>
        {this.props.children}
      </Animated.View>
    );

    return (
      <View
        {...this._panResponder.panHandlers}>
        {slideOutView}
        {swipeableView}
      </View>
    );
  },

  _onSwipeableViewLayout(event: Object): void {
    this.setState({
      isSwipeableViewRendered: true,
      rowHeight: event.nativeEvent.layout.height,
    });
  },

  _handleMoveShouldSetPanResponderCapture(
    event: Object,
    gestureState: Object,
  ): boolean {
    // Decides whether a swipe is responded to by this component or its child
    return gestureState.dy < 10 && this._isValidSwipe(gestureState);
  },

  _handlePanResponderGrant(event: Object, gestureState: Object): void {

  },

  _handlePanResponderMove(event: Object, gestureState: Object): void {
    if (this._isSwipingExcessivelyRightFromClosedPosition(gestureState)) {
      return;
    }

    this.props.onSwipeStart();

    if (this._isSwipingRightFromClosed(gestureState)) {
      this._swipeSlowSpeed(gestureState);
    } else {
      this._swipeFullSpeed(gestureState);
    }
  },

  _isSwipingRightFromClosed(gestureState: Object): boolean {
    const gestureStateDx = IS_RTL ? -gestureState.dx : gestureState.dx;
    return this._previousLeft === CLOSED_LEFT_POSITION && gestureStateDx > 0;
  },

  _swipeFullSpeed(gestureState: Object): void {
    this.state.currentLeft.setValue(this._previousLeft + gestureState.dx);
  },

  _swipeSlowSpeed(gestureState: Object): void {
    this.state.currentLeft.setValue(
      this._previousLeft + gestureState.dx / SLOW_SPEED_SWIPE_FACTOR,
    );
  },

  _isSwipingExcessivelyRightFromClosedPosition(gestureState: Object): boolean {
    /**
     * We want to allow a BIT of right swipe, to allow users to know that
     * swiping is available, but swiping right does not do anything
     * functionally.
     */
    const gestureStateDx = IS_RTL ? -gestureState.dx : gestureState.dx;
    return (
      this._isSwipingRightFromClosed(gestureState) &&
      gestureStateDx > RIGHT_SWIPE_THRESHOLD
    );
  },

  _onPanResponderTerminationRequest(
    event: Object,
    gestureState: Object,
  ): boolean {
    return false;
  },

  _animateTo(
    toValue: number,
    duration: number = SWIPE_DURATION,
    callback: Function = emptyFunction,
  ): void {
    Animated.timing(
      this.state.currentLeft,
      {
        duration,
        toValue,
      },
    ).start(() => {
      this._previousLeft = toValue;
      callback();
    });
  },

  _animateToOpenPosition(): void {
    const maxSwipeDistance = IS_RTL ? -this.props.maxSwipeDistance : this.props.maxSwipeDistance;
    this._animateTo(-maxSwipeDistance);
  },

  _animateToClosedPosition(duration: number = SWIPE_DURATION): void {
    this._animateTo(CLOSED_LEFT_POSITION, duration);
  },

  _animateToClosedPositionDuringBounce(): void {
    this._animateToClosedPosition(RIGHT_SWIPE_BOUNCE_BACK_DURATION);
  },

  _animateBounceBack(duration: number): void {
    /**
     * When swiping right, we want to bounce back past closed position on release
     * so users know they should swipe right to get content.
     */
    const swipeBounceBackDistance = IS_RTL ? -RIGHT_SWIPE_BOUNCE_BACK_DISTANCE : RIGHT_SWIPE_BOUNCE_BACK_DISTANCE;
    this._animateTo(
      -swipeBounceBackDistance,
      duration,
      this._animateToClosedPositionDuringBounce,
    );
  },

  // Ignore swipes due to user's finger moving slightly when tapping
  _isValidSwipe(gestureState: Object): boolean {
    return Math.abs(gestureState.dx) > HORIZONTAL_SWIPE_DISTANCE_THRESHOLD;
  },

  _shouldAnimateRemainder(gestureState: Object): boolean {
    /**
     * If user has swiped past a certain distance, animate the rest of the way
     * if they let go
     */
    return (
      Math.abs(gestureState.dx) > this.props.swipeThreshold ||
      gestureState.vx > HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD
    );
  },

  _handlePanResponderEnd(event: Object, gestureState: Object): void {
    const horizontalDistance = IS_RTL ? -gestureState.dx : gestureState.dx;
    if (this._isSwipingRightFromClosed(gestureState)) {
      this.props.onOpen();
      this._animateBounceBack(RIGHT_SWIPE_BOUNCE_BACK_DURATION);
    } else if (this._shouldAnimateRemainder(gestureState)) {
      if (horizontalDistance < 0) {
        // Swiped left
        this.props.onOpen();
        this._animateToOpenPosition();
      } else {
        // Swiped right
        this._animateToClosedPosition();
      }
    } else {
      if (this._previousLeft === CLOSED_LEFT_POSITION) {
        this._animateToClosedPosition();
      } else {
        this._animateToOpenPosition();
      }
    }

    this.props.onSwipeEnd();
  },
});

const styles = StyleSheet.create({
  slideOutContainer: {
    bottom: 0,
    left: 0,
    position: 'absolute',
    right: 0,
    top: 0,
  },
  swipeableContainer: {
    flex: 1,
  },
});

module.exports = SwipeableRow;
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015-present, Alibaba Group Holding Limited.
 * All rights reserved.
 *
 * Copyright (c) 2015, Facebook, Inc.  All rights reserved.
 *
 * @providesModule ReactTouchableWithoutFeedback
 */
'use strict';

import 'ReactPanResponder';
import React, { Component } from 'react';
import Touchable from 'ReactTouchable';
import mixin from 'react-mixin';
import autobind from 'autobind-decorator';

/**
 * When the scroll view is disabled, this defines how far your touch may move
 * off of the button, before deactivating the button. Once deactivated, try
 * moving it back and you'll see that the button is once again reactivated!
 * Move it back and forth several times while the scroll view is disabled.
 */
var PRESS_RECT_OFFSET = {
  top: 20,
  left: 20,
  right: 20,
  bottom: 30
};

/**
 * Do not use unless you have a very good reason. All the elements that
 * respond to press should have a visual feedback when touched. This is
 * one of the primary reason a "web" app doesn't feel "native".
 */
class TouchableWithoutFeedback extends Component {

  static propTypes = {
    /**
     * Called when the touch is released, but not if cancelled (e.g. by a scroll
     * that steals the responder lock).
     */
    onPress: React.PropTypes.func,
    onPressIn: React.PropTypes.func,
    onPressOut: React.PropTypes.func,

    onLongPress: React.PropTypes.func,

    /**
     * Delay in ms, from the start of the touch, before onPressIn is called.
     */
    delayPressIn: React.PropTypes.number,
    /**
     * Delay in ms, from the release of the touch, before onPressOut is called.
     */
    delayPressOut: React.PropTypes.number,
    /**
     * Delay in ms, from onPressIn, before onLongPress is called.
     */
    delayLongPress: React.PropTypes.number,
  }

  state = this.touchableGetInitialState()

  // componentDidMount: function() {
    // ensurePositiveDelayProps(this.props);
  // },

  componentWillReceiveProps(nextProps: Object) {
    // ensurePositiveDelayProps(nextProps);
  }

  /**
   * `Touchable.Mixin` self callbacks. The mixin will invoke these if they are
   * defined on your component.
   */
  touchableHandlePress(e: Event) {
    var touchBank = e.touchHistory.touchBank[e.touchHistory.touchBank.length - 1];
    var offset = Math.sqrt(Math.pow(touchBank.startPageX - touchBank.currentPageX, 2)
        + Math.pow(touchBank.startPageY - touchBank.currentPageY, 2));
    var velocity = (offset / (touchBank.currentTimeStamp - touchBank.startTimeStamp)) * 1000;
    if (velocity < 100) this.props.onPress && this.props.onPress(e);
  }

  touchableHandleActivePressIn(e: Event) {
    this.props.onPressIn && this.props.onPressIn(e);
  }

  touchableHandleActivePressOut(e: Event) {
    this.props.onPressOut && this.props.onPressOut(e);
  }

  touchableHandleLongPress(e: Event) {
    this.props.onLongPress && this.props.onLongPress(e);
  }

  touchableGetPressRectOffset(): typeof PRESS_RECT_OFFSET {
    return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant!
  }

  touchableGetHighlightDelayMS(): number {
    return this.props.delayPressIn || 0;
  }

  touchableGetLongPressDelayMS(): number {
    return this.props.delayLongPress === 0 ? 0 :
      this.props.delayLongPress || 500;
  }

  touchableGetPressOutDelayMS(): number {
    return this.props.delayPressOut || 0;
  }

  render(): ReactElement {
    // Note(avik): remove dynamic typecast once Flow has been upgraded
    return (React: any).cloneElement(React.Children.only(this.props.children), {
      onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder,
      onResponderTerminationRequest: this.touchableHandleResponderTerminationRequest,
      onResponderGrant: this.touchableHandleResponderGrant,
      onResponderMove: this.touchableHandleResponderMove,
      onResponderRelease: this.touchableHandleResponderRelease,
      onResponderTerminate: this.touchableHandleResponderTerminate
    });
  }

};

mixin.onClass(TouchableWithoutFeedback, Touchable.Mixin);
autobind(TouchableWithoutFeedback);

module.exports = TouchableWithoutFeedback;
<commit_msg>修复ios平台浏览器中touchHistory长度与安装平台不一致引起的不兼容问题<commit_after>/**
 * Copyright (c) 2015-present, Alibaba Group Holding Limited.
 * All rights reserved.
 *
 * Copyright (c) 2015, Facebook, Inc.  All rights reserved.
 *
 * @providesModule ReactTouchableWithoutFeedback
 */
'use strict';

import 'ReactPanResponder';
import React, { Component } from 'react';
import Touchable from 'ReactTouchable';
import mixin from 'react-mixin';
import autobind from 'autobind-decorator';

/**
 * When the scroll view is disabled, this defines how far your touch may move
 * off of the button, before deactivating the button. Once deactivated, try
 * moving it back and you'll see that the button is once again reactivated!
 * Move it back and forth several times while the scroll view is disabled.
 */
var PRESS_RECT_OFFSET = {
  top: 20,
  left: 20,
  right: 20,
  bottom: 30
};

/**
 * Do not use unless you have a very good reason. All the elements that
 * respond to press should have a visual feedback when touched. This is
 * one of the primary reason a "web" app doesn't feel "native".
 */
class TouchableWithoutFeedback extends Component {

  static propTypes = {
    /**
     * Called when the touch is released, but not if cancelled (e.g. by a scroll
     * that steals the responder lock).
     */
    onPress: React.PropTypes.func,
    onPressIn: React.PropTypes.func,
    onPressOut: React.PropTypes.func,

    onLongPress: React.PropTypes.func,

    /**
     * Delay in ms, from the start of the touch, before onPressIn is called.
     */
    delayPressIn: React.PropTypes.number,
    /**
     * Delay in ms, from the release of the touch, before onPressOut is called.
     */
    delayPressOut: React.PropTypes.number,
    /**
     * Delay in ms, from onPressIn, before onLongPress is called.
     */
    delayLongPress: React.PropTypes.number,
  }

  state = this.touchableGetInitialState()

  // componentDidMount: function() {
    // ensurePositiveDelayProps(this.props);
  // },

  componentWillReceiveProps(nextProps: Object) {
    // ensurePositiveDelayProps(nextProps);
  }

  /**
   * `Touchable.Mixin` self callbacks. The mixin will invoke these if they are
   * defined on your component.
   */
  touchableHandlePress(e: Event) {
    var touchBank = e.touchHistory.touchBank[e.touchHistory.indexOfSingleActiveTouch];
    var offset = Math.sqrt(Math.pow(touchBank.startPageX - touchBank.currentPageX, 2)
        + Math.pow(touchBank.startPageY - touchBank.currentPageY, 2));
    var velocity = (offset / (touchBank.currentTimeStamp - touchBank.startTimeStamp)) * 1000;
    if (velocity < 100) this.props.onPress && this.props.onPress(e);
  }

  touchableHandleActivePressIn(e: Event) {
    this.props.onPressIn && this.props.onPressIn(e);
  }

  touchableHandleActivePressOut(e: Event) {
    this.props.onPressOut && this.props.onPressOut(e);
  }

  touchableHandleLongPress(e: Event) {
    this.props.onLongPress && this.props.onLongPress(e);
  }

  touchableGetPressRectOffset(): typeof PRESS_RECT_OFFSET {
    return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant!
  }

  touchableGetHighlightDelayMS(): number {
    return this.props.delayPressIn || 0;
  }

  touchableGetLongPressDelayMS(): number {
    return this.props.delayLongPress === 0 ? 0 :
      this.props.delayLongPress || 500;
  }

  touchableGetPressOutDelayMS(): number {
    return this.props.delayPressOut || 0;
  }

  render(): ReactElement {
    // Note(avik): remove dynamic typecast once Flow has been upgraded
    return (React: any).cloneElement(React.Children.only(this.props.children), {
      onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder,
      onResponderTerminationRequest: this.touchableHandleResponderTerminationRequest,
      onResponderGrant: this.touchableHandleResponderGrant,
      onResponderMove: this.touchableHandleResponderMove,
      onResponderRelease: this.touchableHandleResponderRelease,
      onResponderTerminate: this.touchableHandleResponderTerminate
    });
  }

};

mixin.onClass(TouchableWithoutFeedback, Touchable.Mixin);
autobind(TouchableWithoutFeedback);

module.exports = TouchableWithoutFeedback;
<|endoftext|>


<commit_before>define(['sprd/data/SprdModel'], function (SprdModel) {
	return SprdModel.inherit('sprd.model.Design', {
		defaults : {
			name         : '',
			description  : '',
			restrictions : null
		},

        schema: {
            name: String,
            description: String,
            type: String
        }
    });

});<commit_msg>added PrintTypes to Schema of Design<commit_after>define(['sprd/data/SprdModel', 'sprd/model/PrintType'], function (SprdModel, PrintType) {
	return SprdModel.inherit('sprd.model.Design', {
		defaults : {
			name         : '',
			description  : '',
			restrictions : null
		},

        schema: {
            name: String,
            description: String,
            printTypes: [PrintType]
        }
    });

});<|endoftext|>


<commit_before>import React from 'react';
import _ from 'lodash';
import { connect as reduxConnect } from 'react-redux';
import reduxOkapi from 'redux-okapi';
import * as localstate from './localstate';
import * as okapi from './okapi';
import Wrapping from './ComponentWrapping';

class Wrapper extends React.Component {
  render() {
    return React.createElement(this.props.wrapped);
  }
};

// TODO: This should move to provider or store somehow
//
// Current keys:
//   addReducer(<state key>, <reducer function>)
let config = {};
export const init = newConfig => Object.assign(config, newConfig);

export const connect = (Component, module) => {
  if (!config.addReducer) {
    throw new Error('stripes-connect not configured---please call init() first');
  }
  const addReducer = config.addReducer;
  const manifest = Component.manifest;
  const resources = Object.keys(manifest);

  _.forOwn(manifest, (query, resource) => {
    if (query.remote) {
      addReducer(resource, okapi.reducerFor(resource, module));
    } else {
      addReducer(`${module}-${resource}`, localstate.reducerFor(resource, module));
    }
  });

  const mapStateToProps = (state) => {
    return resources.reduce((result, resource) => {
      const query = manifest[resource];
      if (query.remote) {
        result[resource] = _.get(state, [resource], null);
      } else {
        result[resource] = _.get(state, [`${module}-${resource}`], null);
      }
      return result;
    }, {});
  }

  const mapDispatchToProps = (dispatch) => {
    return {
      mutator: resources.reduce((result, resource) => {
        const query = manifest[resource];
        if (query.remote) {
          result[resource] = okapi.mutatorFor(resource, module, dispatch);
        } else {
          result[resource] = localstate.mutatorFor(resource, module, dispatch);
        }
        return result;
      }, {}),
      refreshRemote: (params) => {
        _.forOwn(manifest, (query, resource) => {
          if (query.remote) {
            let overrides = {};
            if (query.suffix && query.suffix.startsWith(":")) {
              let suffix = query.suffix.substring(1);
              overrides = { suffix : "/"+params[suffix]};
            }
            dispatch(reduxOkapi.actions.fetch(resource,overrides));
          }
        });
      }
    };
  }
  let WrappedComponent = Wrapping(Component);
  const connectedComponent = reduxConnect(mapStateToProps, mapDispatchToProps)(WrappedComponent);
  return connectedComponent;
};

<commit_msg>Removes obsolete code<commit_after>import React from 'react';
import _ from 'lodash';
import { connect as reduxConnect } from 'react-redux';
import reduxOkapi from 'redux-okapi';
import * as localstate from './localstate';
import * as okapi from './okapi';
import Wrapping from './ComponentWrapping';

// TODO: This should move to provider or store somehow
//
// Current keys:
//   addReducer(<state key>, <reducer function>)
let config = {};
export const init = newConfig => Object.assign(config, newConfig);

export const connect = (Component, module) => {
  if (!config.addReducer) {
    throw new Error('stripes-connect not configured---please call init() first');
  }
  const addReducer = config.addReducer;
  const manifest = Component.manifest;
  const resources = Object.keys(manifest);

  _.forOwn(manifest, (query, resource) => {
    if (query.remote) {
      addReducer(resource, okapi.reducerFor(resource, module));
    } else {
      addReducer(`${module}-${resource}`, localstate.reducerFor(resource, module));
    }
  });

  const mapStateToProps = (state) => {
    return resources.reduce((result, resource) => {
      const query = manifest[resource];
      if (query.remote) {
        result[resource] = _.get(state, [resource], null);
      } else {
        result[resource] = _.get(state, [`${module}-${resource}`], null);
      }
      return result;
    }, {});
  }

  const mapDispatchToProps = (dispatch) => {
    return {
      mutator: resources.reduce((result, resource) => {
        const query = manifest[resource];
        if (query.remote) {
          result[resource] = okapi.mutatorFor(resource, module, dispatch);
        } else {
          result[resource] = localstate.mutatorFor(resource, module, dispatch);
        }
        return result;
      }, {}),
      refreshRemote: (params) => {
        _.forOwn(manifest, (query, resource) => {
          if (query.remote) {
            let overrides = {};
            if (query.suffix && query.suffix.startsWith(":")) {
              let suffix = query.suffix.substring(1);
              overrides = { suffix : "/"+params[suffix]};
            }
            dispatch(reduxOkapi.actions.fetch(resource,overrides));
          }
        });
      }
    };
  }
  let WrappedComponent = Wrapping(Component);
  const connectedComponent = reduxConnect(mapStateToProps, mapDispatchToProps)(WrappedComponent);
  return connectedComponent;
};

<|endoftext|>