<commit_before>/**
 * Angular JS multiple-selection module
 * @author Maksym Pomazan
 * @version 0.0.3
 */
function getSelectableElements(element) {
    var out = [];
    var childs = element.children();
    for (var i = 0; i < childs.length; i++) {
        var child = angular.element(childs[i]);
        if (child.scope().isSelectable) {
            out.push(child);
        } else {
            if (child.scope().$id!=element.scope().$id && child.scope().isSelectableZone === true) {

            } else {
                out = out.concat(getSelectableElements(child));
            }
        }
    }
    return out;
}

function offset(element) {
    var documentElem,
        box = {
            top: 0,
            left: 0
        },
        doc = element && element.ownerDocument;
    documentElem = doc.documentElement;

    if (typeof element.getBoundingClientRect !== undefined) {
        box = element.getBoundingClientRect();
    }

    return {
        top: box.top + (window.pageYOffset || documentElem.scrollTop) - (documentElem.clientTop || 0),
        left: box.left + (window.pageXOffset || documentElem.scrollLeft) - (documentElem.clientLeft || 0)
    };
}
angular.module('multipleSelection', [])
    .directive('multipleSelectionItem', [function() {
        return {
            scope: true,
            restrict: 'A',
            link: function(scope, element, iAttrs, controller) {

                scope.isSelectable = true;
                scope.isSelecting = false;
                scope.isSelected = false;

                element.on('mousedown', function(event) {
                    if (element.scope().isSelected) {
                        if (event.ctrlKey) {
                            element.scope().isSelected = false;
                            element.scope().$apply();
                        }
                    } else {
                        if (!event.ctrlKey) {
                            var childs = getSelectableElements(element.parent());
                            for (var i = 0; i < childs.length; i++) {
                                if (childs[i].scope().isSelectable) {
                                    if (childs[i].scope().isSelecting === true || childs[i].scope().isSelected === true) {
                                        childs[i].scope().isSelecting = false;
                                        childs[i].scope().isSelected = false;
                                        childs[i].scope().$apply();
                                    }
                                }
                            }
                        }
                        element.scope().isSelected = true;
                        element.scope().$apply();

                    }
                    event.stopPropagation();
                });
            }
        };
    }])
    .directive('multipleSelectionZone', ['$document', function($document) {
        return {
            scope: true,
            restrict: 'A',
            link: function(scope, element, iAttrs, controller) {

                scope.isSelectableZone = true;

                var startX = 0,
                    startY = 0;
                var helper;

                /**
                 * Check that 2 boxes hitting
                 * @param  {Object} box1
                 * @param  {Object} box2
                 * @return {Boolean} is hitting
                 */
                function checkElementHitting(box1, box2) {
                    return (box2.beginX <= box1.beginX && box1.beginX <= box2.endX || box1.beginX <= box2.beginX && box2.beginX <= box1.endX) &&
                        (box2.beginY <= box1.beginY && box1.beginY <= box2.endY || box1.beginY <= box2.beginY && box2.beginY <= box1.endY);
                }

                /**
                 * Transform box to object to:
                 *  beginX is always be less then endX
                 *  beginY is always be less then endY
                 * @param  {Number} startX
                 * @param  {Number} startY
                 * @param  {Number} endX
                 * @param  {Number} endY
                 * @return {Object} result Transformed object
                 */
                function transformBox(startX, startY, endX, endY) {

                    var result = {};

                    if (startX > endX) {
                        result.beginX = endX;
                        result.endX = startX;
                    } else {
                        result.beginX = startX;
                        result.endX = endX;
                    }
                    if (startY > endY) {
                        result.beginY = endY;
                        result.endY = startY;
                    } else {
                        result.beginY = startY;
                        result.endY = endY;
                    }
                    return result;
                }

                /**
                 * Method move selection helper
                 * @param  {Element} hepler
                 * @param  {Number} startX
                 * @param  {Number} startY
                 * @param  {Number} endX
                 * @param  {Number} endY
                 */
                function moveSelectionHelper(hepler, startX, startY, endX, endY) {

                    var box = transformBox(startX, startY, endX, endY);

                    helper.css({
                        "top": box.beginY + "px",
                        "left": box.beginX + "px",
                        "width": (box.endX - box.beginX) + "px",
                        "height": (box.endY - box.beginY) + "px"
                    });
                }

                /**
                 * Method on Mouse Move
                 * @param  {Event} @event
                 */
                function mousemove(event) {
                    // Prevent default dragging of selected content
                    event.preventDefault();
                    // Move helper
                    moveSelectionHelper(helper, startX, startY, event.pageX, event.pageY);
                    // Check items is selecting
                    var childs = getSelectableElements(element);
                    for (var i = 0; i < childs.length; i++) {
                        if (checkElementHitting(transformBox(offset(childs[i][0]).left, offset(childs[i][0]).top, offset(childs[i][0]).left + childs[i].prop('offsetWidth'), offset(childs[i][0]).top + childs[i].prop('offsetHeight')), transformBox(startX, startY, event.pageX, event.pageY))) {
                            if (childs[i].scope().isSelecting === false) {
                                childs[i].scope().isSelecting = true;
                                childs[i].scope().$apply();
                            }
                        } else {
                            if (childs[i].scope().isSelecting === true) {
                                childs[i].scope().isSelecting = false;
                                childs[i].scope().$apply();
                            }
                        }
                    }
                }

                /**
                 * Event on Mouse up
                 * @param  {Event} event
                 */
                function mouseup(event) {
                    // Prevent default dragging of selected content
                    event.preventDefault();
                    // Remove helper
                    helper.remove();
                    // Change all selecting items to selected
                    var childs = getSelectableElements(element);

                    for (var i = 0; i < childs.length; i++) {
                        if (childs[i].scope().isSelecting === true) {
                            childs[i].scope().isSelecting = false;

                            childs[i].scope().isSelected = event.ctrlKey ? !childs[i].scope().isSelected : true;
                            childs[i].scope().$apply();
                        } else {
                            if (checkElementHitting(transformBox(childs[i].prop('offsetLeft'), childs[i].prop('offsetTop'), childs[i].prop('offsetLeft') + childs[i].prop('offsetWidth'), childs[i].prop('offsetTop') + childs[i].prop('offsetHeight')), transformBox(event.pageX, event.pageY, event.pageX, event.pageY))) {
                                if (childs[i].scope().isSelected === false) {
                                    childs[i].scope().isSelected = true;
                                    childs[i].scope().$apply();
                                }
                            }
                        }
                    }
                    // Remove listeners
                    $document.off('mousemove', mousemove);
                    $document.off('mouseup', mouseup);
                }

                element.on('mousedown', function(event) {
                    // Prevent default dragging of selected content
                    event.preventDefault();
                    if (!event.ctrlKey) {
                        // Skip all selected or selecting items
                        var childs = getSelectableElements(element);
                        for (var i = 0; i < childs.length; i++) {
                            if (childs[i].scope().isSelecting === true || childs[i].scope().isSelected === true) {
                                childs[i].scope().isSelecting = false;
                                childs[i].scope().isSelected = false;
                                childs[i].scope().$apply();
                            }
                        }
                    }
                    // Update start coordinates
                    startX = event.pageX;
                    startY = event.pageY;
                    // Create helper
                    helper = angular
                        .element("

")
                        .addClass('select-helper');

                    $document.find('body').eq(0).append(helper);
                    // Attach events
                    $document.on('mousemove', mousemove);
                    $document.on('mouseup', mouseup);
                });
            }
        };
    }]);
<commit_msg>select bug<commit_after>/**
 * Angular JS multiple-selection module
 * @author Maksym Pomazan
 * @version 0.0.3
 */
function getSelectableElements(element) {
    var out = [];
    var childs = element.children();
    for (var i = 0; i < childs.length; i++) {
        var child = angular.element(childs[i]);
        if (child.scope().isSelectable) {
            out.push(child);
        } else {
            if (child.scope().$id!=element.scope().$id && child.scope().isSelectableZone === true) {

            } else {
                out = out.concat(getSelectableElements(child));
            }
        }
    }
    return out;
}

function offset(element) {
    var documentElem,
        box = {
            top: 0,
            left: 0
        },
        doc = element && element.ownerDocument;
    documentElem = doc.documentElement;

    if (typeof element.getBoundingClientRect !== undefined) {
        box = element.getBoundingClientRect();
    }

    return {
        top: box.top + (window.pageYOffset || documentElem.scrollTop) - (documentElem.clientTop || 0),
        left: box.left + (window.pageXOffset || documentElem.scrollLeft) - (documentElem.clientLeft || 0)
    };
}
angular.module('multipleSelection', [])
    .directive('multipleSelectionItem', [function() {
        return {
            scope: true,
            restrict: 'A',
            link: function(scope, element, iAttrs, controller) {

                scope.isSelectable = true;
                scope.isSelecting = false;
                scope.isSelected = false;

                element.on('mousedown', function(event) {
                    if (element.scope().isSelected) {
                        if (event.ctrlKey) {
                            element.scope().isSelected = false;
                            element.scope().$apply();
                        }
                    } else {
                        if (!event.ctrlKey) {
                            var childs = getSelectableElements(element.parent());
                            for (var i = 0; i < childs.length; i++) {
                                if (childs[i].scope().isSelectable) {
                                    if (childs[i].scope().isSelecting === true || childs[i].scope().isSelected === true) {
                                        childs[i].scope().isSelecting = false;
                                        childs[i].scope().isSelected = false;
                                        childs[i].scope().$apply();
                                    }
                                }
                            }
                        }
                        element.scope().isSelected = true;
                        element.scope().$apply();

                    }
                    event.stopPropagation();
                });
            }
        };
    }])
    .directive('multipleSelectionZone', ['$document', function($document) {
        return {
            scope: true,
            restrict: 'A',
            link: function(scope, element, iAttrs, controller) {

                scope.isSelectableZone = true;

                var startX = 0,
                    startY = 0;
                var helper;

                /**
                 * Check that 2 boxes hitting
                 * @param  {Object} box1
                 * @param  {Object} box2
                 * @return {Boolean} is hitting
                 */
                function checkElementHitting(box1, box2) {
                    return (box2.beginX <= box1.beginX && box1.beginX <= box2.endX || box1.beginX <= box2.beginX && box2.beginX <= box1.endX) &&
                        (box2.beginY <= box1.beginY && box1.beginY <= box2.endY || box1.beginY <= box2.beginY && box2.beginY <= box1.endY);
                }

                /**
                 * Transform box to object to:
                 *  beginX is always be less then endX
                 *  beginY is always be less then endY
                 * @param  {Number} startX
                 * @param  {Number} startY
                 * @param  {Number} endX
                 * @param  {Number} endY
                 * @return {Object} result Transformed object
                 */
                function transformBox(startX, startY, endX, endY) {

                    var result = {};

                    if (startX > endX) {
                        result.beginX = endX;
                        result.endX = startX;
                    } else {
                        result.beginX = startX;
                        result.endX = endX;
                    }
                    if (startY > endY) {
                        result.beginY = endY;
                        result.endY = startY;
                    } else {
                        result.beginY = startY;
                        result.endY = endY;
                    }
                    return result;
                }

                /**
                 * Method move selection helper
                 * @param  {Element} hepler
                 * @param  {Number} startX
                 * @param  {Number} startY
                 * @param  {Number} endX
                 * @param  {Number} endY
                 */
                function moveSelectionHelper(hepler, startX, startY, endX, endY) {

                    var box = transformBox(startX, startY, endX, endY);

                    helper.css({
                        "top": box.beginY + "px",
                        "left": box.beginX + "px",
                        "width": (box.endX - box.beginX) + "px",
                        "height": (box.endY - box.beginY) + "px"
                    });
                }

                /**
                 * Method on Mouse Move
                 * @param  {Event} @event
                 */
                function mousemove(event) {
                    // Prevent default dragging of selected content
                    event.preventDefault();
                    // Move helper
                    moveSelectionHelper(helper, startX, startY, event.pageX, event.pageY);
                    // Check items is selecting
                    var childs = getSelectableElements(element);
                    for (var i = 0; i < childs.length; i++) {
                        if (checkElementHitting(transformBox(offset(childs[i][0]).left, offset(childs[i][0]).top, offset(childs[i][0]).left + childs[i].prop('offsetWidth'), offset(childs[i][0]).top + childs[i].prop('offsetHeight')), transformBox(startX, startY, event.pageX, event.pageY))) {
                            if (childs[i].scope().isSelecting === false) {
                                childs[i].scope().isSelecting = true;
                                childs[i].scope().$apply();
                            }
                        } else {
                            if (childs[i].scope().isSelecting === true) {
                                childs[i].scope().isSelecting = false;
                                childs[i].scope().$apply();
                            }
                        }
                    }
                }

                /**
                 * Event on Mouse up
                 * @param  {Event} event
                 */
                function mouseup(event) {
                    // Prevent default dragging of selected content
                    event.preventDefault();
                    // Remove helper
                    helper.remove();
                    // Change all selecting items to selected
                    var childs = getSelectableElements(element);

                    for (var i = 0; i < childs.length; i++) {
                        if (childs[i].scope().isSelecting === true) {
                            childs[i].scope().isSelecting = false;

                            childs[i].scope().isSelected = event.ctrlKey ? !childs[i].scope().isSelected : true;
                            childs[i].scope().$apply();
                        } else {
                            if (checkElementHitting(transformBox(offset(childs[i][0]).left, offset(childs[i][0]).top, offset(childs[i][0]).left + childs[i].prop('offsetWidth'), offset(childs[i][0]).top + childs[i].prop('offsetHeight')), transformBox(startX, startY, event.pageX, event.pageY))) {
                                if (childs[i].scope().isSelected === false) {
                                    childs[i].scope().isSelected = true;
                                    childs[i].scope().$apply();
                                }
                            }
                        }
                    }
                    // Remove listeners
                    $document.off('mousemove', mousemove);
                    $document.off('mouseup', mouseup);
                }

                element.on('mousedown', function(event) {
                    // Prevent default dragging of selected content
                    event.preventDefault();
                    if (!event.ctrlKey) {
                        // Skip all selected or selecting items
                        var childs = getSelectableElements(element);
                        for (var i = 0; i < childs.length; i++) {
                            if (childs[i].scope().isSelecting === true || childs[i].scope().isSelected === true) {
                                childs[i].scope().isSelecting = false;
                                childs[i].scope().isSelected = false;
                                childs[i].scope().$apply();
                            }
                        }
                    }
                    // Update start coordinates
                    startX = event.pageX;
                    startY = event.pageY;
                    // Create helper
                    helper = angular
                        .element("

")
                        .addClass('select-helper');

                    $document.find('body').eq(0).append(helper);
                    // Attach events
                    $document.on('mousemove', mousemove);
                    $document.on('mouseup', mouseup);
                });
            }
        };
    }]);
<|endoftext|>


<commit_before>/* @flow */

export const DiffURI = 'atom://git/diff/'

export type ObjectMap<V> = { [key: string]: V }

export function ifNotNull <T, U> (a: ?T, fn: (a: T) => U): ?U {
  if (a) {
    return fn(a)
  } else {
    return null
  }
}

export function unnull <T> (x: ?T): T {
  // The whole point of this function is to coerce a nullable to a non-null,
  // which isn't type safe. So tell Flow to keep quiet about it.
  // $FlowSilence
  return x
}

export function findFirst <T> (array: Array<T>, pred: (arg: T) => boolean): ?T {
  for (const item of array) {
    if (pred(item)) return item
  }

  return null
}
<commit_msg>Don't need this anymore.<commit_after>/* @flow */

export const DiffURI = 'atom://git/diff/'

export type ObjectMap<V> = { [key: string]: V }

export function ifNotNull <T, U> (a: ?T, fn: (a: T) => U): ?U {
  if (a) {
    return fn(a)
  } else {
    return null
  }
}

export function unnull <T> (x: ?T): T {
  // The whole point of this function is to coerce a nullable to a non-null,
  // which isn't type safe. So tell Flow to keep quiet about it.
  // $FlowSilence
  return x
}
<|endoftext|>


<commit_before>'use strict';

const OFF = 'off';
const ERROR = 'error';
const WARN = 'warn';

const COMPLEXITY_MAX = 5;
const TABWIDTH = 2;
const NESTED_CALLBACK_MAX = 4;
const ARGUMENTS_MAX = 4;

module.exports = {
  extends: 'eslint:recommended',
  env: {
    node: true,
  },
  globals: {
    require: false,
    module: false,
  },
  parserOptions: {
    ecmaVersion: 6,
    sourceType: 'script',
    arrowFunctions: true,
    binaryLiterals: true,
    blockBindings: true,
    classes: false,
    defaultParams: true,
    destructuring: true,
    forOf: true,
    generators: false,
    modules: false,
    objectLiteralComputedProperties: true,
    objectLiteralDuplicateProperties: true,
    objectLiteralShorthandMethods: true,
    objectLiteralShorthandProperties: true,
    octalLiterals: false,
    regexUFlag: true,
    regexYFlag: true,
    restParams: true,
    spread: true,
    superInFunctions: true,
    templateStrings: true,
    unicodeCodePointEscapes: true,
  },
  rules: {
    'accessor-pairs': [ERROR, { getWithoutSet: false, setWithoutGet: true }],
    'array-bracket-newline': OFF,
    'array-bracket-spacing': [ERROR, 'never'],
    'array-callback-return': ERROR,
    'array-element-newline': OFF,
    'arrow-body-style': [ERROR, 'as-needed'],
    'arrow-parens': [ERROR, 'as-needed'],
    'arrow-spacing': ERROR,
    'block-spacing': [ERROR, 'always'],
    'brace-style': OFF,
    'callback-return': [ERROR, ['callback', 'cb', 'next', 'done']],
    camelcase: OFF,
    'capitalized-comments': OFF,
    'class-methods-use-this': ERROR,
    'comma-dangle': [ERROR, 'always-multiline'],
    'comma-spacing': [ERROR, { before: false, after: true }],
    'comma-style': [ERROR, 'last'],
    complexity: [WARN, COMPLEXITY_MAX],
    'computed-property-spacing': [ERROR, 'never'],
    'consistent-return': ERROR,
    'consistent-this': [ERROR, '_this'],
    'constructor-super': ERROR,
    curly: ERROR,
    'default-case': ERROR,
    'dot-location': [ERROR, 'property'],
    'dot-notation': ERROR,
    'eol-last': ERROR,
    eqeqeq: [ERROR, 'smart'],
    'for-direction': ERROR,
    'func-call-spacing': [ERROR, 'never'],
    'func-names': WARN,
    'func-name-matching': OFF,
    'func-style': [ERROR, 'declaration', { allowArrowFunctions: true }],
    'function-paren-newline': OFF,
    'getter-return': ERROR,
    'global-require': ERROR,
    'guard-for-in': ERROR,
    'handle-callback-err': ERROR,
    'id-blacklist': OFF,
    'id-length': OFF,
    'id-match': OFF,
    indent: OFF,
    'init-declarations': OFF,
    'jsx-quotes': OFF,
    'key-spacing': [ERROR, { beforeColon: false, afterColon: true }],
    'lines-between-class-members': OFF,
    'line-comment-position': OFF,
    'linebreak-style': [ERROR, 'unix'],
    'lines-around-comment': OFF,
    'lines-around-directive': OFF,
    'max-len': [
      WARN,
      100,
      TABWIDTH,
      {
        ignoreComments: true,
        ignorePattern: '^\\s*import\\s.+\\sfrom\\s.+;$',
      },
    ],
    'max-lines': [WARN, { max: 1000 }],
    'max-nested-callbacks': [ERROR, NESTED_CALLBACK_MAX],
    'max-params': [ERROR, ARGUMENTS_MAX],
    'max-statements-per-line': [WARN, { max: 2 }],
    'multiline-comment-style': OFF,
    'multiline-ternary': OFF,
    'new-cap': [ERROR, { newIsCap: true, capIsNew: true }],
    'new-parens': ERROR,
    'newline-after-var': WARN,
    'newline-before-return': OFF,
    'newline-per-chained-call': OFF,
    'no-alert': ERROR,
    'no-array-constructor': ERROR,
    'no-await-in-loop': ERROR,
    'no-buffer-constructor': ERROR,
    'no-caller': ERROR,
    'no-case-declarations': ERROR,
    'no-catch-shadow': ERROR,
    'no-class-assign': ERROR,
    'no-compare-neg-zero': ERROR,
    'no-confusing-arrow': OFF,
    'no-cond-assign': ERROR,
    'no-console': ERROR,
    'no-const-assign': ERROR,
    'no-constant-condition': ERROR,
    'no-continue': OFF,
    'no-control-regex': ERROR,
    'no-debugger': ERROR,
    'no-delete-var': ERROR,
    'no-div-regex': ERROR,
    'no-dupe-args': ERROR,
    'no-dupe-class-members': OFF,
    'no-dupe-keys': ERROR,
    'no-duplicate-case': ERROR,
    'no-duplicate-imports': ERROR,
    'no-else-return': ERROR,
    'no-empty': ERROR,
    'no-empty-character-class': ERROR,
    'no-empty-pattern': ERROR,
    'no-global-assign': ERROR,
    'no-labels': ERROR,
    'no-eq-null': ERROR,
    'no-eval': ERROR,
    'no-ex-assign': ERROR,
    'no-extend-native': ERROR,
    'no-extra-bind': ERROR,
    'no-extra-boolean-cast': ERROR,
    'no-extra-label': OFF,
    'no-extra-parens': OFF,
    'no-extra-semi': ERROR,
    'no-fallthrough': ERROR,
    'no-floating-decimal': ERROR,
    'no-func-assign': ERROR,
    'no-implicit-coercion': OFF,
    'no-implicit-globals': OFF,
    'no-implied-eval': ERROR,
    'no-inline-comments': OFF,
    'no-inner-declarations': ERROR,
    'no-invalid-regexp': ERROR,
    'no-invalid-this': WARN,
    'no-irregular-whitespace': ERROR,
    'no-iterator': ERROR,
    'no-label-var': ERROR,
    'no-lone-blocks': ERROR,
    'no-lonely-if': ERROR,
    'no-loop-func': ERROR,
    'no-magic-numbers': [
      ERROR,
      {
        ignoreArrayIndexes: true,
        ignore: [
          -1,
          0,
          1,
          100,
          101,
          102,
          200,
          201,
          202,
          203,
          204,
          205,
          206,
          207,
          210,
          226,
          300,
          301,
          302,
          303,
          304,
          305,
          306,
          307,
          308,
          310,
          400,
          401,
          402,
          403,
          404,
          405,
          406,
          407,
          408,
          409,
          410,
          411,
          412,
          413,
          414,
          415,
          416,
          417,
          418,
          421,
          422,
          423,
          424,
          425,
          426,
          427,
          428,
          429,
          431,
          449,
          450,
          451,
          456,
          499,
          500,
          501,
          502,
          503,
          504,
          505,
          506,
          507,
          508,
          509,
          510,
          511,
          520,
        ],
      },
    ],
    'no-mixed-operators': OFF,
    'no-mixed-requires': OFF,
    'no-mixed-spaces-and-tabs': ERROR,
    'no-multi-spaces': ERROR,
    'no-multi-str': ERROR,
    'no-multiple-empty-lines': [ERROR, { max: 2 }],
    'no-native-reassign': ERROR,
    'no-negated-condition': OFF,
    'no-negated-in-lhs': ERROR,
    'no-nested-ternary': OFF,
    'no-new': WARN,
    'no-new-func': ERROR,
    'no-new-object': ERROR,
    'no-new-require': ERROR,
    'no-new-symbol': ERROR,
    'no-obj-calls': ERROR,
    'no-octal': ERROR,
    'no-octal-escape': ERROR,
    'no-param-reassign': OFF,
    'no-path-concat': ERROR,
    'no-process-env': OFF,
    'no-process-exit': OFF,
    'no-proto': ERROR,
    'no-prototype-builtins': WARN,
    'no-redeclare': ERROR,
    'no-regex-spaces': ERROR,
    'no-reserved-keys': OFF,
    'no-restricted-globals': OFF,
    'no-restricted-imports': OFF,
    'no-restricted-modules': OFF,
    'no-restricted-syntax': OFF,
    'no-restricted-properties': [
      ERROR,
      {
        object: 'describe',
        property: 'only',
        message: 'Using describe.only is not allowed',
      },
      {
        object: 'it',
        property: 'only',
        message: 'Using it.only is not allowed',
      },
    ],
    'no-return-assign': ERROR,
    'no-return-await': ERROR,
    'no-script-url': ERROR,
    'no-self-assign': ERROR,
    'no-self-compare': ERROR,
    'no-sequences': ERROR,
    'no-shadow': WARN,
    'no-shadow-restricted-names': ERROR,
    'no-spaced-func': ERROR,
    'no-sparse-arrays': ERROR,
    'no-sync': OFF,
    'no-tabs': ERROR,
    'no-ternary': OFF,
    'no-template-curly-in-string': WARN,
    'no-throw-literal': ERROR,
    'no-this-before-super': ERROR,
    'no-trailing-spaces': ERROR,
    'no-undef': ERROR,
    'no-undef-init': ERROR,
    'no-undefined': ERROR,
    'no-underscore-dangle': OFF,
    'no-unexpected-multiline': ERROR,
    'no-unmodified-loop-condition': ERROR,
    'no-unneeded-ternary': ERROR,
    'no-unreachable': ERROR,
    'no-unsafe-finally': ERROR,
    'no-unsafe-negation': ERROR,
    'no-unused-expressions': ERROR,
    'no-unused-labels': OFF,
    'no-unused-vars': [ERROR, { args: 'none' }],
    'no-use-before-define': [ERROR, 'nofunc'],
    'no-useless-call': ERROR,
    'no-useless-computed-key': ERROR,
    'no-useless-concat': ERROR,
    'no-useless-constructor': ERROR,
    'no-useless-escape': WARN,
    'no-useless-rename': WARN,
    'no-useless-return': ERROR,
    'no-void': ERROR,
    'no-warning-comments': OFF,
    'no-with': ERROR,
    'no-whitespace-before-property': WARN,
    'nonblock-statement-body-position': OFF,
    'object-curly-newline': OFF,
    'object-curly-spacing': [ERROR, 'always'],
    'object-property-newline': [
      ERROR,
      { allowMultiplePropertiesPerLine: true },
    ],
    'one-var': [ERROR, 'never'],
    'one-var-declaration-per-line': OFF,
    'operator-assignment': [ERROR, 'always'],
    'operator-linebreak': OFF,
    'padded-blocks': OFF,
    'padding-line-between-statements': OFF,
    'prefer-arrow-callback': OFF,
    'prefer-destructuring': OFF,
    'prefer-numeric-literals': ERROR,
    'prefer-reflect': OFF,
    'prefer-rest-params': WARN,
    'prefer-spread': OFF,
    'prefer-template': OFF,
    'quote-props': [ERROR, 'as-needed'],
    quotes: [ERROR, 'single', { avoidEscape: true }],
    radix: ERROR,
    'require-await': WARN,
    'require-jsdoc': OFF,
    'require-yield': ERROR,
    'rest-spread-spacing': [ERROR, 'never'],
    semi: [ERROR, 'always'],
    'semi-spacing': [ERROR, { before: false, after: true }],
    'semi-style': ERROR,
    'sort-imports': OFF,
    'sort-keys': OFF,
    'sort-vars': OFF,
    'space-after-keywords': OFF,
    'space-before-blocks': [ERROR, 'always'],
    'space-before-function-paren': OFF,
    'keyword-spacing': [
      'error',
      {
        before: true,
      },
    ],
    'space-in-parens': [ERROR, 'never'],
    'space-infix-ops': ERROR,
    'space-unary-ops': ERROR,
    'spaced-comment': [ERROR, 'always'],
    'switch-colon-spacing': WARN,
    'symbol-description': ERROR,
    'template-curly-spacing': [ERROR, 'never'],
    'template-tag-spacing': OFF,
    'unicode-bom': ERROR,
    'valid-jsdoc': ERROR,
    'valid-typeof': ERROR,
    'vars-on-top': ERROR,
    'wrap-iife': ERROR,
    'wrap-regex': OFF,
    yoda: [ERROR, 'always'],
  },
};
<commit_msg>Remove yoda rule<commit_after>'use strict';

const OFF = 'off';
const ERROR = 'error';
const WARN = 'warn';

const COMPLEXITY_MAX = 5;
const TABWIDTH = 2;
const NESTED_CALLBACK_MAX = 4;
const ARGUMENTS_MAX = 4;

module.exports = {
  extends: 'eslint:recommended',
  env: {
    node: true,
  },
  globals: {
    require: false,
    module: false,
  },
  parserOptions: {
    ecmaVersion: 6,
    sourceType: 'script',
    arrowFunctions: true,
    binaryLiterals: true,
    blockBindings: true,
    classes: false,
    defaultParams: true,
    destructuring: true,
    forOf: true,
    generators: false,
    modules: false,
    objectLiteralComputedProperties: true,
    objectLiteralDuplicateProperties: true,
    objectLiteralShorthandMethods: true,
    objectLiteralShorthandProperties: true,
    octalLiterals: false,
    regexUFlag: true,
    regexYFlag: true,
    restParams: true,
    spread: true,
    superInFunctions: true,
    templateStrings: true,
    unicodeCodePointEscapes: true,
  },
  rules: {
    'accessor-pairs': [ERROR, { getWithoutSet: false, setWithoutGet: true }],
    'array-bracket-newline': OFF,
    'array-bracket-spacing': [ERROR, 'never'],
    'array-callback-return': ERROR,
    'array-element-newline': OFF,
    'arrow-body-style': [ERROR, 'as-needed'],
    'arrow-parens': [ERROR, 'as-needed'],
    'arrow-spacing': ERROR,
    'block-spacing': [ERROR, 'always'],
    'brace-style': OFF,
    'callback-return': [ERROR, ['callback', 'cb', 'next', 'done']],
    camelcase: OFF,
    'capitalized-comments': OFF,
    'class-methods-use-this': ERROR,
    'comma-dangle': [ERROR, 'always-multiline'],
    'comma-spacing': [ERROR, { before: false, after: true }],
    'comma-style': [ERROR, 'last'],
    complexity: [WARN, COMPLEXITY_MAX],
    'computed-property-spacing': [ERROR, 'never'],
    'consistent-return': ERROR,
    'consistent-this': [ERROR, '_this'],
    'constructor-super': ERROR,
    curly: ERROR,
    'default-case': ERROR,
    'dot-location': [ERROR, 'property'],
    'dot-notation': ERROR,
    'eol-last': ERROR,
    eqeqeq: [ERROR, 'smart'],
    'for-direction': ERROR,
    'func-call-spacing': [ERROR, 'never'],
    'func-names': WARN,
    'func-name-matching': OFF,
    'func-style': [ERROR, 'declaration', { allowArrowFunctions: true }],
    'function-paren-newline': OFF,
    'getter-return': ERROR,
    'global-require': ERROR,
    'guard-for-in': ERROR,
    'handle-callback-err': ERROR,
    'id-blacklist': OFF,
    'id-length': OFF,
    'id-match': OFF,
    indent: OFF,
    'init-declarations': OFF,
    'jsx-quotes': OFF,
    'key-spacing': [ERROR, { beforeColon: false, afterColon: true }],
    'lines-between-class-members': OFF,
    'line-comment-position': OFF,
    'linebreak-style': [ERROR, 'unix'],
    'lines-around-comment': OFF,
    'lines-around-directive': OFF,
    'max-len': [
      WARN,
      100,
      TABWIDTH,
      {
        ignoreComments: true,
        ignorePattern: '^\\s*import\\s.+\\sfrom\\s.+;$',
      },
    ],
    'max-lines': [WARN, { max: 1000 }],
    'max-nested-callbacks': [ERROR, NESTED_CALLBACK_MAX],
    'max-params': [ERROR, ARGUMENTS_MAX],
    'max-statements-per-line': [WARN, { max: 2 }],
    'multiline-comment-style': OFF,
    'multiline-ternary': OFF,
    'new-cap': [ERROR, { newIsCap: true, capIsNew: true }],
    'new-parens': ERROR,
    'newline-after-var': WARN,
    'newline-before-return': OFF,
    'newline-per-chained-call': OFF,
    'no-alert': ERROR,
    'no-array-constructor': ERROR,
    'no-await-in-loop': ERROR,
    'no-buffer-constructor': ERROR,
    'no-caller': ERROR,
    'no-case-declarations': ERROR,
    'no-catch-shadow': ERROR,
    'no-class-assign': ERROR,
    'no-compare-neg-zero': ERROR,
    'no-confusing-arrow': OFF,
    'no-cond-assign': ERROR,
    'no-console': ERROR,
    'no-const-assign': ERROR,
    'no-constant-condition': ERROR,
    'no-continue': OFF,
    'no-control-regex': ERROR,
    'no-debugger': ERROR,
    'no-delete-var': ERROR,
    'no-div-regex': ERROR,
    'no-dupe-args': ERROR,
    'no-dupe-class-members': OFF,
    'no-dupe-keys': ERROR,
    'no-duplicate-case': ERROR,
    'no-duplicate-imports': ERROR,
    'no-else-return': ERROR,
    'no-empty': ERROR,
    'no-empty-character-class': ERROR,
    'no-empty-pattern': ERROR,
    'no-global-assign': ERROR,
    'no-labels': ERROR,
    'no-eq-null': ERROR,
    'no-eval': ERROR,
    'no-ex-assign': ERROR,
    'no-extend-native': ERROR,
    'no-extra-bind': ERROR,
    'no-extra-boolean-cast': ERROR,
    'no-extra-label': OFF,
    'no-extra-parens': OFF,
    'no-extra-semi': ERROR,
    'no-fallthrough': ERROR,
    'no-floating-decimal': ERROR,
    'no-func-assign': ERROR,
    'no-implicit-coercion': OFF,
    'no-implicit-globals': OFF,
    'no-implied-eval': ERROR,
    'no-inline-comments': OFF,
    'no-inner-declarations': ERROR,
    'no-invalid-regexp': ERROR,
    'no-invalid-this': WARN,
    'no-irregular-whitespace': ERROR,
    'no-iterator': ERROR,
    'no-label-var': ERROR,
    'no-lone-blocks': ERROR,
    'no-lonely-if': ERROR,
    'no-loop-func': ERROR,
    'no-magic-numbers': [
      ERROR,
      {
        ignoreArrayIndexes: true,
        ignore: [
          -1,
          0,
          1,
          100,
          101,
          102,
          200,
          201,
          202,
          203,
          204,
          205,
          206,
          207,
          210,
          226,
          300,
          301,
          302,
          303,
          304,
          305,
          306,
          307,
          308,
          310,
          400,
          401,
          402,
          403,
          404,
          405,
          406,
          407,
          408,
          409,
          410,
          411,
          412,
          413,
          414,
          415,
          416,
          417,
          418,
          421,
          422,
          423,
          424,
          425,
          426,
          427,
          428,
          429,
          431,
          449,
          450,
          451,
          456,
          499,
          500,
          501,
          502,
          503,
          504,
          505,
          506,
          507,
          508,
          509,
          510,
          511,
          520,
        ],
      },
    ],
    'no-mixed-operators': OFF,
    'no-mixed-requires': OFF,
    'no-mixed-spaces-and-tabs': ERROR,
    'no-multi-spaces': ERROR,
    'no-multi-str': ERROR,
    'no-multiple-empty-lines': [ERROR, { max: 2 }],
    'no-native-reassign': ERROR,
    'no-negated-condition': OFF,
    'no-negated-in-lhs': ERROR,
    'no-nested-ternary': OFF,
    'no-new': WARN,
    'no-new-func': ERROR,
    'no-new-object': ERROR,
    'no-new-require': ERROR,
    'no-new-symbol': ERROR,
    'no-obj-calls': ERROR,
    'no-octal': ERROR,
    'no-octal-escape': ERROR,
    'no-param-reassign': OFF,
    'no-path-concat': ERROR,
    'no-process-env': OFF,
    'no-process-exit': OFF,
    'no-proto': ERROR,
    'no-prototype-builtins': WARN,
    'no-redeclare': ERROR,
    'no-regex-spaces': ERROR,
    'no-reserved-keys': OFF,
    'no-restricted-globals': OFF,
    'no-restricted-imports': OFF,
    'no-restricted-modules': OFF,
    'no-restricted-syntax': OFF,
    'no-restricted-properties': [
      ERROR,
      {
        object: 'describe',
        property: 'only',
        message: 'Using describe.only is not allowed',
      },
      {
        object: 'it',
        property: 'only',
        message: 'Using it.only is not allowed',
      },
    ],
    'no-return-assign': ERROR,
    'no-return-await': ERROR,
    'no-script-url': ERROR,
    'no-self-assign': ERROR,
    'no-self-compare': ERROR,
    'no-sequences': ERROR,
    'no-shadow': WARN,
    'no-shadow-restricted-names': ERROR,
    'no-spaced-func': ERROR,
    'no-sparse-arrays': ERROR,
    'no-sync': OFF,
    'no-tabs': ERROR,
    'no-ternary': OFF,
    'no-template-curly-in-string': WARN,
    'no-throw-literal': ERROR,
    'no-this-before-super': ERROR,
    'no-trailing-spaces': ERROR,
    'no-undef': ERROR,
    'no-undef-init': ERROR,
    'no-undefined': ERROR,
    'no-underscore-dangle': OFF,
    'no-unexpected-multiline': ERROR,
    'no-unmodified-loop-condition': ERROR,
    'no-unneeded-ternary': ERROR,
    'no-unreachable': ERROR,
    'no-unsafe-finally': ERROR,
    'no-unsafe-negation': ERROR,
    'no-unused-expressions': ERROR,
    'no-unused-labels': OFF,
    'no-unused-vars': [ERROR, { args: 'none' }],
    'no-use-before-define': [ERROR, 'nofunc'],
    'no-useless-call': ERROR,
    'no-useless-computed-key': ERROR,
    'no-useless-concat': ERROR,
    'no-useless-constructor': ERROR,
    'no-useless-escape': WARN,
    'no-useless-rename': WARN,
    'no-useless-return': ERROR,
    'no-void': ERROR,
    'no-warning-comments': OFF,
    'no-with': ERROR,
    'no-whitespace-before-property': WARN,
    'nonblock-statement-body-position': OFF,
    'object-curly-newline': OFF,
    'object-curly-spacing': [ERROR, 'always'],
    'object-property-newline': [
      ERROR,
      { allowMultiplePropertiesPerLine: true },
    ],
    'one-var': [ERROR, 'never'],
    'one-var-declaration-per-line': OFF,
    'operator-assignment': [ERROR, 'always'],
    'operator-linebreak': OFF,
    'padded-blocks': OFF,
    'padding-line-between-statements': OFF,
    'prefer-arrow-callback': OFF,
    'prefer-destructuring': OFF,
    'prefer-numeric-literals': ERROR,
    'prefer-reflect': OFF,
    'prefer-rest-params': WARN,
    'prefer-spread': OFF,
    'prefer-template': OFF,
    'quote-props': [ERROR, 'as-needed'],
    quotes: [ERROR, 'single', { avoidEscape: true }],
    radix: ERROR,
    'require-await': WARN,
    'require-jsdoc': OFF,
    'require-yield': ERROR,
    'rest-spread-spacing': [ERROR, 'never'],
    semi: [ERROR, 'always'],
    'semi-spacing': [ERROR, { before: false, after: true }],
    'semi-style': ERROR,
    'sort-imports': OFF,
    'sort-keys': OFF,
    'sort-vars': OFF,
    'space-after-keywords': OFF,
    'space-before-blocks': [ERROR, 'always'],
    'space-before-function-paren': OFF,
    'keyword-spacing': [
      'error',
      {
        before: true,
      },
    ],
    'space-in-parens': [ERROR, 'never'],
    'space-infix-ops': ERROR,
    'space-unary-ops': ERROR,
    'spaced-comment': [ERROR, 'always'],
    'switch-colon-spacing': WARN,
    'symbol-description': ERROR,
    'template-curly-spacing': [ERROR, 'never'],
    'template-tag-spacing': OFF,
    'unicode-bom': ERROR,
    'valid-jsdoc': ERROR,
    'valid-typeof': ERROR,
    'vars-on-top': ERROR,
    'wrap-iife': ERROR,
    'wrap-regex': OFF,
    yoda: OFF,
  },
};
<|endoftext|>


<commit_before>/**
 * Created by nuintun on 2015/4/27.
 */

'use strict';

var is = require('is');
var css = require('css');
var path = require('path');
var join = path.join;
var extname = path.extname;
var rename = require('./rename');
var udeps = require('umd-deps');
var cdeps = require('./css-deps');
var util = require('./util');
var debug = util.debug;
var colors = util.colors;

/**
 * Transport vinyl id
 * - vinyl: vinyl object
 * - required options: idleading, rename
 */

function transportId(vinyl, options){
  var id;
  var pkg = util.parsePackage(vinyl, options.wwwroot);
  var idleading = resolveIdleading(options.idleading, vinyl.path, pkg);

  // get id
  id = util.template(idleading, pkg);
  // rename id
  id = util.addExt(id);
  id = rename(id, options.rename);
  id = util.hideExt(id);

  // seajs has hacked css before 3.0.0
  // https://github.com/seajs/seajs/blob/2.2.1/src/util-path.js#L49
  // demo https://github.com/popomore/seajs-test/tree/master/css-deps
  if (extname(id) === '.css') {
    id += '.js';
  }

  // normalize id
  id = util.normalize(id);

  // debug
  debug('transport id: %s', colors.data(id));

  // rewrite vinyl path
  if (path.isAbsolute(id)) {
    vinyl.path = join(options.wwwroot, util.addExt(id));
  } else {
    vinyl.path = join(vinyl.cwd, vinyl.base, util.addExt(id));
  }

  // set vinyl package info
  vinyl.package = util.extend(pkg, { id: id });

  return id;
}

/**
 * Transport cmd dependencies.
 * - vinyl: vinyl object
 * - required options: idleading
 */

function transportDeps(vinyl, options){
  var deps = [];
  var include = [];
  var vars = options.vars;
  var alias = options.alias;
  var paths = options.paths;
  var pkg = vinyl.package || {};

  // replace require and collect dependencies
  vinyl.contents = new Buffer(udeps(vinyl.contents.toString(), function (id, flag){
    // parse id form alias, paths, vars
    id = util.parseAlias(id, alias);
    id = util.parsePaths(id, paths);
    id = util.parseAlias(id, alias);
    id = util.parseVars(id, vars);
    id = util.parseAlias(id, alias);

    // normalize id
    id = util.normalize(id);

    // id is not a local file
    if (!util.isLocal(id)) {
      // cache dependencie id
      deps.push(id);

      return id;
    }

    var path;

    // if end with /, find index file
    if (id.substring(id.length - 1) === '/') {
      id += 'index';
    }

    // debug
    debug('transport%s deps: %s', flag ? ' ' + flag : '', colors.data(id));

    // add extname
    path = util.addExt(id);
    // rename id
    id = rename(path, options.rename);
    // hide extname
    id = util.hideExt(id);

    // seajs has hacked css before 3.0.0
    // https://github.com/seajs/seajs/blob/2.2.1/src/util-path.js#L49
    // demo https://github.com/popomore/seajs-test/tree/master/css-deps
    if (extname(id) === '.css') {
      id += '.js';
    }

    // normalize id
    id = util.normalize(id);

    // cache dependencie id and path
    if (flag === null) {
      // cache dependencie id
      deps.push(id);

      // get absolute path
      path = util.resolve(path, vinyl, options.wwwroot);

      // cache dependencie absolute path
      include.push({
        id: id,
        path: path
      });
    }

    return id;
  }, true));

  // Cache file dependencies
  vinyl.package = util.extend(pkg, {
    include: include,
    dependencies: deps
  });

  return deps;
}

/**
 * Transport css dependencies.
 * - vinyl: vinyl object
 */

function transportCssDeps(vinyl, options){
  var deps = [];
  var include = [];
  var prefix = options.prefix;
  var pkg = vinyl.package || {};

  // compute prefix
  prefix = is.fn(prefix) ? prefix(pkg.id || null, vinyl.path) : prefix;

  // replace imports and collect dependencies
  vinyl.contents = new Buffer(cdeps(vinyl.contents, function (id){
    var path;

    // normalize id
    id = util.normalize(id);

    // id is not a local file
    if (!util.isLocal(id)) {
      // cache dependencie id
      deps.push(id);

      // keep import
      return id;
    }

    var isRelative = util.isRelative(id);
    var isAbsolute = util.isAbsolute(id);

    // css import parsing rules using html
    if (!isAbsolute && !isRelative) {
      id = './' + id;
    }

    // if end with /, find index file
    if (id.substring(id.length - 1) === '/') {
      id += 'index.css';
    }

    // add extname
    path = util.addExt(id);
    // rename id
    id = rename(path, options.rename);
    // hide extname
    id = util.hideExt(id);

    // seajs has hacked css before 3.0.0
    // https://github.com/seajs/seajs/blob/2.2.1/src/util-path.js#L49
    // demo https://github.com/popomore/seajs-test/tree/master/css-deps
    if (extname(id) === '.css') {
      id += '.js';
    }

    // normalize id
    id = util.normalize(id);

    // debug
    debug('transport deps: %s', colors.data(id));

    // get absolute path
    path = util.resolve(path, vinyl, options.wwwroot);

    // cache dependencie id
    deps.push(id);
    // cache dependencie absolute path
    include.push({
      id: id,
      path: path
    });

    // delete all import
    return false;
  }, options.oncsspath, prefix));

  // Cache file dependencies
  vinyl.package = util.extend(pkg, {
    include: include,
    dependencies: deps
  });

  return deps;
}

/*
 Create a parser in lib/parser
 */

function createParser(type, transport){
  return function (vinyl, options){
    // debug
    debug('read %s: %s', type, colors.data(util.pathFromCwd(vinyl.path)));

    vinyl = transport(vinyl, options);

    return vinyl;
  };
}

/**
 * resolve id leading
 * @param idleading
 * @param path
 * @param pkg
 * @returns {*}
 */

function resolveIdleading(idleading, path, pkg){
  return is.fn(idleading) ? idleading(path, pkg) : idleading;
}

/**
 * Exports module.
 */

exports.transportId = transportId;
exports.transportDeps = transportDeps;
exports.createParser = createParser;
exports.resolveIdleading = resolveIdleading;
exports.transportCssDeps = transportCssDeps;
<commit_msg>add source files<commit_after>/**
 * Created by nuintun on 2015/4/27.
 */

'use strict';

var is = require('is');
var css = require('css');
var path = require('path');
var join = path.join;
var extname = path.extname;
var rename = require('./rename');
var udeps = require('umd-deps');
var cdeps = require('./css-deps');
var util = require('./util');
var debug = util.debug;
var colors = util.colors;

/**
 * Transport vinyl id
 * - vinyl: vinyl object
 * - required options: idleading, rename
 */

function transportId(vinyl, options){
  var id;
  var pkg = util.parsePackage(vinyl, options.wwwroot);
  var idleading = resolveIdleading(options.idleading, vinyl.path, pkg);

  // get id
  id = util.template(idleading, pkg);
  // rename id
  id = util.addExt(id);
  id = rename(id, options.rename);
  id = util.hideExt(id);

  // seajs has hacked css before 3.0.0
  // https://github.com/seajs/seajs/blob/2.2.1/src/util-path.js#L49
  // demo https://github.com/popomore/seajs-test/tree/master/css-deps
  if (extname(id) === '.css') {
    id += '.js';
  }

  // normalize id
  id = util.normalize(id);

  // debug
  debug('transport id: %s', colors.data(id));

  // rewrite vinyl path
  if (path.isAbsolute(id)) {
    vinyl.path = join(options.wwwroot, util.addExt(id));
  } else {
    vinyl.path = join(vinyl.cwd, vinyl.base, util.addExt(id));
  }

  // set vinyl package info
  vinyl.package = util.extend(pkg, { id: id });

  return id;
}

/**
 * Transport cmd dependencies.
 * - vinyl: vinyl object
 * - required options: idleading
 */

function transportDeps(vinyl, options){
  var deps = [];
  var include = [];
  var vars = options.vars;
  var alias = options.alias;
  var paths = options.paths;
  var pkg = vinyl.package || {};

  // replace require and collect dependencies
  vinyl.contents = new Buffer(udeps(vinyl.contents.toString(), function (id, flag){
    // parse id form alias, paths, vars
    id = util.parseAlias(id, alias);
    id = util.parsePaths(id, paths);
    id = util.parseAlias(id, alias);
    id = util.parseVars(id, vars);
    id = util.parseAlias(id, alias);

    // id is not a local file
    if (!util.isLocal(id)) {
      // cache dependencie id
      deps.push(id);

      return id;
    }

    var path;

    // normalize id
    id = util.normalize(id);

    // if end with /, find index file
    if (id.substring(id.length - 1) === '/') {
      id += 'index';
    }

    // debug
    debug('transport%s deps: %s', flag ? ' ' + flag : '', colors.data(id));

    // add extname
    path = util.addExt(id);
    // rename id
    id = rename(path, options.rename);
    // hide extname
    id = util.hideExt(id);

    // seajs has hacked css before 3.0.0
    // https://github.com/seajs/seajs/blob/2.2.1/src/util-path.js#L49
    // demo https://github.com/popomore/seajs-test/tree/master/css-deps
    if (extname(id) === '.css') {
      id += '.js';
    }

    // normalize id
    id = util.normalize(id);

    // cache dependencie id and path
    if (flag === null) {
      // cache dependencie id
      deps.push(id);

      // get absolute path
      path = util.resolve(path, vinyl, options.wwwroot);

      // cache dependencie absolute path
      include.push({
        id: id,
        path: path
      });
    }

    return id;
  }, true));

  // Cache file dependencies
  vinyl.package = util.extend(pkg, {
    include: include,
    dependencies: deps
  });

  return deps;
}

/**
 * Transport css dependencies.
 * - vinyl: vinyl object
 */

function transportCssDeps(vinyl, options){
  var deps = [];
  var include = [];
  var prefix = options.prefix;
  var pkg = vinyl.package || {};

  // compute prefix
  prefix = is.fn(prefix) ? prefix(pkg.id || null, vinyl.path) : prefix;

  // replace imports and collect dependencies
  vinyl.contents = new Buffer(cdeps(vinyl.contents, function (id){
    var path;

    // id is not a local file
    if (!util.isLocal(id)) {
      // cache dependencie id
      deps.push(id);

      // keep import
      return id;
    }

    // normalize id
    id = util.normalize(id);

    var isRelative = util.isRelative(id);
    var isAbsolute = util.isAbsolute(id);

    // css import parsing rules using html
    if (!isAbsolute && !isRelative) {
      id = './' + id;
    }

    // if end with /, find index file
    if (id.substring(id.length - 1) === '/') {
      id += 'index.css';
    }

    // add extname
    path = util.addExt(id);
    // rename id
    id = rename(path, options.rename);
    // hide extname
    id = util.hideExt(id);

    // seajs has hacked css before 3.0.0
    // https://github.com/seajs/seajs/blob/2.2.1/src/util-path.js#L49
    // demo https://github.com/popomore/seajs-test/tree/master/css-deps
    if (extname(id) === '.css') {
      id += '.js';
    }

    // normalize id
    id = util.normalize(id);

    // debug
    debug('transport deps: %s', colors.data(id));

    // get absolute path
    path = util.resolve(path, vinyl, options.wwwroot);

    // cache dependencie id
    deps.push(id);
    // cache dependencie absolute path
    include.push({
      id: id,
      path: path
    });

    // delete all import
    return false;
  }, options.oncsspath, prefix));

  // Cache file dependencies
  vinyl.package = util.extend(pkg, {
    include: include,
    dependencies: deps
  });

  return deps;
}

/*
 Create a parser in lib/parser
 */

function createParser(type, transport){
  return function (vinyl, options){
    // debug
    debug('read %s: %s', type, colors.data(util.pathFromCwd(vinyl.path)));

    vinyl = transport(vinyl, options);

    return vinyl;
  };
}

/**
 * resolve id leading
 * @param idleading
 * @param path
 * @param pkg
 * @returns {*}
 */

function resolveIdleading(idleading, path, pkg){
  return is.fn(idleading) ? idleading(path, pkg) : idleading;
}

/**
 * Exports module.
 */

exports.transportId = transportId;
exports.transportDeps = transportDeps;
exports.createParser = createParser;
exports.resolveIdleading = resolveIdleading;
exports.transportCssDeps = transportCssDeps;
<|endoftext|>


<commit_before>import React from 'react';
import uuid from 'node-uuid';
import {connect} from 'react-redux';
import {Form, Grid, FormControl, Button, Glyphicon, Row, Col, FormGroup} from 'react-bootstrap';

// FIXME: we should maybe pick one? :)
import R from 'ramda';
import _ from 'lodash';
import Actions from '../actions/Creators';
import TodoListItem from './TodoListItem';
import TodoModalShareList from './TodoModalShareList';

class TodoCreateList extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      itemTitle: '',
      items: [],
    };
  }

  saveDisabled() {
    return !(this.state.listTitle &&
    this.state.items.length !== 0);
  }

  // Fixes an issue with controllable/uncontrollable inputs. You might
  // wanna check if there's better way of doing this
  getListTitle() {
    return this.state.listTitle || '';
  }

  handleSaveButton() {

    var items = this.state.items;
    var title = this.state.listTitle;
    var {dispatch} =  this.props;
    var data = {title, items};

    Actions(dispatch).createList(data);
  }

  handleAddItemButton(title) {
    if (!!title) {

      var item = {
        title,
        id: uuid.v1(),
        date: new Date(),
      };
      this.setState({
        items: R.append(item, this.state.items),
      });
    }

    this.setState({itemTitle: ''});
  }

  handleItemRemoval(item) {
    var tempItems = this.state.items;

    _.remove(tempItems, tempItem => tempItem.id === item.id);

    this.setState({
      items: tempItems
    });

  }

  render() {

    var {todos} = this.props;
    var items = this.state.items;
    var existingItem;
    //TODO: this should probably be in didReceiveNewProps or smhitng
    var itemId = null;

    if (!!this.props.params) {
      itemId = this.props.params.listId;

      for (var i = 0; i < todos.length; ++i) {

      }

      if (existingItem !== undefined) {
        existingItem = todos[existingItemIndex];
        console.log("existingItem", existingItem);
      }
    }

    var pageTitle = (!!itemId) ? 'Edit list ' + (this.state.listTitle || '') : 'Create a new list';

    return (

        <Grid>

{pageTitle}

          <Form>
            <FormGroup>
              <Row>
                <Col xs={12}>
                  <FormControl value={this.getListTitle()}
                               type="text"
                               placeholder="Enter title"
                               onChange={e => this.setState({listTitle: e.target.value})}/>
                </Col>
              </Row>

              <Row className="todo-create-list-add-item-container">

                <Col xs={12}>

                  <FormControl value={this.state.itemTitle}
                               type="text"
                               placeholder="Item title"
                               onChange={e => this.setState({itemTitle: e.target.value})}
                  />

                  <Button className="todo-create-list-add-item-button"
                          disabled={!this.state.itemTitle}
                          onClick={() => this.handleAddItemButton(this.state.itemTitle)}>
                    <Glyphicon glyph="plus"/>
                  </Button>

                </Col>
              </Row>

              {items.length > 0 ?

                  {items.map((item) => {
                      return (

                        <TodoListItem
                          key={item.id}
                          removeFn={e => this.handleItemRemoval(item)}
                          id={item.id}
                          date={item.date}>

                          {item.title}
                        </TodoListItem>
                      );
                    }
                  )}

                : null }

              <Row className="todo-create-list-control-buttons">
                <Col xs={12}>
                  <Button className="todo-button"
                          onClick={() => this.handleSaveButton()}
                          disabled={this.saveDisabled()}>

                    <Glyphicon glyph="save"/> Save</Button>
                  <TodoModalShareList />
                </Col>
              </Row>
            </FormGroup>
          </Form>

        </Grid>

    );
  }
}

function mapStateToProps(state) {
  console.log("new redux state", state);
  return {
    todos: state.todo.lists,
  };
}

export default connect(mapStateToProps)(TodoCreateList);
<commit_msg>Todo: User is redirected to the main page after saving a list<commit_after>import React from 'react';
import uuid from 'node-uuid';
import {connect} from 'react-redux';
import {Form, Grid, FormControl, Button, Glyphicon, Row, Col, FormGroup} from 'react-bootstrap';

// FIXME: we should maybe pick one? :)
import R from 'ramda';
import _ from 'lodash';
import Actions from '../actions/Creators';
import TodoListItem from './TodoListItem';
import TodoModalShareList from './TodoModalShareList';

class TodoCreateList extends React.Component {

  static contextTypes = {
    router: React.PropTypes.object,
  };

  constructor(props) {
    super(props);
    this.state = {
      itemTitle: '',
      items: [],
    };
  }

  saveDisabled() {
    return !(this.state.listTitle &&
    this.state.items.length !== 0);
  }

  navigateTo(url) {
    this.context.router.push(url);
  }

  // Fixes an issue with controllable/uncontrollable inputs. You might
  // wanna check if there's better way of doing this
  getListTitle() {
    return this.state.listTitle || '';
  }

  handleSaveButton() {

    var items = this.state.items;
    var title = this.state.listTitle;
    var {dispatch} =  this.props;
    var data = {title, items};

    Actions(dispatch).createList(data).then(res => {
      this.navigateTo('/reactDemo');
    });
  }

  handleAddItemButton(title) {
    if (!!title) {
      console.log(this.props);
      var item = {
        title,
        id: uuid.v1(),
        date: new Date(),
      };
      this.setState({
        items: R.append(item, this.state.items),
      });
    }

    this.setState({itemTitle: ''});
  }

  handleItemRemoval(item) {
    var tempItems = this.state.items;

    _.remove(tempItems, tempItem => tempItem.id === item.id);

    this.setState({
      items: tempItems
    });

  }

  render() {

    var {todos} = this.props;
    var items = this.state.items;
    var existingItem;
    //TODO: this should probably be in didReceiveNewProps or smhitng
    var itemId = null;

    if (!!this.props.params) {
      itemId = this.props.params.listId;

      for (var i = 0; i < todos.length; ++i) {

      }

      if (existingItem !== undefined) {
        existingItem = todos[existingItemIndex];
        console.log("existingItem", existingItem);
      }
    }

    var pageTitle = (!!itemId) ? 'Edit list ' + (this.state.listTitle || '') : 'Create a new list';

    return (

        <Grid>

{pageTitle}

          <Form>
            <FormGroup>
              <Row>
                <Col xs={12}>
                  <FormControl value={this.getListTitle()}
                               type="text"
                               placeholder="Enter title"
                               onChange={e => this.setState({listTitle: e.target.value})}/>
                </Col>
              </Row>

              <Row className="todo-create-list-add-item-container">

                <Col xs={12}>

                  <FormControl value={this.state.itemTitle}
                               type="text"
                               placeholder="Item title"
                               onChange={e => this.setState({itemTitle: e.target.value})}
                  />

                  <Button className="todo-create-list-add-item-button"
                          disabled={!this.state.itemTitle}
                          onClick={() => this.handleAddItemButton(this.state.itemTitle)}>
                    <Glyphicon glyph="plus"/>
                  </Button>

                </Col>
              </Row>

              {items.length > 0 ?

                  {items.map((item) => {
                      return (

                        <TodoListItem
                          key={item.id}
                          removeFn={e => this.handleItemRemoval(item)}
                          id={item.id}
                          date={item.date}>

                          {item.title}
                        </TodoListItem>
                      );
                    }
                  )}

                : null }

              <Row className="todo-create-list-control-buttons">
                <Col xs={12}>
                  <Button className="todo-button"
                          onClick={() => this.handleSaveButton()}
                          disabled={this.saveDisabled()}>

                    <Glyphicon glyph="save"/> Save</Button>
                  <TodoModalShareList />
                </Col>
              </Row>
            </FormGroup>
          </Form>

        </Grid>

    );
  }
}

function mapStateToProps(state) {
  console.log("new redux state", state);
  return {
    todos: state.todo.lists,
  };
}

export default connect(mapStateToProps)(TodoCreateList);
<|endoftext|>


<commit_before>import { createHmac } from 'crypto';

export default async function handleWebhook(req, res) {
  // verify the webhook signature request against the
  // unmodified, unparsed body
  const body = await getRawBody(req);
  if (!body) {
    res.status(400).send('Bad request (no body)');
    return;
  }

  const jsonBody = JSON.parse(body);

  console.log({ jsonBody });

  const slug = jsonBody.fields.slug[0];

  console.log({ slug });

  // secret
  const secret = process.env.NEXT_PUBLIC_REVALIDATION;

  if (req.query.secret === secret) {
    // issue opened or edited
    // comment created or edited
    console.log('[Next.js] Revalidating /');
    await res.revalidate('/');
    if (slug) {
      console.log(`[Next.js] Revalidating /${slug}`);
      await res.revalidate(`/${slug}`);
    }

    return res.status(200).send('Success!');
  } else {
    return res.status(403).send('Forbidden');
  }
}

function getRawBody(req) {
  return new Promise((resolve, reject) => {
    let bodyChunks = [];
    req.on('end', () => {
      const rawBody = Buffer.concat(bodyChunks).toString('utf8');
      resolve(rawBody);
    });
    req.on('data', (chunk) => bodyChunks.push(chunk));
  });
}

export const config = {
  api: {
    bodyParser: false,
  },
};
<commit_msg>fix: api revalidation test<commit_after>import { createHmac } from 'crypto';

export default async function handleWebhook(req, res) {
  // verify the webhook signature request against the
  // unmodified, unparsed body
  const body = await getRawBody(req);
  if (!body) {
    res.status(400).send('Bad request (no body)');
    return;
  }

  const jsonBody = JSON.parse(body);

  console.log({ jsonBody });

  const slug = jsonBody.fields.slug;

  console.log({ slug });

  // secret
  const secret = process.env.NEXT_PUBLIC_REVALIDATION;

  if (req.query.secret === secret) {
    // issue opened or edited
    // comment created or edited
    console.log('[Next.js] Revalidating /');
    await res.revalidate('/');
    if (slug) {
      console.log(`[Next.js] Revalidating /${slug}`);
      await res.revalidate(`/${slug}`);
    }

    return res.status(200).send('Success!');
  } else {
    return res.status(403).send('Forbidden');
  }
}

function getRawBody(req) {
  return new Promise((resolve, reject) => {
    let bodyChunks = [];
    req.on('end', () => {
      const rawBody = Buffer.concat(bodyChunks).toString('utf8');
      resolve(rawBody);
    });
    req.on('data', (chunk) => bodyChunks.push(chunk));
  });
}

export const config = {
  api: {
    bodyParser: false,
  },
};
<|endoftext|>


<commit_before>import React, { Component, Fragment } from 'react'
import ErrorPage from 'components/admin/ErrorPage'
import LoadingPage from 'components/LoadingAnimation'
import LoginPage from 'components/apply/Login'
import LeaderForm from 'components/confirm_invite/LeaderForm'
import Nav from 'components/apply/ApplyNav'
import api from 'api'
import Helmet from 'react-helmet'
import {
  Container,
  Card,
  Heading,
  Button,
  Text,
  Box
} from '@hackclub/design-system'
import { Modal, Overlay, CloseButton } from 'components/Modal'

class Invite extends Component {
  constructor(props) {
    super(props)
    this.state = {
      status: props.accepted
        ? 'accepted'
        : props.rejected
          ? 'rejected'
          : 'undecided',
      formActive: false
    }
    this.rejectInvite = this.rejectInvite.bind(this)
    this.acceptInvite = this.acceptInvite.bind(this)
    this.submitAcceptance = this.submitAcceptance.bind(this)
  }

  rejectInvite() {
    const { invite } = this.props
    this.setState({ status: 'loading' })
    api
      .post(`v1/leadership_position_invites/${invite.id}/reject`)
      .then(res => {
        this.setState({ status: 'rejected' })
      })
      .catch(err => {
        console.error(err)
        this.setState({ status: 'error' })
      })
  }

  acceptInvite() {
    const { invite, user } = this.props
    if (user.new_leader) {
      this.setState({ status: 'loading' })
      this.submitAcceptance()
    } else {
      this.setState({ status: 'loading', showForm: true })
    }
  }

  submitAcceptance(newLeader) {
    const { invite, updateLeader } = this.props
    if (newLeader) {
      updateLeader(newLeader)
    }
    this.setState({ showForm: false })
    return api
      .post(`v1/leadership_position_invites/${invite.id}/accept`)
      .then(res => {
        this.setState({ status: 'accepted' })
      })
  }

  renderSwitch() {
    const { status, showForm } = this.state
    const { invite, user } = this.props
    switch (status) {
      case 'loading':
        return (
          <Fragment>
            <Button bg="warning">Loading...</Button>
            {showForm && (
              <Fragment>
                <Modal align="left" my={4} p={[3, 4]}>
                  <CloseButton
                    onClick={() =>
                      this.setState({ status: 'undecided', showForm: false })
                    }
                  />
                  <LeaderForm
                    email={user.email}
                    userId={user.id}
                    clubId={invite.new_club.id}
                    callback={this.submitAcceptance}
                  />
                </Modal>
                <Overlay
                  onClick={() =>
                    this.setState({ status: 'undecided', showForm: false })
                  }
                />
              </Fragment>
            )}
          </Fragment>
        )
      case 'accepted':
        return <Button bg="success">Invite accepted</Button>
      case 'rejected':
        return <Button bg="error">Invite rejected</Button>
      case 'undecided':
        return (
          <Fragment>
            <Button
              color="white"
              bg="primary"
              mx={2}
              onClick={this.acceptInvite}
            >
              Accept
            </Button>
            <Button
              color="white"
              bg="primary"
              mx={2}
              onClick={this.rejectInvite}
              inverted
            >
              Reject
            </Button>
          </Fragment>
        )
      default:
        return <ErrorPage />
    }
  }

  render() {
    const { invite } = this.props
    return (
      <Card p={2} m={3} boxShadowSize="md" align="center">
        <Heading.h2>{invite.new_club.high_school_name}</Heading.h2>
        <Text>{invite.new_club.high_school_adress}</Text>
        <Text>
          invited by {invite.sender.username && `${invite.sender.username} `}
          ({invite.sender.email})
        </Text>
        <Box my={3}>{this.renderSwitch()}</Box>
      </Card>
    )
  }
}

export default class extends Component {
  constructor(props) {
    super(props)
    this.state = { status: 'loading' }
    this.updateLeader = this.updateLeader.bind(this)
  }

  componentDidMount() {
    api
      .get(`v1/users/current`)
      .then(user => {
        this.setState({ user })
        const promiseArray = user.leadership_position_invites.map(invite =>
          api.get(`v1/leadership_position_invites/${invite.id}`)
        )
        return Promise.all(promiseArray)
      })
      .then(invites => {
        const sortedInvites = invites.sort(
          (a, b) => a.created_at < b.created_at
        )
        this.setState({ invites: sortedInvites, status: 'success' })
      })
      .catch(err => {
        if (err.status === 403 || err.status === 401) {
          this.setState({ status: 'needsToAuth' })
        } else {
          this.setState({ status: 'error' })
        }
      })
  }

  updateLeader(newLeader) {
    this.setState({
      user: {
        ...this.state.user,
        new_leader: newLeader
      }
    })
  }

  render() {
    const { status, invites, leader, user } = this.state
    switch (status) {
      case 'loading':
        return <LoadingPage />
      case 'success':
        return (
          <Fragment>
            <Helmet title="Confirm Invitation – Hack Club" />
            <Nav />
            <Container maxWidth={32}>
              {invites.map(invite => (
                <Invite
                  key={invite.id}
                  invite={invite}
                  user={user}
                  updateLeader={this.updateLeader}
                  rejected={invite.rejected_at !== null}
                  accepted={invite.accepted_at !== null}
                />
              ))}
            </Container>
          </Fragment>
        )
      case 'needsToAuth':
        return <LoginPage />
      default:
        return <ErrorPage />
    }
  }
}
<commit_msg>Confirm invites page works for users without invites<commit_after>import React, { Component, Fragment } from 'react'
import ErrorPage from 'components/admin/ErrorPage'
import LoadingPage from 'components/LoadingAnimation'
import LoginPage from 'components/apply/Login'
import LeaderForm from 'components/confirm_invite/LeaderForm'
import Nav from 'components/apply/ApplyNav'
import api from 'api'
import Helmet from 'react-helmet'
import {
  Container,
  Card,
  Heading,
  Button,
  Text,
  Box
} from '@hackclub/design-system'
import { Modal, Overlay, CloseButton } from 'components/Modal'

class Invite extends Component {
  constructor(props) {
    super(props)
    this.state = {
      status: props.accepted
        ? 'accepted'
        : props.rejected
          ? 'rejected'
          : 'undecided',
      formActive: false
    }
    this.rejectInvite = this.rejectInvite.bind(this)
    this.acceptInvite = this.acceptInvite.bind(this)
    this.submitAcceptance = this.submitAcceptance.bind(this)
  }

  rejectInvite() {
    const { invite } = this.props
    this.setState({ status: 'loading' })
    api
      .post(`v1/leadership_position_invites/${invite.id}/reject`)
      .then(res => {
        this.setState({ status: 'rejected' })
      })
      .catch(err => {
        console.error(err)
        this.setState({ status: 'error' })
      })
  }

  acceptInvite() {
    const { invite, user } = this.props
    if (user.new_leader) {
      this.setState({ status: 'loading' })
      this.submitAcceptance()
    } else {
      this.setState({ status: 'loading', showForm: true })
    }
  }

  submitAcceptance(newLeader) {
    const { invite, updateLeader } = this.props
    if (newLeader) {
      updateLeader(newLeader)
    }
    this.setState({ showForm: false })
    return api
      .post(`v1/leadership_position_invites/${invite.id}/accept`)
      .then(res => {
        this.setState({ status: 'accepted' })
      })
  }

  renderSwitch() {
    const { status, showForm } = this.state
    const { invite, user } = this.props
    switch (status) {
      case 'loading':
        return (
          <Fragment>
            <Button bg="warning">Loading...</Button>
            {showForm && (
              <Fragment>
                <Modal align="left" my={4} p={[3, 4]}>
                  <CloseButton
                    onClick={() =>
                      this.setState({ status: 'undecided', showForm: false })
                    }
                  />
                  <LeaderForm
                    email={user.email}
                    userId={user.id}
                    clubId={invite.new_club.id}
                    callback={this.submitAcceptance}
                  />
                </Modal>
                <Overlay
                  onClick={() =>
                    this.setState({ status: 'undecided', showForm: false })
                  }
                />
              </Fragment>
            )}
          </Fragment>
        )
      case 'accepted':
        return <Button bg="success">Invite accepted</Button>
      case 'rejected':
        return <Button bg="error">Invite rejected</Button>
      case 'undecided':
        return (
          <Fragment>
            <Button
              color="white"
              bg="primary"
              mx={2}
              onClick={this.acceptInvite}
            >
              Accept
            </Button>
            <Button
              color="white"
              bg="primary"
              mx={2}
              onClick={this.rejectInvite}
              inverted
            >
              Reject
            </Button>
          </Fragment>
        )
      default:
        return <ErrorPage />
    }
  }

  render() {
    const { invite } = this.props
    return (
      <Card p={2} m={3} boxShadowSize="md" align="center">
        <Heading.h2>{invite.new_club.high_school_name}</Heading.h2>
        <Text>{invite.new_club.high_school_adress}</Text>
        <Text>
          invited by {invite.sender.username && `${invite.sender.username} `}
          ({invite.sender.email})
        </Text>
        <Box my={3}>{this.renderSwitch()}</Box>
      </Card>
    )
  }
}

export default class extends Component {
  constructor(props) {
    super(props)
    this.state = { status: 'loading' }
    this.updateLeader = this.updateLeader.bind(this)
  }

  componentDidMount() {
    api
      .get(`v1/users/current`)
      .then(user => {
        this.setState({ user })
        const promiseArray = user.leadership_position_invites.map(invite =>
          api.get(`v1/leadership_position_invites/${invite.id}`)
        )
        return Promise.all(promiseArray)
      })
      .then(invites => {
        const sortedInvites = invites.sort(
          (a, b) => a.created_at < b.created_at
        )
        this.setState({ invites: sortedInvites, status: 'success' })
      })
      .catch(err => {
        if (err.status === 403 || err.status === 401) {
          this.setState({ status: 'needsToAuth' })
        } else {
          this.setState({ status: 'error' })
        }
      })
  }

  updateLeader(newLeader) {
    this.setState({
      user: {
        ...this.state.user,
        new_leader: newLeader
      }
    })
  }

  render() {
    const { status, invites, leader, user } = this.state
    switch (status) {
      case 'loading':
        return <LoadingPage />
      case 'success':
        return (
          <Fragment>
            <Helmet title="Confirm Invitation – Hack Club" />
            <Nav />
            <Container maxWidth={32}>
              {invites.map(invite => (
                <Invite
                  key={invite.id}
                  invite={invite}
                  user={user}
                  updateLeader={this.updateLeader}
                  rejected={invite.rejected_at !== null}
                  accepted={invite.accepted_at !== null}
                />
              ))}
              {invites.length === 0 && (
                <Box align="center">
                  <Heading.h2 my={3}>No invites here!</Heading.h2>
                  <Text>
                    We couldn’t find any invites for{' '}
                    <Text.span bold>{user.email}</Text.span>.
                  </Text>
                </Box>
              )}
            </Container>
          </Fragment>
        )
      case 'needsToAuth':
        return <LoginPage />
      default:
        return <ErrorPage />
    }
  }
}
<|endoftext|>


<commit_before>'use strict'

/* eslint-disable no-new-func */

const common = {
  toFunction: function (validators) {
    if (!Array.isArray(validators)) {
      throw new TypeError('Validators is not an array')
    }
    // Function code
    let code = `  "use strict"
  let errors = 0
  `

    // Here we get the validator function code
    validators.forEach(validator => {
      // Error checking
      if (typeof validator !== 'object') {
        throw new TypeError('Validator is not an object')
      }
      if (typeof validator.parameters !== 'object') {
        throw new TypeError('validator.parameters is not an object')
      }
      if (typeof validator.function !== 'function') {
        throw new TypeError('validator.function is not a function')
      }

      // Begins a new block scope
      code += '{'
      // Stringify the validator function code
      const functionCode = validator.function.toString()
      // Here we remove the function declaration,
      // this works ONLY if there are not destructuring assignment as parameters.
      // Because of the lib design the validator function has never parameters,
      // so we can be "safe" about the following implementation.
      const linesOfCode = functionCode.substring(functionCode.indexOf('{') + 1, functionCode.lastIndexOf('}'))
                                      .split('\n')
                                      .filter(line => line.trim() !== '') // Removes empty lines
      // gets first line indentation
      const spaces = linesOfCode[0].search(/\S/)
      const params = validator.parameters
      linesOfCode.forEach(line => {
        for (let val in params) {
          let value
          if (typeof params[val] === 'string') {
            value = `'${params[val]}'`

          // If the variable is an object (but not an instance of RegExp) we stringify it
          } else if (typeof params[val] === 'object' && !(params[val] instanceof RegExp)) {
            value = JSON.stringify(params[val])

          // If the variable is a function
          } else if (typeof params[val] === 'function') {
            value = params[val].toString()

          // In all the other cases we add it 'as is' to the code
          } else {
            value = params[val]
          }
          // Replace $varname$ with its value
          line = line.replace(new RegExp('\\' + val.substring(0, val.length - 1) + '\\$', 'g'), value)
        }
        code += `
    ${line.slice(spaces)}`
      })
      // Ends the block scope
      code += `
  };`
    })

    // Adds the final return
    code += `
  return errors === 0`
    // Generates the new Function
    return new Function('value', code)
  },

  or: function () {
    const functions = Array.prototype.slice.call(arguments)
    let code = `  "use strict"
    `
    let returnCode = `
    return`

    functions.forEach((func, index) => {
      if (typeof func !== 'function') {
        throw new Error('tyval.or, parameters must be functions')
      }
      code += `
    const validate${index} = ${func.toString()}`
      returnCode += ` validate${index}(orValue)`
      if (index < functions.length - 1) {
        returnCode += ' ||'
      }
    })

    code += `
    function orify (orValue) {${returnCode}
    }
    return orify`
    return new Function(code)()
  },

  // Thanks to: https://davidwalsh.name/javascript-arguments
  getArgs: function (func) {
    if (typeof func !== 'function') {
      throw new TypeError('func is not a function')
    }

    // First match everything inside the function argument parens.
    let args = func.toString().match(/function\s.*?\(([^)]*)\)/)[1]

    // Split the arguments string into an array comma delimited.
    return args.split(',').map(function (arg) {
      // Ensure no inline comments are parsed and trim the whitespace.
      return arg.replace(/\/\*.*\*\//, '').trim()
    }).filter(function (arg) {
      // Ensure no undefined values are added.
      return arg
    })
  },

  extend: function (tyvalValidator, func) {
    if (typeof func !== 'function') {
      throw new TypeError('func is not a function')
    }

    // Gets the parameters name
    const parametersName = this.getArgs(func)

    // Extends the passed tyval validator with a new function
    tyvalValidator[func.name] = function () {
      // gets the parameters passed as arguments
      const parametersValue = Array.prototype.slice.call(arguments)
      if (parametersName.length !== parametersValue.length) {
        throw new Error('The length of parametersName and parametersValue do not coincide')
      }

      // Instantiate the parameters object
      const parameters = {}
      for (let i = 0; i < parametersName.length; i++) {
        // Adds the parameters name: value
        parameters['$' + parametersName[i] + '$'] = parametersValue[i]
      }

      // Push the function and the generated parameters object
      tyvalValidator.validators.push({
        function: func,
        parameters: parameters
      })

      return tyvalValidator
    }
  }
}

module.exports = common
<commit_msg>Refactored toFunction and extend<commit_after>'use strict'

/* eslint-disable no-new-func */

const common = {
  toFunction: function (validatorObject) {
    if (typeof validatorObject !== 'function') {
      throw new TypeError('validatorObject is not a function')
    }
    return (context, validatorFunction, validatorParameters) => {
      // Error checking
      if (typeof context !== 'function' && context !== null) {
        throw new TypeError('context is not a function or null')
      }
      if (typeof validatorFunction !== 'function') {
        throw new TypeError('validatorFunction must be a function')
      }
      if (validatorParameters && typeof validatorParameters !== 'object') {
        throw new TypeError('validatorParameters must be an object')
      }

      // Returns an array with every line of the function
      // Here we remove the function declaration,
      // this works ONLY if there are not destructuring assignment as parameters.
      // Because of the lib design the validator function has never parameters,
      // so we can be "safe" about the following implementation.
      const linesOfCode = func => {
        func = func.toString()
        return func.substring(func.indexOf('{') + 1, func.lastIndexOf('}'))
                   .split('\n')
                   .filter(line => line.trim() !== '') // Removes empty lines
      }

      let code = ''
      // if the validator has already been defined
      if (context !== null) {
        let lines = linesOfCode(context)
        // Gets the number of spaces between
        // the beginning of the string and the first character
        let spaces = lines[0].search(/\S/)
        // Formats the indentation
        lines.forEach((line, index) => {
          if (index === lines.length - 1) return
          if (line.trim() === '{') spaces = line.search(/\S/)
          code += `
     ${line.slice(spaces)}`
        })
      // if is a new validator
      } else {
      // Function code
        code = `
    "use strict"
  `
      }

      code += `
    {`
      const lines = linesOfCode(validatorFunction)
      const spaces = lines[0].search(/\S/)

      lines.forEach(line => {
        for (let val in validatorParameters) {
          let value
          if (typeof validatorParameters[val] === 'string') {
            value = `'${validatorParameters[val]}'`

          // If the variable is an object (but not an instance of RegExp) we stringify it
          } else if (typeof validatorParameters[val] === 'object' && !(validatorParameters[val] instanceof RegExp)) {
            value = JSON.stringify(validatorParameters[val])

          // If the variable is a function
          } else if (typeof validatorParameters[val] === 'function') {
            value = validatorParameters[val].toString()

          // In all the other cases we add it 'as is' to the code
          } else {
            value = validatorParameters[val]
          }
          // Replace $varname$ with its value
          line = line.replace(new RegExp('\\' + val.substring(0, val.length - 1) + '\\$', 'g'), value)
        }
        code += `
      ${line.slice(spaces)}`
      })
      // Ends the block scope
      code += `
    };`

      code += `
    return true`

      // Appends all the validator functions to the newly generated function
      const func = new Function('value', code)
      Object.keys(validatorObject).forEach(val => {
        func[val] = validatorObject[val]
      })

      // Fix for .length property
      Object.defineProperty(func, 'length', {
        writable: true
      })
      if (typeof validatorObject.length === 'function') {
        func.length = validatorObject.length
      }

      return func
    }
  },

  or: function () {
    const functions = Array.prototype.slice.call(arguments)
    let code = `  "use strict"
    `
    let returnCode = `
    return`

    functions.forEach((func, index) => {
      if (typeof func !== 'function') {
        throw new Error('tyval.or, parameters must be functions')
      }
      // Stringify every validator function in the code
      code += `
    const validate${index} = ${func.toString()}`
      // Call every declared function
      returnCode += ` validate${index}(orValue)`
      if (index < functions.length - 1) {
        returnCode += ' ||'
      }
    })

    // Declares all the validator functions
    // and use them with closures
    code += `
    function orify (orValue) {${returnCode}
    }
    return orify`
    return new Function(code)()
  },

  extend: function (tyvalValidator, func, toFunction) {
    // Error checking
    if (typeof tyvalValidator !== 'function') {
      throw new TypeError('tyvalValidator is not a function')
    }
    if (typeof func !== 'function') {
      throw new TypeError('func is not a function')
    }
    if (typeof toFunction !== 'function') {
      throw new TypeError('toFunction is not a function')
    }

    // Thanks to: https://davidwalsh.name/javascript-arguments
    // gets the name of the arguments of a function
    const getArgs = func => {
      // First match everything inside the function argument parens.
      let args = func.toString().match(/function\s.*?\(([^)]*)\)/)[1]
      // Split the arguments string into an array comma delimited.
      return args.split(',').map(arg => {
        // Ensure no inline comments are parsed and trim the whitespace.
        return arg.replace(/\/\*.*\*\//, '').trim()
      }).filter(arg => {
        // Ensure no undefined values are added.
        return arg
      })
    }

    // Gets the parameters name
    const parametersName = getArgs(func)

    // Extends the passed tyval validator with a new function
    tyvalValidator[func.name] = function () {
      // gets the parameters passed as arguments
      const parametersValue = Array.prototype.slice.call(arguments)
      if (parametersName.length !== parametersValue.length) {
        throw new Error('The length of parametersName and parametersValue do not coincide')
      }

      // Instantiate the parameters object
      const parameters = {}
      for (let i = 0; i < parametersName.length; i++) {
        // Adds the parameters name: value
        parameters['$' + parametersName[i] + '$'] = parametersValue[i]
      }

      return toFunction(this, func, parameters)
    }
  }
}

module.exports = common
<|endoftext|>


<commit_before>/**
 * @file get config
 * @author nighca<nighca@live.cn>
 */

var path = require('path');
var Manis = require('manis');
var yaml = require('js-yaml');
var stripJSONComments = require('strip-json-comments');

var util = require('./util');
var fsUtil = require('./fs-util');

/**
 * Name of the config file.
 *
 * @type {string}
 * @const
 */
var CONFIG_FILENAME = '.htmlcsrc';
var YAML_CONFIG_FILENAME = '.htmlcsrc.yml';

/**
 * Parse given config text content.
 *
 * @param {string} text - given config text content
 * @return {?Object} the config content
 */
var parseConfig = function (text) {
    try {
        return JSON.parse(stripJSONComments(text));
    }
    catch (e) {
        return yaml.safeLoad(text);
    }
};

/**
 * Load config for given file.
 *
 * @param {string} filePath - path of given file
 * @param {boolean=} refresh - if skips cache
 * @return {?Object} the config content
 */
var loadConfig = util.cachable(function (filePath, refresh) {
    var options = {
        orphan: true,
        loader: parseConfig
    };

    var manis = new Manis(CONFIG_FILENAME, options);
    manis.setDefault(path.join(fsUtil.app.root, 'lib/default/htmlcsrc'), options);
    manis.setUserConfig();

    return manis.from(filePath);
});

module.exports = {
    fileName: CONFIG_FILENAME,
    parse: parseConfig,
    load: loadConfig
};
<commit_msg>remove nosue variable<commit_after>/**
 * @file get config
 * @author nighca<nighca@live.cn>
 */

var path = require('path');
var Manis = require('manis');
var yaml = require('js-yaml');
var stripJSONComments = require('strip-json-comments');

var util = require('./util');
var fsUtil = require('./fs-util');

/**
 * Name of the config file.
 *
 * @type {string}
 * @const
 */
var CONFIG_FILENAME = '.htmlcsrc';

/**
 * Parse given config text content.
 *
 * @param {string} text - given config text content
 * @return {?Object} the config content
 */
var parseConfig = function (text) {
    try {
        return JSON.parse(stripJSONComments(text));
    }
    catch (e) {
        return yaml.safeLoad(text);
    }
};

/**
 * Load config for given file.
 *
 * @param {string} filePath - path of given file
 * @param {boolean=} refresh - if skips cache
 * @return {?Object} the config content
 */
var loadConfig = util.cachable(function (filePath, refresh) {
    var options = {
        orphan: true,
        loader: parseConfig
    };

    var manis = new Manis(CONFIG_FILENAME, options);
    manis.setDefault(path.join(fsUtil.app.root, 'lib/default/htmlcsrc'), options);
    manis.setUserConfig();

    return manis.from(filePath);
});

module.exports = {
    fileName: CONFIG_FILENAME,
    parse: parseConfig,
    load: loadConfig
};
<|endoftext|>