<commit_before>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var Validate = exports;

function InvalidValueError(message) {
  this.message = message;
  this.name = 'InvalidValueError';
  Error.captureStackTrace(this, InvalidValueError);
}
InvalidValueError.prototype = Object.create(Error.prototype);
InvalidValueError.prototype.constructor = InvalidValueError;

InvalidValueError.prepend = function(message, error) {
  if (error instanceof InvalidValueError) {
    return new InvalidValueError(message + ': ' + error.message);
  }
  return error;
};

Validate.InvalidValueError = InvalidValueError;

Validate.acceptAll = function(value) {
  return value;
};

Validate.optional = function(validator) {
  return function(value) {
    return (value == undefined) ? value : validator(value);
  };
};

Validate.that = function(predicate, message) {
  return function(value) {
    if (predicate(value)) return value;
    throw new InvalidValueError(message);
  };
};

Validate.number = Validate.that(function(value) {
  return typeof value === 'number';
}, 'not a number');

Validate.string = Validate.that(function(value) {
  return typeof value === 'string';
}, 'not a string');

Validate.object = function(propertyValidators) {
  return function(object) {
    var result = {};

    if (!object || typeof object !== 'object') {
      throw new InvalidValueError('not an Object');
    }

    // Validate all properties.
    for (key in propertyValidators) {
      var validator = propertyValidators[key];
      try {
        var valid = validator(object[key]);
      } catch (error) {
        if (key in object) {
          throw InvalidValueError.prepend('in property "' + key + '"', error);
        } else {
          throw new InvalidValueError('missing property "' + key + '"');
        }
      }
      if (key in object && valid !== undefined) {
        result[key] = valid;
      }
    }

    // Check for unexpected properties.
    for (var key in object) {
      if (!propertyValidators[key]) {
        throw new InvalidValueError('unexpected property "' + key + '"');
      }
    }

    return result;
  };
};

Validate.array = function(validator) {
  return function(array) {
    var result = [];

    if (Object.prototype.toString.call(array) !== '[object Array]') {
      throw new InvalidValueError('not an Array');
    }

    for (var i = 0; i < array.length; ++i) {
      try {
        result[i] = validator(array[i]);
      } catch (error) {
        throw InvalidValueError.prepend('at index ' + i, error);
      }
    }

    return result;
  };
};

Validate.oneOf = function(names) {
  var myObject = {};
  var quotedNames = [];
  names.forEach(function(name) {
    myObject[name] = true;
    quotedNames.push('"' + name + '"');
  });

  return function(value) {
    if (myObject[value]) return value;
    throw new InvalidValueError('not one of ' + quotedNames.join(', '));
  };
};

Validate.mutuallyExclusiveProperties = function(names) {
  return function(value) {
    if (!value) return value;

    var present = [];
    names.forEach(function(name) {
      if (name in value) {
        present.push('"' + name + '"');
      }
    });

    if (present.length > 1) {
      throw new InvalidValueError(
          'cannot specify properties '
          + present.slice(0, -1).join(', ')
          + ' and '
          + present.slice(-1)
          + ' together');
    }

    return value;
  };
};

Validate.compose = function(validators) {
  return function(value) {
    validators.forEach(function(validate) {
      value = validate(value);
    });
    return value;
  };
};

Validate.boolean = Validate.compose([
  Validate.that(function(value) {
    return typeof value === 'boolean';
  }, 'not a boolean'),
  function(value) {
    // In each API, boolean fields default to false, and the presence of
    // a querystring value indicates true, so we omit the value if
    // explicitly set to false.
    return value ? value : undefined;
  }
]);<commit_msg>Fix default arg handling. Closes #123.<commit_after>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var Validate = exports;

function InvalidValueError(message) {
  this.message = message;
  this.name = 'InvalidValueError';
  Error.captureStackTrace(this, InvalidValueError);
}
InvalidValueError.prototype = Object.create(Error.prototype);
InvalidValueError.prototype.constructor = InvalidValueError;

InvalidValueError.prepend = function(message, error) {
  if (error instanceof InvalidValueError) {
    return new InvalidValueError(message + ': ' + error.message);
  }
  return error;
};

Validate.InvalidValueError = InvalidValueError;

Validate.acceptAll = function(value) {
  return value;
};

Validate.optional = function(validator) {
  return function(value) {
    return (value == undefined) ? value : validator(value);
  };
};

Validate.that = function(predicate, message) {
  return function(value) {
    if (predicate(value)) return value;
    throw new InvalidValueError(message);
  };
};

Validate.number = Validate.that(function(value) {
  return typeof value === 'number';
}, 'not a number');

Validate.string = Validate.that(function(value) {
  return typeof value === 'string';
}, 'not a string');

Validate.object = function(propertyValidators) {
  return function(object) {
    var result = {};

    if (!object || typeof object !== 'object') {
      throw new InvalidValueError('not an Object');
    }

    // Validate all properties.
    for (key in propertyValidators) {
      var validator = propertyValidators[key];
      try {
        var valid = validator(object[key]);
      } catch (error) {
        if (key in object) {
          throw InvalidValueError.prepend('in property "' + key + '"', error);
        } else {
          throw new InvalidValueError('missing property "' + key + '"');
        }
      }
      if (key in object || valid !== undefined) {
        result[key] = valid;
      }
    }

    // Check for unexpected properties.
    for (var key in object) {
      if (!propertyValidators[key]) {
        throw new InvalidValueError('unexpected property "' + key + '"');
      }
    }

    return result;
  };
};

Validate.array = function(validator) {
  return function(array) {
    var result = [];

    if (Object.prototype.toString.call(array) !== '[object Array]') {
      throw new InvalidValueError('not an Array');
    }

    for (var i = 0; i < array.length; ++i) {
      try {
        result[i] = validator(array[i]);
      } catch (error) {
        throw InvalidValueError.prepend('at index ' + i, error);
      }
    }

    return result;
  };
};

Validate.oneOf = function(names) {
  var myObject = {};
  var quotedNames = [];
  names.forEach(function(name) {
    myObject[name] = true;
    quotedNames.push('"' + name + '"');
  });

  return function(value) {
    if (myObject[value]) return value;
    throw new InvalidValueError('not one of ' + quotedNames.join(', '));
  };
};

Validate.mutuallyExclusiveProperties = function(names) {
  return function(value) {
    if (!value) return value;

    var present = [];
    names.forEach(function(name) {
      if (name in value) {
        present.push('"' + name + '"');
      }
    });

    if (present.length > 1) {
      throw new InvalidValueError(
          'cannot specify properties '
          + present.slice(0, -1).join(', ')
          + ' and '
          + present.slice(-1)
          + ' together');
    }

    return value;
  };
};

Validate.compose = function(validators) {
  return function(value) {
    validators.forEach(function(validate) {
      value = validate(value);
    });
    return value;
  };
};

Validate.boolean = Validate.compose([
  Validate.that(function(value) {
    return typeof value === 'boolean';
  }, 'not a boolean'),
  function(value) {
    // In each API, boolean fields default to false, and the presence of
    // a querystring value indicates true, so we omit the value if
    // explicitly set to false.
    return value ? value : undefined;
  }
]);<|endoftext|>


<commit_before>// As explained here: http://code.google.com/p/phantomjs/wiki/QuickStart

var page = new WebPage(), address, output, size;
//console.log('Usage: rasterize.js URL filename');

var args = require('system').args;

//var chinese_fonts = ['Microsoft yahei', 'Droid Sans Fallback', "宋体", "方正韵动中黑简体", "方正兰亭黑简体", "方正兰亭中黑_GBK", ".萍方-简"]
font = "'Helvetica','\\u65B9\\u6B63\\u5170\\u4EAD\\u4E2D\\u9ED1_GBK','Microsoft yahei','Segoe UI Symbol'";

var cookies = phantom.addCookie({
  'name': 'SUB',
  'domain': '.weibo.cn',
  'value': args[4],
  'path': '/'
});

address = args[1];
output = args[2];
page.viewportSize = {width: 880, height: 600};
page.zoomFactor = 2;

// http://phantomjs.org/api/webpage/handler/on-resource-requested.html
// page.onResourceRequested = function(requestData, networkRequest) {
//   //console.log('Request (#' + requestData.id + '): ' + JSON.stringify(requestData));
//   console.log(requestData.url);
//   if (requestData.url.indexOf('comment') != -1) {
//     //networkRequest.abort();
//     networkRequest.changeUrl("");
//   }
// };

page.open(address, function (status) {
    if (status !== 'success') {
        console.log('Unable to load the address!');
        phantom.exit();
    } else {
        console.log('Page loading status: ' + status);
        if (address.indexOf("comment") != -1) {
          window.setInterval(function() {
              page.evaluate(function() {
                // Scrolls to the bottom of page
                window.document.body.scrollTop = document.body.scrollHeight;
              });
          }, 9500);
        }

        window.setTimeout(function () {
            page.evaluate(function (font) {
                var r = /\\u([\d\w]{4})/gi;
                font = font.replace(r, function (match, grp) {
                        return String.fromCharCode(parseInt(grp, 16));});
                font = unescape(font);
                document.body.style["fontFamily"]=font;
            }, font);

            // page.evaluate(function() {
            //   var cmtTab = document.querySelectorAll('[cont-type="cmtTab"]')[0];
            //   if (cmtTab != null) {
            //     var ul = cmtTab.getElementsByTagName('ul');
            //     if (ul != null && ul.length > 1) {
            //         //ul[1].parentNode.removeChild(ul[1]);
            //         //ul[1].remove();
            //         ul[1].setAttribute('style', 'display:none');
            //     }
            //   }

            //   var cmtTab = document.querySelectorAll('[data-node-type="comment-list"]')[0];
            //   if (cmtTab != null) {
            //     var sec = cmtTab.getElementsByTagName('section');
            //     if (sec != null && sec.length > 1) {
            //         //sec[1].parentNode.removeChild(sec[1]);
            //         //sec[1].remove();
            //         sec[1].setAttribute('style', 'display:none');
            //     }
            //   }
            // });

            var clipRect = page.evaluate(function(){
              var m1 = document.getElementsByClassName("module-infobox line-bottom more");
              if (m1.length != 0) return m1[0].getBoundingClientRect();

              var m2 = document.getElementsByClassName("commment-more");
              if (m2.length != 0) return m2[0].getBoundingClientRect();

              var m3 = document.getElementsByClassName("comment-more");
              if (m3.length != 0) return m3[0].getBoundingClientRect();

              return null;
            });

            if (clipRect != null) {
              page.clipRect = {
                top: 0,
                left: 0,
                width: page.viewportSize['width'],
                height: clipRect.top*page.zoomFactor + clipRect.height*page.zoomFactor*2
              };
            }

            page.render(output);
            phantom.exit();
        }, args[3]);
    }
});<commit_msg>Update js script<commit_after>// As explained here: http://code.google.com/p/phantomjs/wiki/QuickStart

var page = new WebPage(), address, output, size;
//console.log('Usage: rasterize.js URL filename');

var args = require('system').args;

// console.log(args[0]);
// console.log(args[1]);
// console.log(args[2]);
// console.log(args[3]);
// console.log(args[4]);

//var chinese_fonts = ['Microsoft yahei', 'Droid Sans Fallback', "宋体", "方正韵动中黑简体", "方正兰亭黑简体", "方正兰亭中黑_GBK", ".萍方-简"]
font = "'Helvetica','\\u65B9\\u6B63\\u5170\\u4EAD\\u4E2D\\u9ED1_GBK','Microsoft yahei','Segoe UI Symbol'";

var cookies = phantom.addCookie({
  'name': 'SUB',
  'domain': '.weibo.cn',
  'value': args[4],
  'path': '/'
});

address = args[1];
output = args[2];
page.viewportSize = {width: 880, height: 600};
page.zoomFactor = 2;

// http://phantomjs.org/api/webpage/handler/on-resource-requested.html
// page.onResourceRequested = function(requestData, networkRequest) {
//   //console.log('Request (#' + requestData.id + '): ' + JSON.stringify(requestData));
//   console.log(requestData.url);
//   if (requestData.url.indexOf('comment') != -1) {
//     //networkRequest.abort();
//     networkRequest.changeUrl("");
//   }
// };

page.open(address, function (status) {
    if (status !== 'success') {
        console.log('Unable to load the address!');
        phantom.exit();
    } else {
        console.log('Page loading status: ' + status);
        if (address.indexOf("comment") != -1) {
          window.setInterval(function() {
              page.evaluate(function() {
                // Scrolls to the bottom of page
                window.document.body.scrollTop = document.body.scrollHeight;
              });
          }, 10000);
        }

        window.setTimeout(function () {
            page.evaluate(function (font) {
                var r = /\\u([\d\w]{4})/gi;
                font = font.replace(r, function (match, grp) {
                        return String.fromCharCode(parseInt(grp, 16));});
                font = unescape(font);
                document.body.style["fontFamily"]=font;
            }, font);

            // page.evaluate(function() {
            //   var cmtTab = document.querySelectorAll('[cont-type="cmtTab"]')[0];
            //   if (cmtTab != null) {
            //     var ul = cmtTab.getElementsByTagName('ul');
            //     if (ul != null && ul.length > 1) {
            //         //ul[1].parentNode.removeChild(ul[1]);
            //         //ul[1].remove();
            //         ul[1].setAttribute('style', 'display:none');
            //     }
            //   }

            //   var cmtTab = document.querySelectorAll('[data-node-type="comment-list"]')[0];
            //   if (cmtTab != null) {
            //     var sec = cmtTab.getElementsByTagName('section');
            //     if (sec != null && sec.length > 1) {
            //         //sec[1].parentNode.removeChild(sec[1]);
            //         //sec[1].remove();
            //         sec[1].setAttribute('style', 'display:none');
            //     }
            //   }
            // });

            if (address.indexOf("comment") == -1) {
              var clipRect = page.evaluate(function(){
                var m1 = document.getElementsByClassName("module-infobox line-bottom more");
                if (m1.length != 0) return m1[0].getBoundingClientRect();

                var m2 = document.getElementsByClassName("commment-more");
                if (m2.length != 0) return m2[0].getBoundingClientRect();

                var m3 = document.getElementsByClassName("comment-more");
                if (m3.length != 0) return m3[0].getBoundingClientRect();

                return null;
              });

              if (clipRect != null) {
                page.clipRect = {
                  top: 0,
                  left: 0,
                  width: page.viewportSize['width'],
                  height: clipRect.top*page.zoomFactor + clipRect.height*page.zoomFactor*2
                };
              }
            }

            page.render(output);
            phantom.exit();
        }, args[3]);
    }
});<|endoftext|>


<commit_before>var checkInterval = 300;
var paramString = "?ts=4&w=1";

function setLocationWhenPageFullyLoaded(newLocation) {
	var retry = false;

	if (location.href.indexOf("/pull-request/new") > -1) {
		if (!!document.getElementById("compare-tabs") != true)
			retry = true;
	}
	else if (location.href.indexOf("/pull-request/update/") > -1) { // viewing an existing pull request
		if (!!document.getElementById("diff") != true)
			retry = true;
	}
	else if (location.href.indexOf("/pull-request/") > -1) { // viewing an existing pull request
		if (!!document.getElementById("pullrequest-diff") != true)
			retry = true;
	}

	if (retry == true)
		setTimeout(function(){ setLocationWhenPageFullyLoaded(newLocation); }, checkInterval);
	else
		location.href = newLocation;
}

function addParametersToPullRequestLinks() {
    var elems = document.getElementsByTagName('a');
    var count = elems.length;
    for (var i = 0; i < count; i++) {
        if((' ' + elems[i].className + ' ').indexOf(' execute ') > -1
        || (' ' + elems[i].className + ' ').indexOf(' comments-link ') > -1
        || (' ' + elems[i].className + ' ').indexOf(' likes-link ') > -1) {
			if (elems[i].href.indexOf("/pull-request/") > -1 && elems[i].href.indexOf(paramString) == -1)
				elems[i].href = elems[i].href + paramString;
        }
    }

    setTimeout(function(){ addParametersToPullRequestLinks(); }, checkInterval);
}

function addParametersToCommitLinks() {
    var elems = document.getElementsByTagName('a');
    var count = elems.length;
    for (var i = 0; i < count; i++) {
        if((' ' + elems[i].className + ' ').indexOf(' hash execute ') > -1) {
			if (elems[i].href.indexOf("/commits/") > -1 && elems[i].href.indexOf(paramString) == -1)
				elems[i].href = elems[i].href + paramString;
        }
    }

    setTimeout(function(){ addParametersToPullRequestLinks(); }, checkInterval);
}

if (location.href.indexOf("/pull-requests") > -1) {	// if viewing the main pull requests page
	var createPullRequestLink = document.getElementById("create-pull-request-contextual");

	// modify "Create pull request" link
	if (!!createPullRequestLink == true) {
		var suffix = "/pull-request/new";
		if (createPullRequestLink.href.indexOf(suffix, this.length - suffix.length) !== -1) // i.e. if (string.endsWith(suffix))
			createPullRequestLink.href = createPullRequestLink.href + paramString;
	}

	setTimeout(function(){ addParametersToPullRequestLinks(); }, checkInterval);
}
else { // viewing any other page, pull request diff, new pull request, update pull request or a commit page
	var queryParameters = location.search.length
		? location.search.replace('?', '').split('&')
		: []
	;

	var tabsParameter = 'ts=4';
	var tabsIndex = queryParameters.indexOf(tabsParameter);
	var whiteSpaceParameter	= 'w=1';
	var whiteSpaceIndex = queryParameters.indexOf(whiteSpaceParameter);

	var parametersChanged = false;

	if (tabsIndex == -1) {
		queryParameters.push(tabsParameter);
		parametersChanged = true;
	}

	if (whiteSpaceIndex == -1) {
		queryParameters.push(whiteSpaceParameter);
		parametersChanged = true;
	}

	if (parametersChanged == true) {
		var newLocation = location.pathname + '?' + queryParameters.join('&') + location.hash;
		setTimeout(function(){ setLocationWhenPageFullyLoaded(newLocation); }, checkInterval);
	}

	if (location.href.indexOf("/commits/") == -1)
		setTimeout(function(){ addParametersToCommitLinks(); }, checkInterval);
}<commit_msg>Fixing a typo.<commit_after>var checkInterval = 300;
var paramString = "?ts=4&w=1";

function setLocationWhenPageFullyLoaded(newLocation) {
	var retry = false;

	if (location.href.indexOf("/pull-request/new") > -1) {
		if (!!document.getElementById("compare-tabs") != true)
			retry = true;
	}
	else if (location.href.indexOf("/pull-request/update/") > -1) { // viewing an existing pull request
		if (!!document.getElementById("diff") != true)
			retry = true;
	}
	else if (location.href.indexOf("/pull-request/") > -1) { // viewing an existing pull request
		if (!!document.getElementById("pullrequest-diff") != true)
			retry = true;
	}

	if (retry == true)
		setTimeout(function(){ setLocationWhenPageFullyLoaded(newLocation); }, checkInterval);
	else
		location.href = newLocation;
}

function addParametersToPullRequestLinks() {
    var elems = document.getElementsByTagName('a');
    var count = elems.length;
    for (var i = 0; i < count; i++) {
        if((' ' + elems[i].className + ' ').indexOf(' execute ') > -1
        || (' ' + elems[i].className + ' ').indexOf(' comments-link ') > -1
        || (' ' + elems[i].className + ' ').indexOf(' likes-link ') > -1) {
			if (elems[i].href.indexOf("/pull-request/") > -1 && elems[i].href.indexOf(paramString) == -1)
				elems[i].href = elems[i].href + paramString;
        }
    }

    setTimeout(function(){ addParametersToPullRequestLinks(); }, checkInterval);
}

function addParametersToCommitLinks() {
    var elems = document.getElementsByTagName('a');
    var count = elems.length;
    for (var i = 0; i < count; i++) {
        if((' ' + elems[i].className + ' ').indexOf(' hash execute ') > -1) {
			if (elems[i].href.indexOf("/commits/") > -1 && elems[i].href.indexOf(paramString) == -1)
				elems[i].href = elems[i].href + paramString;
        }
    }

    setTimeout(function(){ addParametersToCommitLinks(); }, checkInterval);
}

if (location.href.indexOf("/pull-requests") > -1) {	// if viewing the main pull requests page
	var createPullRequestLink = document.getElementById("create-pull-request-contextual");

	// modify "Create pull request" link
	if (!!createPullRequestLink == true) {
		var suffix = "/pull-request/new";
		if (createPullRequestLink.href.indexOf(suffix, this.length - suffix.length) !== -1) // i.e. if (string.endsWith(suffix))
			createPullRequestLink.href = createPullRequestLink.href + paramString;
	}

	setTimeout(function(){ addParametersToPullRequestLinks(); }, checkInterval);
}
else { // viewing any other page, pull request diff, new pull request, update pull request or a commit page
	var queryParameters = location.search.length
		? location.search.replace('?', '').split('&')
		: []
	;

	var tabsParameter = 'ts=4';
	var tabsIndex = queryParameters.indexOf(tabsParameter);
	var whiteSpaceParameter	= 'w=1';
	var whiteSpaceIndex = queryParameters.indexOf(whiteSpaceParameter);

	var parametersChanged = false;

	if (tabsIndex == -1) {
		queryParameters.push(tabsParameter);
		parametersChanged = true;
	}

	if (whiteSpaceIndex == -1) {
		queryParameters.push(whiteSpaceParameter);
		parametersChanged = true;
	}

	if (parametersChanged == true) {
		var newLocation = location.pathname + '?' + queryParameters.join('&') + location.hash;
		setTimeout(function(){ setLocationWhenPageFullyLoaded(newLocation); }, checkInterval);
	}

	if (location.href.indexOf("/commits/") == -1)
		setTimeout(function(){ addParametersToCommitLinks(); }, checkInterval);
}<|endoftext|>


<commit_before>(function (ng, $) {
  "use strict";

  ng.module('BackendApp', [
    'ngCookies', 'ngSanitize', 'ngResource', 'ngAnimate', 'ngMaterial',
    'ngWebSocket',
    'ui.bootstrap',
    'directives', 'truncate',
    'monospaced.elastic',
    'angular-loading-bar', 'angular-redactor'
  ])

    .config([
      '$httpProvider', '$animateProvider', '$mdThemingProvider',
      function ($httpProvider, $animateProvider, $mdThemingProvider) {
        $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
        $httpProvider.defaults.headers.common['X-CSRF-Token'] = yii.getCsrfToken();

        $animateProvider.classNameFilter(/^(?:(?!wo-animate).)*$/);

        var $token = $('meta[name=token]');
        if ($token.length > 0) {
          //      $httpProvider.defaults.headers.common['Authorization'] = 'Bearer ' + $token.prop('content');
          //      @todo конфликт с http auth сервера
        }

        $mdThemingProvider.theme('default')
          .accentPalette('red');
      }
    ])

    .run([
      '$cookies',
      function ($cookies) {
        if (typeof $cookies.get('timezone') === 'undefined') {
          $cookies.put('timezone', new Date().getTimezoneOffset() / 60);
        }
      }
    ])

    .filter('nl2br', function () {
      return function (input) {
        if (typeof input === 'string') {
          return input.replace(/\n/g, '
');
        }
      };
    });

})(angular, jQuery);<commit_msg>Update<commit_after>(function (ng, $) {
  "use strict";

  ng.module('BackendApp', [
    'ngCookies', 'ngSanitize', 'ngResource', 'ngAnimate', 'ngMaterial',
    'ui.bootstrap',
    'directives', 'truncate',
    'monospaced.elastic',
    'angular-loading-bar', 'angular-redactor'
  ])

    .config([
      '$httpProvider', '$animateProvider', '$mdThemingProvider',
      function ($httpProvider, $animateProvider, $mdThemingProvider) {
        $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
        $httpProvider.defaults.headers.common['X-CSRF-Token'] = yii.getCsrfToken();

        $animateProvider.classNameFilter(/^(?:(?!wo-animate).)*$/);

        var $token = $('meta[name=token]');
        if ($token.length > 0) {
          //      $httpProvider.defaults.headers.common['Authorization'] = 'Bearer ' + $token.prop('content');
          //      @todo конфликт с http auth сервера
        }

        $mdThemingProvider.theme('default')
          .accentPalette('red');
      }
    ])

    .run([
      '$cookies',
      function ($cookies) {
        if (typeof $cookies.get('timezone') === 'undefined') {
          $cookies.put('timezone', new Date().getTimezoneOffset() / 60);
        }
      }
    ])

    .filter('nl2br', function () {
      return function (input) {
        if (typeof input === 'string') {
          return input.replace(/\n/g, '
');
        }
      };
    });

})(angular, jQuery);<|endoftext|>


<commit_before>import _ from 'lodash';

class Page {
    loadScript(url) {
        return new Promise(resolve => {
            // Is it already inserted, possibly with server-side rendering?
            if (document.querySelectorAll(`script[src="${url}"]`).length) {
                return;
            }
            const s = document.createElement('script');
            s.type = 'text/javascript';
            s.src = url;
            s.async = true;
            s.onload = resolve;
            document.body.appendChild(s);
        });
    }

    loadStylesheet(url) {
        return new Promise(resolve => {
            // Is it already inserted, possibly with server-side rendering?
            // Is it already inserted, possibly with server-side rendering?
            for (let i = 0, max = document.styleSheets.length; i < max; i++) {
                if (document.styleSheets[i].href === url) {
                    return;
                }
            }

            const s = document.createElement('link');
            s.rel = 'stylesheet';
            s.href = url;
            s.onload = resolve;
            document.head.appendChild(s);
        });
    }

    setMeta(attributes) {
        let updatedExisting = false;
        _.each(['name', 'property'], name => {
            if (_.has(attributes, name)) {
                // Fetch existing element
                const element = document.querySelector(`meta[${name}="${attributes[name]}"]`);
                if (element) {
                    // If exists, update with new attributes
                    _.each(attributes, (value, key) => element.setAttribute(key, value));
                    updatedExisting = true;
                    return false;
                }
            }
        });

        if (updatedExisting) {
            return;
        }

        // Create new element
        const element = document.createElement('meta');
        _.each(attributes, (value, key) => element.setAttribute(key, value));
        document.head.appendChild(element);
    }

    setTitle(title) {
        document.title = title;
    }
}

export default Page;<commit_msg>Fixed Page.js - finding CSS link tags the right way.<commit_after>import _ from 'lodash';

class Page {
    loadScript(url) {
        return new Promise(resolve => {
            // Is it already inserted, possibly with server-side rendering?
            if (document.querySelectorAll(`script[src="${url}"]`).length > 0) {
                return;
            }
            const s = document.createElement('script');
            s.type = 'text/javascript';
            s.src = url;
            s.async = true;
            s.onload = resolve;
            document.body.appendChild(s);
        });
    }

    loadStylesheet(url) {
        return new Promise(resolve => {
            // Is it already inserted, possibly with server-side rendering?
            if (document.querySelectorAll(`link[rel="stylesheet"][href="${url}"]`).length > 0) {
                return;
            }

            const s = document.createElement('link');
            s.rel = 'stylesheet';
            s.href = url;
            s.onload = resolve;
            document.head.appendChild(s);
        });
    }

    setMeta(attributes) {
        let updatedExisting = false;
        _.each(['name', 'property'], name => {
            if (_.has(attributes, name)) {
                // Fetch existing element
                const element = document.querySelector(`meta[${name}="${attributes[name]}"]`);
                if (element) {
                    // If exists, update with new attributes
                    _.each(attributes, (value, key) => element.setAttribute(key, value));
                    updatedExisting = true;
                    return false;
                }
            }
        });

        if (updatedExisting) {
            return;
        }

        // Create new element
        const element = document.createElement('meta');
        _.each(attributes, (value, key) => element.setAttribute(key, value));
        document.head.appendChild(element);
    }

    setTitle(title) {
        document.title = title;
    }
}

export default Page;<|endoftext|>


<commit_before>(function () {
  "use strict";

  function ContentAppListViewController($scope) {

    var vm = this;

    vm.propertyEditorReadonly = propertyEditorReadonly;

    function propertyEditorReadonly () {
      // check for permission to update
      return !(typeof $scope.variantContent !== 'undefined' && $scope.variantContent.allowedActions.includes('A'));
    }

  }

  angular.module("umbraco").controller("Umbraco.Editors.Content.Apps.ListViewController", ContentAppListViewController);
})();
<commit_msg>Fix broken selectable state for list view items (#13148)<commit_after>(function () {
  "use strict";

  function ContentAppListViewController($scope) {

    var vm = this;

    vm.propertyEditorReadonly = propertyEditorReadonly;

    function propertyEditorReadonly () {
      // check for permission to update
      return $scope.variantContent && !$scope.variantContent.allowedActions.includes('A');
    }

  }

  angular.module("umbraco").controller("Umbraco.Editors.Content.Apps.ListViewController", ContentAppListViewController);
})();
<|endoftext|>


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

/* jshint node: true */
"use strict";

var Promise = require('bluebird');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var consolidate = require('consolidate');
var csurf = require('csurf');
var express = require('express');
var session = require('express-session');
var fsSession = require('fs-session')({ session: session });
var _ = require('underscore');
var uuid = require('node-uuid');

var DBConn = require('./dbconn');
var gravatar = require('./gravatar');
var webforms = require('./webforms');

function WebApp(config, callback) {
	var self = this;

	if (!("web" in config)) {
		callback(new Error("Missing auth configuration"));
		return;
	}

	if (!("port" in config.web)) {
		callback(new Error("Missing port in web configuration."));
		return;
	}

	if (!("secret" in config.web)) {
		callback(new Error("Missing port in secret configuration."));
		return;
	}

	// Set ReCAPTCHA settings if present
	if ("recaptcha" in config) {
		if (!("privateKey" in config.recaptcha)) {
			callback(new Error("Missing privateKey in WebApp ReCAPTCHA configuration."));
			return;
		}

		if (!("publicKey" in config.recaptcha)) {
			callback(new Error("Missing publicKey in WebApp ReCAPTCHA configuration."));
			return;
		}

		this.recaptcha = {
			publicKey: config.recaptcha.publicKey,
			privateKey: config.recaptcha.privateKey
		};
	}

	// Create database connection
	new DBConn(config).then(function(dbconn) {
		self.dbconn = dbconn;

		self.app = express();

		// Middleware
		self.app.use(express.static(__dirname + '/public'));
		self.app.use(bodyParser.urlencoded({
			extended: true
		}));
		self.app.use(cookieParser());
		self.app.use(session({
			secret: config.web.secret,
			store: new fsSession()
		}));
		self.app.use(csurf());

		// Template engine
		self.app.engine('hjs', consolidate.hogan);

		// Configuration
		self.app.set('view engine', 'hjs');

		// Top-level routes
		self.app.get('/', self.home.bind(self));
		self.app.all('/login', self.login.bind(self));
		self.app.get('/logout', self.logout.bind(self));
		self.app.all('/register', self.register.bind(self));
		self.app.get('/register/:token', self.registerVerify.bind(self));
		self.app.all('/reset', self.reset.bind(self));
		self.app.get('/reset/:token', self.resetVerify.bind(self));

		// Users
		self.app.get('/users', self.getUsers.bind(self));
		self.app.all('/users/new', self.newUser.bind(self));
		self.app.get('/users/:id', self.getUser.bind(self));
		self.app.all('/users/:id/edit', self.editUser.bind(self));
		self.app.all('/users/:id/destroy', self.destroyUser.bind(self));

		// Start listening for connections
		self.app.listen(config.web.port, function() {
			callback(null, self);
		});
	});
}

WebApp.prototype.render = function(req, res, layout, options) {
	res.render('layout', _.extend(options || {}, {
		session: req.session,
		partials: {
			body: layout,
			header: 'header'
		}
	}));
};

// Top level controllers
WebApp.prototype.home = function(req, res) {
	this.render(req, res, 'home');
};
WebApp.prototype.login = function(req, res) {
	var self = this;

	function render(data, errors) {
		data = data || {};
		errors = errors || {};

		data._csrf = req.csrfToken();
		self.render(req, res, 'login', {
			data: data, errors: errors,
		});
		return;
	}

	var data = req.body;
	if (!_.isEmpty(data)) {
		webforms.loginForm(data, this.dbconn.User, function(errors, user) {
			if (errors) {
				render(data, errors);
			} else {
				req.session.user = user;
				res.redirect('/');
			}
		});
	} else {
		render();
	}
};
WebApp.prototype.logout = function(req, res) {
	delete req.session.user;

	res.render('layout', {
		partials: { body: 'logout' }
	});
};
WebApp.prototype.register = function(req, res) {
	var self = this;

	function render(data, errors) {
		data = data || {};
		errors = errors || {};

		data._csrf = req.csrfToken();
		self.render(req, res, 'register', {
			data: data, errors: errors,
			recaptcha_public_key: self.recaptcha ? self.recaptcha.publicKey : null
		});
		return;
	}

	var data = req.body;
	if (!_.isEmpty(data)) {
		webforms.registerForm(
			data, req.ip,
			this.recaptcha ? this.recaptcha.privateKey : null,
			this.dbconn.User
		).then(function(errors) {
			if (errors) {
				render(data, errors);
			} else {
				return Promise.all([
					self.dbconn.addUser(data.username, data.password, data.email),
					self.dbconn.Verify.create({
						token: uuid.v4()
					})
				]).spread(function(user, verify) {
					return user.setVerify(verify);
				}).then(function(verify){
					return verify.getUser();
				});
			}
		}).then(function(user) {
			self.render(req, res, 'registerNotify', {
				email: user.email
			});
		});
	} else {
		render();
	}
};
WebApp.prototype.registerVerify = function(req, res) {
	var self = this;

	this.dbconn.Verify.find({
		where: {
			token: req.params.token
		}
	}).success(function(data) {
		if (data) {
			self.render(req, res, 'registerVerify');
		} else {
			res.send(404);
		}
	});
};
WebApp.prototype.reset = function(req, res) {

};
WebApp.prototype.resetVerify = function(req, res) {

};

// Users controllers

WebApp.prototype.getUsers = function(req, res) {
	this.dbconn.User.findAll()
	.success(function(users) {
		res.render('layout', { users: users, partials: { body: 'getUsers' }});
	});
};
WebApp.prototype.newUser = function(req, res) {
	res.render('layout', {
		partials: { body: 'newUser' }
	});
};
WebApp.prototype.getUser = function(req, res) {
	this.dbconn.User.find({
		include: [ this.dbconn.Profile ],
		where: { username: req.params.id }
	}).success(function(user) {
		res.render('layout', {
			user: user,
			gravatar: gravatar.image(user.email),
			partials: { body: 'getUser' }
		});
	});
};
WebApp.prototype.editUser = function(req, res) {
	res.render('layout', {
		partials: { body: 'editUser' }
	});
};
WebApp.prototype.destroyUser = function(req, res) {
	res.render('layout', {
		partials: { body: 'destroyUser' }
	});
};

module.exports = WebApp;
<commit_msg>Registration form fix.<commit_after>/*
 *  Charon: A game authentication server
 *  Copyright (C) 2014  Alex Mayfield
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/* jshint node: true */
"use strict";

var Promise = require('bluebird');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var consolidate = require('consolidate');
var csurf = require('csurf');
var express = require('express');
var session = require('express-session');
var fsSession = require('fs-session')({ session: session });
var _ = require('underscore');
var uuid = require('node-uuid');

var DBConn = require('./dbconn');
var gravatar = require('./gravatar');
var webforms = require('./webforms');

function WebApp(config, callback) {
	var self = this;

	if (!("web" in config)) {
		callback(new Error("Missing auth configuration"));
		return;
	}

	if (!("port" in config.web)) {
		callback(new Error("Missing port in web configuration."));
		return;
	}

	if (!("secret" in config.web)) {
		callback(new Error("Missing port in secret configuration."));
		return;
	}

	// Set ReCAPTCHA settings if present
	if ("recaptcha" in config) {
		if (!("privateKey" in config.recaptcha)) {
			callback(new Error("Missing privateKey in WebApp ReCAPTCHA configuration."));
			return;
		}

		if (!("publicKey" in config.recaptcha)) {
			callback(new Error("Missing publicKey in WebApp ReCAPTCHA configuration."));
			return;
		}

		this.recaptcha = {
			publicKey: config.recaptcha.publicKey,
			privateKey: config.recaptcha.privateKey
		};
	}

	// Create database connection
	new DBConn(config).then(function(dbconn) {
		self.dbconn = dbconn;

		self.app = express();

		// Middleware
		self.app.use(express.static(__dirname + '/public'));
		self.app.use(bodyParser.urlencoded({
			extended: true
		}));
		self.app.use(cookieParser());
		self.app.use(session({
			secret: config.web.secret,
			store: new fsSession()
		}));
		self.app.use(csurf());

		// Template engine
		self.app.engine('hjs', consolidate.hogan);

		// Configuration
		self.app.set('view engine', 'hjs');

		// Top-level routes
		self.app.get('/', self.home.bind(self));
		self.app.all('/login', self.login.bind(self));
		self.app.get('/logout', self.logout.bind(self));
		self.app.all('/register', self.register.bind(self));
		self.app.get('/register/:token', self.registerVerify.bind(self));
		self.app.all('/reset', self.reset.bind(self));
		self.app.get('/reset/:token', self.resetVerify.bind(self));

		// Users
		self.app.get('/users', self.getUsers.bind(self));
		self.app.all('/users/new', self.newUser.bind(self));
		self.app.get('/users/:id', self.getUser.bind(self));
		self.app.all('/users/:id/edit', self.editUser.bind(self));
		self.app.all('/users/:id/destroy', self.destroyUser.bind(self));

		// Start listening for connections
		self.app.listen(config.web.port, function() {
			callback(null, self);
		});
	});
}

WebApp.prototype.render = function(req, res, layout, options) {
	res.render('layout', _.extend(options || {}, {
		session: req.session,
		partials: {
			body: layout,
			header: 'header'
		}
	}));
};

// Top level controllers
WebApp.prototype.home = function(req, res) {
	this.render(req, res, 'home');
};
WebApp.prototype.login = function(req, res) {
	var self = this;

	function render(data, errors) {
		data = data || {};
		errors = errors || {};

		data._csrf = req.csrfToken();
		self.render(req, res, 'login', {
			data: data, errors: errors,
		});
		return;
	}

	var data = req.body;
	if (!_.isEmpty(data)) {
		webforms.loginForm(data, this.dbconn.User, function(errors, user) {
			if (errors) {
				render(data, errors);
			} else {
				req.session.user = user;
				res.redirect('/');
			}
		});
	} else {
		render();
	}
};
WebApp.prototype.logout = function(req, res) {
	delete req.session.user;

	res.render('layout', {
		partials: { body: 'logout' }
	});
};
WebApp.prototype.register = function(req, res) {
	var self = this;

	function render(data, errors) {
		data = data || {};
		errors = errors || {};

		data._csrf = req.csrfToken();
		self.render(req, res, 'register', {
			data: data, errors: errors,
			recaptcha_public_key: self.recaptcha ? self.recaptcha.publicKey : null
		});
		return;
	}

	var data = req.body;
	if (!_.isEmpty(data)) {
		webforms.registerForm(
			data, req.ip,
			this.recaptcha ? this.recaptcha.privateKey : null,
			this.dbconn.User
		).then(function(errors) {
			if (errors) {
				render(data, errors);
			} else {
				return Promise.all([
					self.dbconn.addUser(data.username, data.password, data.email),
					self.dbconn.Verify.create({
						token: uuid.v4()
					})
				]).spread(function(user, verify) {
					return user.setVerify(verify);
				}).then(function(verify){
					return verify.getUser();
				}).then(function(user) {
					self.render(req, res, 'registerNotify', {
						email: user.email
					});
				});
			}
		});
	} else {
		render();
	}
};
WebApp.prototype.registerVerify = function(req, res) {
	var self = this;

	this.dbconn.Verify.find({
		where: {
			token: req.params.token
		}
	}).success(function(data) {
		if (data) {
			self.render(req, res, 'registerVerify');
		} else {
			res.send(404);
		}
	});
};
WebApp.prototype.reset = function(req, res) {

};
WebApp.prototype.resetVerify = function(req, res) {

};

// Users controllers

WebApp.prototype.getUsers = function(req, res) {
	this.dbconn.User.findAll()
	.success(function(users) {
		res.render('layout', { users: users, partials: { body: 'getUsers' }});
	});
};
WebApp.prototype.newUser = function(req, res) {
	res.render('layout', {
		partials: { body: 'newUser' }
	});
};
WebApp.prototype.getUser = function(req, res) {
	this.dbconn.User.find({
		include: [ this.dbconn.Profile ],
		where: { username: req.params.id }
	}).success(function(user) {
		res.render('layout', {
			user: user,
			gravatar: gravatar.image(user.email),
			partials: { body: 'getUser' }
		});
	});
};
WebApp.prototype.editUser = function(req, res) {
	res.render('layout', {
		partials: { body: 'editUser' }
	});
};
WebApp.prototype.destroyUser = function(req, res) {
	res.render('layout', {
		partials: { body: 'destroyUser' }
	});
};

module.exports = WebApp;
<|endoftext|>


<commit_before>'use strict';
var request = require('request');
var fs = require('fs');
var Job = require('../../lib/models/job');
var _ = require('underscore');
var location = __dirname;

module.exports = {
  config: {},
  routes: function (app, context) {
    app.get('/report', function (req, res) {
      var org = req.params.org;
      var repo = req.params.repo;
      var branch = req.query.branch;
      var protocol = req.protocol;
      var hostName = req.get('Host');
      var project = org + '/' + repo;
      var jobsEndpoint = protocol + '://' + hostName + '/' + org + '/' + repo + '/jobs';
      var options = {
        limit: 1,
        sort: [['finished', 'desc']]
      };
      Job.find({ project: project, archived: null}, options, function(err, docs){
        var id = docs[0]._id;
        var home = process.env.HOME;
        var coverageLocation = home + '/.strider/data/'+ org + '-' + repo + '-' + branch + '/job-' + id +'/coverage';
        fs.readdir(coverageLocation, function (err, file) {
          var promises = [];
          var valid = _.map(file, function (item) {
            var index = item.indexOf('.');
            if (index !== -1) {
              var extension = item.substr(index, item.length);
              if (extension === 'js' || extension === 'html' || extension === 'css') {
                return item;
              } else {
                return;
              }
            } else {
              return;
            }
          });
          res.send(valid);
        });
        //   _.each(valid, function (item) {
        //     var temp = (function (src) {
        //       return new Promise(function (resolve, reject) {
        //         fs.readFile(src, function (err, data) {
        //           var returnData = '';
        //           switch(extension){
        //             case 'js':
        //               returnData = '<script>' + data + '</script>';
        //               break;
        //             case 'css':
        //               returnData = '<style>' + data + '</style>';
        //               break;
        //             default:
        //               returnData = data;
        //           }
        //           resolve(returnData);
        //         });
        //       });
        //     })(item);
        //     promises.push(temp);
        //   });
        //   Promise.all(promises).then(function(finalStrings){
        //     var fileStrings = '';
        //     _.each(finalStrings, function (item) {
        //       fileStrings += item;
        //     });
        //     res.send(fileStrings);
        //   });
        // });
      });
      // request({url: jobsEndpoint}, function (er, response, body) {
      //   var myCookie = request.cookie(response.headers['set-cookie'][0]);
      //   var cookieJar = request.jar();
      //   cookieJar.setCookie(myCookie, jobsEndpoint);
      //   request({url: jobsEndpoint, jar: cookieJar}, function(err, response, body){
      //     res.send(body);
      //   });
      // });

      // res.json({user: req.session});

      // res.json({yes: app});
      // var jobsEndpoint = protocol + '://' + hostName + '/' + org + '/' + repo + '/jobs';
      // console.log('BODY', body);
      // var latestJobId = JSON.parse(body)[0];
    });
  },
  globalRoutes: function (app, context) {
    app.get('/report', function (req, res) {
      res.json({context: context});
    });
  }
};
<commit_msg>reports endpoint<commit_after>'use strict';
var request = require('request');
var fs = require('fs');
var Job = require('../../lib/models/job');
var _ = require('underscore');
var location = __dirname;

module.exports = {
  config: {},
  routes: function (app, context) {
    app.get('/report', function (req, res) {
      var org = req.params.org;
      var repo = req.params.repo;
      var branch = req.query.branch;
      var protocol = req.protocol;
      var hostName = req.get('Host');
      var project = org + '/' + repo;
      var jobsEndpoint = protocol + '://' + hostName + '/' + org + '/' + repo + '/jobs';
      var options = {
        limit: 1,
        sort: [['finished', 'desc']]
      };
      Job.find({ project: project, archived: null}, options, function(err, docs){
        var id = docs[0]._id;
        var home = process.env.HOME;
        var coverageLocation = home + '/.strider/data/'+ org + '-' + repo + '-' + branch + '/job-' + id +'/coverage';
        fs.readdir(coverageLocation, function (err, file) {
          var promises = [];
          var valid = [];
          _.each(file, function (item) {
            var index = item.indexOf('.');
            if (index !== -1) {
              var extension = item.substr(index, item.length);
              if (extension === 'js' || extension === 'html' || extension === 'css') {
                valid.push(item);
              }
            }
          });
          res.send(valid);
        });
        //   _.each(valid, function (item) {
        //     var temp = (function (src) {
        //       return new Promise(function (resolve, reject) {
        //         fs.readFile(src, function (err, data) {
        //           var returnData = '';
        //           switch(extension){
        //             case 'js':
        //               returnData = '<script>' + data + '</script>';
        //               break;
        //             case 'css':
        //               returnData = '<style>' + data + '</style>';
        //               break;
        //             default:
        //               returnData = data;
        //           }
        //           resolve(returnData);
        //         });
        //       });
        //     })(item);
        //     promises.push(temp);
        //   });
        //   Promise.all(promises).then(function(finalStrings){
        //     var fileStrings = '';
        //     _.each(finalStrings, function (item) {
        //       fileStrings += item;
        //     });
        //     res.send(fileStrings);
        //   });
        // });
      });
      // request({url: jobsEndpoint}, function (er, response, body) {
      //   var myCookie = request.cookie(response.headers['set-cookie'][0]);
      //   var cookieJar = request.jar();
      //   cookieJar.setCookie(myCookie, jobsEndpoint);
      //   request({url: jobsEndpoint, jar: cookieJar}, function(err, response, body){
      //     res.send(body);
      //   });
      // });

      // res.json({user: req.session});

      // res.json({yes: app});
      // var jobsEndpoint = protocol + '://' + hostName + '/' + org + '/' + repo + '/jobs';
      // console.log('BODY', body);
      // var latestJobId = JSON.parse(body)[0];
    });
  },
  globalRoutes: function (app, context) {
    app.get('/report', function (req, res) {
      res.json({context: context});
    });
  }
};
<|endoftext|>


<commit_before>// vim: et:ts=2:sw=2:sts=2:ft=javascript
/**
 * Copyright 2013 j <j@mailb.org>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var eejs = require('ep_etherpad-lite/node/eejs/');
var settings = require('ep_etherpad-lite/node/utils/Settings');
var sessioninfos = require('ep_etherpad-lite/node/handler/PadMessageHandler').sessioninfos;
var socketio;

/**
 * Handles an RTC Message
 * @param client the client that send this message
 * @param message the message from the client
 */
function handleRTCMessage(client, payload)
{
  var userId = sessioninfos[client.id].author;
  var to = payload.to;
  var padId = sessioninfos[client.id].padId;
  var clients = socketio.sockets.clients(padId);
  var otherClient;
  var msg = {
    type: "COLLABROOM",
    data: {
      type: "RTC_MESSAGE",
      payload: {
        from: userId,
        data: payload.data
      }
    }
  };
  // Lookup recipient and send message
  for(var i = 0; i < clients.length; i++) {
    if (sessioninfos[clients[i].id].author == to) {
      clients[i].json.send(msg);
      break;
    }
  }
}

exports.clientVars = function(hook, context, callback)
{
  var enabled = true;
  if(settings.ep_webrtc && settings.ep_webrtc.enabled === false){
    enabled = settings.ep_webrtc.enabled;
  }

  var iceServers = [ {"url": "stun:stun.l.google.com:19302"} ];
  if(settings.ep_webrtc && settings.ep_webrtc.iceServers){
    iceServers = settings.ep_webrtc.iceServers;
  }

  var listenClass = false;
  if(settings.ep_webrtc && settings.ep_webrtc.listenClass){
    listenClass = settings.ep_webrtc.listenClass;
  }

  return callback({
    webrtc: {
      "iceServers": iceServers,
      "enabled": enabled,
      "listenClass": listenClass
    }
  });
};

exports.handleMessage = function ( hook, context, callback )
{
  if (context.message.type == 'COLLABROOM' && context.message.data.type == 'RTC_MESSAGE') {
    handleRTCMessage(context.client, context.message.data.payload);
    callback([null]);
  } else {
    callback();
  }
};

exports.setSocketIO = function (hook, context, callback)
{
  socketio = context.io;
  callback();
};

exports.settings = function (hook, context, callback)
{
    var checked = (settings.ep_webrtc && settings.ep_webrtc.enabled === false)
      ? 'unchecked'
      : 'checked';
    context.content += eejs.require('ep_webrtc/templates/webrtc_entry.ejs', {
      checked : checked
    });
    callback();
};
<commit_msg>Update to new socketio api, fixes #14<commit_after>// vim: et:ts=2:sw=2:sts=2:ft=javascript
/**
 * Copyright 2013 j <j@mailb.org>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var eejs = require('ep_etherpad-lite/node/eejs/');
var settings = require('ep_etherpad-lite/node/utils/Settings');
var sessioninfos = require('ep_etherpad-lite/node/handler/PadMessageHandler').sessioninfos;
var socketio;

/**
 * Handles an RTC Message
 * @param client the client that send this message
 * @param message the message from the client
 */
function handleRTCMessage(client, payload)
{
  var userId = sessioninfos[client.id].author;
  var to = payload.to;
  var padId = sessioninfos[client.id].padId;
  var room = socketio.sockets.adapter.rooms[padId];
  var clients = [];

  if (room) {
    for (var id in room) {
      clients.push(socketio.sockets.adapter.nsp.connected[id]);
    }
  }

  var msg = {
    type: "COLLABROOM",
    data: {
      type: "RTC_MESSAGE",
      payload: {
        from: userId,
        data: payload.data
      }
    }
  };
  // Lookup recipient and send message
  for(var i = 0; i < clients.length; i++) {
    var session = sessioninfos[clients[i].id];
    if(session && session.author == to) {
      clients[i].json.send(msg);
      break;
    }
  }
}

exports.clientVars = function(hook, context, callback)
{
  var enabled = true;
  if(settings.ep_webrtc && settings.ep_webrtc.enabled === false){
    enabled = settings.ep_webrtc.enabled;
  }

  var iceServers = [ {"url": "stun:stun.l.google.com:19302"} ];
  if(settings.ep_webrtc && settings.ep_webrtc.iceServers){
    iceServers = settings.ep_webrtc.iceServers;
  }

  var listenClass = false;
  if(settings.ep_webrtc && settings.ep_webrtc.listenClass){
    listenClass = settings.ep_webrtc.listenClass;
  }

  return callback({
    webrtc: {
      "iceServers": iceServers,
      "enabled": enabled,
      "listenClass": listenClass
    }
  });
};

exports.handleMessage = function ( hook, context, callback )
{
  if (context.message.type == 'COLLABROOM' && context.message.data.type == 'RTC_MESSAGE') {
    handleRTCMessage(context.client, context.message.data.payload);
    callback([null]);
  } else {
    callback();
  }
};

exports.setSocketIO = function (hook, context, callback)
{
  socketio = context.io;
  callback();
};

exports.settings = function (hook, context, callback)
{
    var checked = (settings.ep_webrtc && settings.ep_webrtc.enabled === false)
      ? 'unchecked'
      : 'checked';
    context.content += eejs.require('ep_webrtc/templates/webrtc_entry.ejs', {
      checked : checked
    });
    callback();
};
<|endoftext|>


<commit_before>"use strict";

var phoneNumber = require("libphonenumber");

function What() {

}

/**
 * [function description]
 * @param  {[any]} what [input any type]
 * @return {[String]}      [returns the string of type]
 */
What.prototype.type = function(what) {
  var type = Object.prototype.toString.call(what).slice(8, -1);
  var email = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  var url = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/;
  if (type === "String") {
    if (email.test(what)) {
      return 'Email';
    }
    if (url.test(what)) {
      return 'Url';
    }
    try {
      if (phoneNumber.validate(what) === true) {
        return 'Phone';
      }
    } catch (e) {
      return 'String';
    }
  }
  if (type === "Number") {
    if (this.isNaN(what)) {
      return 'NaN';
    } else if (what % 1 !== 0 &&
              what !== Infinity &&
              what !== -Infinity) {
      return 'Float';
    } else if (what % 1 === 0) {
      return 'Int';
    } else {
      return 'Number';
    }
  }
  return type;
};

/**
 * [function description]
 * @param  {[any]} what [description]
 * @return {[type]}      [description]
 */
What.prototype.isNaN = function(what) {
  if (what !== what) {
    return true;
  }
  return false;
};

/**
 * [function description]
 * @param  {[any]} what [description]
 * @return {[type]}      [description]
 */
What.prototype.isFalsey = function(what) {
  if (this.trim(what)) {
    if (this.type(what) === "Object" &&
        JSON.stringify(what) === "{}") {
        return true;
    }
    if (this.type(what) === "Array" &&
        this.trim(what).length === 0) {
          return true;
    }
    return false;
  }
  return true;
};

/**
 * [function description]
 * @param  {[type]} what [description]
 * @return {[type]}      [description]
 */
What.prototype.isEmpty = function(what) {
  if (this.trim(what) ||
      this.trim(what) === false ||
      this.trim(what) === 0) {
    if (this.type(what) === "Object" &&
        JSON.stringify(what) === "{}") {
        return true;
    }
    if (this.type(what) === "Array" &&
        what.length === 0) {
      return true;
    }
    return false;
  }
  return true;
};

/**
 * [function description]
 * @param  {[type]} what [description]
 * @return {[type]}      [description]
 */
What.prototype.trim = function(what) {
  if (this.type(what) === "String") {
    return what.trim();
  }
  if (this.type(what) === "Array") {
    return what.filter(Boolean);
  }
  return what;
};

module.exports = new What();
<commit_msg>added prefix and sufix search for an array<commit_after>"use strict";

var phoneNumber = require("libphonenumber");

function What() {

}

/**
 * [function description]
 * @param  {[any]} what [input any type]
 * @return {[String]}      [returns the string of type]
 */
What.prototype.type = function(what) {
  var type = Object.prototype.toString.call(what).slice(8, -1);
  var email = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  var url = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/;
  if (type === "String") {
    if (email.test(what)) {
      return 'Email';
    }
    if (url.test(what)) {
      return 'Url';
    }
    try {
      if (phoneNumber.validate(what) === true) {
        return 'Phone';
      }
    } catch (e) {
      return 'String';
    }
  }
  if (type === "Number") {
    if (this.isNaN(what)) {
      return 'NaN';
    } else if (what % 1 !== 0 &&
              what !== Infinity &&
              what !== -Infinity) {
      return 'Float';
    } else if (what % 1 === 0) {
      return 'Int';
    } else {
      return 'Number';
    }
  }
  return type;
};

/**
 * [function description]
 * @param  {[any]} what [description]
 * @return {[type]}      [description]
 */
What.prototype.isNaN = function(what) {
  if (what !== what) {
    return true;
  }
  return false;
};

/**
 * [function description]
 * @param  {[any]} what [description]
 * @return {[type]}      [description]
 */
What.prototype.isFalsey = function(what) {
  if (this.trim(what)) {
    if (this.type(what) === "Object" &&
        JSON.stringify(what) === "{}") {
        return true;
    }
    if (this.type(what) === "Array" &&
        this.trim(what).length === 0) {
          return true;
    }
    return false;
  }
  return true;
};

/**
 * [function description]
 * @param  {[type]} what [description]
 * @return {[type]}      [description]
 */
What.prototype.isEmpty = function(what) {
  if (this.trim(what) ||
      this.trim(what) === false ||
      this.trim(what) === 0) {
    if (this.type(what) === "Object" &&
        JSON.stringify(what) === "{}") {
        return true;
    }
    if (this.type(what) === "Array" &&
        what.length === 0) {
      return true;
    }
    return false;
  }
  return true;
};

/**
 * [function description]
 * @param  {[type]} what [description]
 * @return {[type]}      [description]
 */
What.prototype.trim = function(what) {
  if (this.type(what) === "String") {
    return what.trim();
  }
  if (this.type(what) === "Array") {
    return what.filter(Boolean);
  }
  return what;
};

/**
 * [function description]
 * @param  {[type]} what  [description]
 * @param  {[type]} query [description]
 * @return {[type]}       [description]
 */
What.prototype.prefixInArray = function(what, query) {
  var type = this.type(what),
      matches;
  if (this.type(query) === "String" && type === "Array") {
    matches = what.filter(function(whatValue) {
      if (whatValue) {
        return (whatValue.substring(0, query.length) === query);
      }
    });
  }

  return what;
};

/**
 * [function description]
 * @param  {[type]} what  [description]
 * @param  {[type]} query [description]
 * @return {[type]}       [description]
 */
What.prototype.sufixInArray = function(what, query) {
  var type = this.type(what),
      matches;
  if (this.type(query) === "String" && type === "Array") {
    matches = what.filter(function(whatValue) {
      if (whatValue) {
        let valueLength = whatValue.length;
        return (whatValue.substring(valueLength - query.length, valueLength) === query);
      }
    });
  }

  return what;
};

module.exports = new What();
<|endoftext|>


<commit_before>import React from 'react';
import { mount } from 'enzyme';
import Upload from '..';
import Form from '../../form';
import { errorRequest, successRequest } from './requests';

const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));

const fileList = [{
  uid: -1,
  name: 'xxx.png',
  status: 'done',
  url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
  thumbUrl: 'https://zos.alipayobjects.com/rmsportal/IQKRngzUuFzJzGzRJXUs.png',
}, {
  uid: -2,
  name: 'yyy.png',
  status: 'done',
  url: 'https://zos.alipayobjects.com/rmsportal/IQKRngzUuFzJzGzRJXUs.png',
  thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
}];

describe('Upload List', () => {
  // https://github.com/ant-design/ant-design/issues/4653
  it('should use file.thumbUrl for <img /> in priority', () => {
    const wrapper = mount(
      <Upload defaultFileList={fileList} listType="picture">
        <button>upload</button>
      </Upload>
    );
    fileList.forEach((file, i) => {
      const linkNode = wrapper.find('.ant-upload-list-item-thumbnail').at(i);
      const imgNode = wrapper.find('.ant-upload-list-item-thumbnail img').at(i);
      expect(linkNode.prop('href')).toBe(file.url);
      expect(imgNode.prop('src')).toBe(file.thumbUrl);
    });
  });

  // https://github.com/ant-design/ant-design/issues/7269
  it('should remove correct item when uid is 0', async () => {
    const list = [{
      uid: 0,
      name: 'xxx.png',
      status: 'done',
      url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
      thumbUrl: 'https://zos.alipayobjects.com/rmsportal/IQKRngzUuFzJzGzRJXUs.png',
    }, {
      uid: 1,
      name: 'xxx.png',
      status: 'done',
      url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
      thumbUrl: 'https://zos.alipayobjects.com/rmsportal/IQKRngzUuFzJzGzRJXUs.png',
    }];
    const wrapper = mount(
      <Upload defaultFileList={list}>
        <button>upload</button>
      </Upload>
    );
    expect(wrapper.find('.ant-upload-list-item').length).toBe(2);
    wrapper.find('.ant-upload-list-item').at(0).find('.anticon-cross').simulate('click');
    await delay(400);
    wrapper.update();
    expect(wrapper.find('.ant-upload-list-item').hostNodes().length).toBe(1);
  });

  it('should be uploading when upload a file', (done) => {
    let wrapper;
    const onChange = ({ file }) => {
      if (file.status === 'uploading') {
        expect(wrapper.render()).toMatchSnapshot();
      }
      if (file.status === 'done') {
        expect(wrapper.render()).toMatchSnapshot();
        done();
      }
    };
    wrapper = mount(
      <Upload
        action="http://jsonplaceholder.typicode.com/posts/"
        onChange={onChange}
        customRequest={successRequest}
      >
        <button>upload</button>
      </Upload>
    );
    wrapper.find('input').simulate('change', {
      target: {
        files: [
          { filename: 'foo.png' },
        ],
      },
    });
  });

  it('handle error', (done) => {
    let wrapper;
    const onChange = ({ file }) => {
      if (file.status !== 'uploading') {
        expect(wrapper.render()).toMatchSnapshot();
        done();
      }
    };
    wrapper = mount(
      <Upload
        action="http://jsonplaceholder.typicode.com/posts/"
        onChange={onChange}
        customRequest={errorRequest}
      >
        <button>upload</button>
      </Upload>
    );
    wrapper.find('input').simulate('change', {
      target: {
        files: [
          { filename: 'foo.png' },
        ],
      },
    });
  });

  it('does concat filelist when beforeUpload returns false', () => {
    const handleChange = jest.fn();
    const wrapper = mount(
      <Upload
        listType="picture"
        defaultFileList={fileList}
        onChange={handleChange}
        beforeUpload={() => false}
      >
        <button>upload</button>
      </Upload>
    );

    wrapper.find('input').simulate('change', {
      target: {
        files: [
          { filename: 'foo.png' },
        ],
      },
    });

    expect(wrapper.state().fileList.length).toBe(fileList.length + 1);
    expect(handleChange.mock.calls[0][0].fileList).toHaveLength(3);
  });

  // https://github.com/ant-design/ant-design/issues/7762
  it('work with form validation', () => {
    let errors;
    class TestForm extends React.Component {
      handleSubmit = () => {
        const { validateFields } = this.props.form;
        validateFields((err) => {
          errors = err;
        });
      }

      render() {
        const { getFieldDecorator } = this.props.form;

        return (
          <Form onSubmit={this.handleSubmit}>
            <Form.Item>
              {getFieldDecorator('file', {
                valuePropname: 'fileList',
                getValueFromEvent: e => e.fileList,
                rules: [
                  {
                    required: true,
                    validator: (rule, value, callback) => {
                      if (!value || value.length === 0) {
                        callback('file required');
                      } else {
                        callback();
                      }
                    },
                  },
                ],
              })(
                <Upload
                  beforeUpload={() => false}
                >
                  <button>upload</button>
                </Upload>
              )}
            </Form.Item>
          </Form>
        );
      }
    }

    const App = Form.create()(TestForm);
    const wrapper = mount(<App />);
    wrapper.find(Form).simulate('submit');
    expect(errors.file.errors).toEqual([{ message: 'file required', field: 'file' }]);

    wrapper.find('input').simulate('change', {
      target: {
        files: [
          { filename: 'foo.png' },
        ],
      },
    });
    wrapper.find(Form).simulate('submit');
    expect(errors).toBeNull();
  });

  it('should support onPreview', () => {
    const handlePreview = jest.fn();
    const wrapper = mount(
      <Upload
        listType="picture-card"
        defaultFileList={fileList}
        onPreview={handlePreview}
      >
        <button>upload</button>
      </Upload>
    );
    wrapper.find('.anticon-eye-o').at(0).simulate('click');
    expect(handlePreview).toBeCalledWith(fileList[0]);
    wrapper.find('.anticon-eye-o').at(1).simulate('click');
    expect(handlePreview).toBeCalledWith(fileList[1]);
  });

  it('should support onRemove', async () => {
    const handleRemove = jest.fn();
    const handleChange = jest.fn();
    const wrapper = mount(
      <Upload
        listType="picture-card"
        defaultFileList={fileList}
        onRemove={handleRemove}
        onChange={handleChange}
      >
        <button>upload</button>
      </Upload>
    );
    wrapper.find('.anticon-delete').at(0).simulate('click');
    expect(handleRemove).toBeCalledWith(fileList[0]);
    wrapper.find('.anticon-delete').at(1).simulate('click');
    expect(handleRemove).toBeCalledWith(fileList[1]);
    await delay(0);
    expect(handleChange.mock.calls.length).toBe(2);
  });

  it('should generate thumbUrl from file', async () => {
    const handlePreview = jest.fn();
    const newFileList = [...fileList];
    const newFile = { ...fileList[0], uid: -3, originFileObj: new File([], 'xxx.png') };
    delete newFile.thumbUrl;
    newFileList.push(newFile);
    const wrapper = mount(
      <Upload
        listType="picture-card"
        defaultFileList={newFileList}
        onPreview={handlePreview}
      >
        <button>upload</button>
      </Upload>
    );
    wrapper.setState({});
    await delay(20);
    expect(wrapper.state().fileList[2].thumbUrl).not.toBeFalsy();
  });

  it('should non-image format file preview', () => {
    const list = [
      {
        ...fileList[0],
        uid: -3,
        url: 'https://cdn.xxx.com/aaa.zip',
        thumbUrl: 'data:application/zip;base64,UEsDBAoAAAAAADYZYkwAAAAAAAAAAAAAAAAdAAk',
        originFileObj: new File([], 'aaa.zip'),
      },
    ];

    const wrapper = mount(
      <Upload
        listType="picture"
        defaultFileList={list}
      >
        <button>upload</button>
      </Upload>
    );
    expect(wrapper.render()).toMatchSnapshot();
  });
});
<commit_msg>fix test case<commit_after>import React from 'react';
import { mount } from 'enzyme';
import Upload from '..';
import Form from '../../form';
import { errorRequest, successRequest } from './requests';

const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));

const fileList = [{
  uid: -1,
  name: 'xxx.png',
  status: 'done',
  url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
  thumbUrl: 'https://zos.alipayobjects.com/rmsportal/IQKRngzUuFzJzGzRJXUs.png',
}, {
  uid: -2,
  name: 'yyy.png',
  status: 'done',
  url: 'https://zos.alipayobjects.com/rmsportal/IQKRngzUuFzJzGzRJXUs.png',
  thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
}];

describe('Upload List', () => {
  // https://github.com/ant-design/ant-design/issues/4653
  it('should use file.thumbUrl for <img /> in priority', () => {
    const wrapper = mount(
      <Upload defaultFileList={fileList} listType="picture">
        <button>upload</button>
      </Upload>
    );
    fileList.forEach((file, i) => {
      const linkNode = wrapper.find('.ant-upload-list-item-thumbnail').at(i);
      const imgNode = wrapper.find('.ant-upload-list-item-thumbnail img').at(i);
      expect(linkNode.prop('href')).toBe(file.url);
      expect(imgNode.prop('src')).toBe(file.thumbUrl);
    });
  });

  // https://github.com/ant-design/ant-design/issues/7269
  it('should remove correct item when uid is 0', async () => {
    const list = [{
      uid: 0,
      name: 'xxx.png',
      status: 'done',
      url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
      thumbUrl: 'https://zos.alipayobjects.com/rmsportal/IQKRngzUuFzJzGzRJXUs.png',
    }, {
      uid: 1,
      name: 'xxx.png',
      status: 'done',
      url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
      thumbUrl: 'https://zos.alipayobjects.com/rmsportal/IQKRngzUuFzJzGzRJXUs.png',
    }];
    const wrapper = mount(
      <Upload defaultFileList={list}>
        <button>upload</button>
      </Upload>
    );
    expect(wrapper.find('.ant-upload-list-item').length).toBe(2);
    wrapper.find('.ant-upload-list-item').at(0).find('.anticon-cross').simulate('click');
    await delay(400);
    wrapper.update();
    expect(wrapper.find('.ant-upload-list-item').hostNodes().length).toBe(1);
  });

  it('should be uploading when upload a file', (done) => {
    let wrapper;
    const onChange = ({ file }) => {
      if (file.status === 'uploading') {
        expect(wrapper.render()).toMatchSnapshot();
      }
      if (file.status === 'done') {
        expect(wrapper.render()).toMatchSnapshot();
        done();
      }
    };
    wrapper = mount(
      <Upload
        action="http://jsonplaceholder.typicode.com/posts/"
        onChange={onChange}
        customRequest={successRequest}
      >
        <button>upload</button>
      </Upload>
    );
    wrapper.find('input').simulate('change', {
      target: {
        files: [
          { filename: 'foo.png' },
        ],
      },
    });
  });

  it('handle error', (done) => {
    let wrapper;
    const onChange = ({ file }) => {
      if (file.status !== 'uploading') {
        expect(wrapper.render()).toMatchSnapshot();
        done();
      }
    };
    wrapper = mount(
      <Upload
        action="http://jsonplaceholder.typicode.com/posts/"
        onChange={onChange}
        customRequest={errorRequest}
      >
        <button>upload</button>
      </Upload>
    );
    wrapper.find('input').simulate('change', {
      target: {
        files: [
          { filename: 'foo.png' },
        ],
      },
    });
  });

  it('does concat filelist when beforeUpload returns false', () => {
    const handleChange = jest.fn();
    const wrapper = mount(
      <Upload
        listType="picture"
        defaultFileList={fileList}
        onChange={handleChange}
        beforeUpload={() => false}
      >
        <button>upload</button>
      </Upload>
    );

    wrapper.find('input').simulate('change', {
      target: {
        files: [
          { filename: 'foo.png' },
        ],
      },
    });

    expect(wrapper.state().fileList.length).toBe(fileList.length + 1);
    expect(handleChange.mock.calls[0][0].fileList).toHaveLength(3);
  });

  // https://github.com/ant-design/ant-design/issues/7762
  it('work with form validation', () => {
    let errors;
    class TestForm extends React.Component {
      handleSubmit = () => {
        const { validateFields } = this.props.form;
        validateFields((err) => {
          errors = err;
        });
      }

      render() {
        const { getFieldDecorator } = this.props.form;

        return (
          <Form onSubmit={this.handleSubmit}>
            <Form.Item>
              {getFieldDecorator('file', {
                valuePropname: 'fileList',
                getValueFromEvent: e => e.fileList,
                rules: [
                  {
                    required: true,
                    validator: (rule, value, callback) => {
                      if (!value || value.length === 0) {
                        callback('file required');
                      } else {
                        callback();
                      }
                    },
                  },
                ],
              })(
                <Upload
                  beforeUpload={() => false}
                >
                  <button>upload</button>
                </Upload>
              )}
            </Form.Item>
          </Form>
        );
      }
    }

    const App = Form.create()(TestForm);
    const wrapper = mount(<App />);
    wrapper.find(Form).simulate('submit');
    expect(errors.file.errors).toEqual([{ message: 'file required', field: 'file' }]);

    wrapper.find('input').simulate('change', {
      target: {
        files: [
          { filename: 'foo.png' },
        ],
      },
    });
    wrapper.find(Form).simulate('submit');
    expect(errors).toBeNull();
  });

  it('should support onPreview', () => {
    const handlePreview = jest.fn();
    const wrapper = mount(
      <Upload
        listType="picture-card"
        defaultFileList={fileList}
        onPreview={handlePreview}
      >
        <button>upload</button>
      </Upload>
    );
    wrapper.find('.anticon-eye-o').at(0).simulate('click');
    expect(handlePreview).toBeCalledWith(fileList[0]);
    wrapper.find('.anticon-eye-o').at(1).simulate('click');
    expect(handlePreview).toBeCalledWith(fileList[1]);
  });

  it('should support onRemove', async () => {
    const handleRemove = jest.fn();
    const handleChange = jest.fn();
    const wrapper = mount(
      <Upload
        listType="picture-card"
        defaultFileList={fileList}
        onRemove={handleRemove}
        onChange={handleChange}
      >
        <button>upload</button>
      </Upload>
    );
    wrapper.find('.anticon-delete').at(0).simulate('click');
    expect(handleRemove).toBeCalledWith(fileList[0]);
    wrapper.find('.anticon-delete').at(1).simulate('click');
    expect(handleRemove).toBeCalledWith(fileList[1]);
    await delay(0);
    expect(handleChange.mock.calls.length).toBe(2);
  });

  it('should generate thumbUrl from file', async () => {
    const handlePreview = jest.fn();
    const newFileList = [...fileList];
    const newFile = { ...fileList[0], uid: -3, originFileObj: new File([], 'xxx.png') };
    delete newFile.thumbUrl;
    newFileList.push(newFile);
    const wrapper = mount(
      <Upload
        listType="picture-card"
        defaultFileList={newFileList}
        onPreview={handlePreview}
      >
        <button>upload</button>
      </Upload>
    );
    wrapper.setState({});
    await delay(200);
    expect(wrapper.state().fileList[2].thumbUrl).not.toBeFalsy();
  });

  it('should non-image format file preview', () => {
    const list = [
      {
        ...fileList[0],
        uid: -3,
        url: 'https://cdn.xxx.com/aaa.zip',
        thumbUrl: 'data:application/zip;base64,UEsDBAoAAAAAADYZYkwAAAAAAAAAAAAAAAAdAAk',
        originFileObj: new File([], 'aaa.zip'),
      },
    ];

    const wrapper = mount(
      <Upload
        listType="picture"
        defaultFileList={list}
      >
        <button>upload</button>
      </Upload>
    );
    expect(wrapper.render()).toMatchSnapshot();
  });
});
<|endoftext|>


<commit_before>/**
 * Author: Bruno Germano
 * Date: 2012-09-26 19:45
 * URL: https://github.com/egermano/jquery.dateAgo
 */

 /**
  * Date Ago
  * @param  string input
  * @param  object options
  * @return string formated string
  */
angular.module('egermano.dateAgo', [])
  .fitler('dateAgo', function() {
    return function(input){
      if (!input) return input;

      var options = {};
      if (arguments[1]) options = arguments[1];

      // This is the easiest way to have default options.
      var settings = $.extend({
        texts: {
          now: 'just now',
          minutes: 'minutes ago',
          hour: 'hour ago',
          hours: 'hours ago',
          yesterday: 'yesterday',
          days: 'dasy ago'
        }
      }, options );

      var baseDate = input;

      //date from menssage
      var date = new Date(Date.parse(baseDate)).toLocaleDateString(),
          hour = new Date(Date.parse(baseDate)).toLocaleTimeString(),
          _agoDate = new Date(date + ' ' + hour),
          today = new Date(),

          diff = (today.getTime()-_agoDate.getTime()),
          dataText = '';

      if(diff<(1000*60*60*24)){
          if(diff<(1000*60*60)){
              var minutes = Math.floor(diff/(1000*60));
              if(minutes <= 1)
                  dataText = settings.texts.now;
              else
                  dataText = minutes.toString() + ' ' + settings.texts.minutes;
          }else{
              var hours = Math.floor(diff/(1000*60*60));
              dataText = hours.toString() + (hours==1?' ' + settings.texts.hour:' ' + settings.texts.hours);
          }
      }else{
          var days = Math.floor(diff/(1000*60*60*24));
          if(days==1)
              dataText = settings.texts.yesterday;
          else
              dataText = days.toString() + ' ' + settings.texts.days;
      }

      return dataText;
    }
  });
<commit_msg>fix type<commit_after>/**
 * Author: Bruno Germano
 * Date: 2015-11-13 16:30
 * URL: https://github.com/egermano/jquery.dateAgo
 */

 /**
  * Date Ago
  * @param  string input
  * @param  object options
  * @return string formated string
  */
angular.module('egermano.dateAgo', [])
  .filter('dateAgo', function() {
    return function(input){
      if (!input) return input;

      var options = {};
      if (arguments[1]) options = arguments[1];

      // This is the easiest way to have default options.
      var settings = $.extend({
        texts: {
          now: 'just now',
          minutes: 'minutes ago',
          hour: 'hour ago',
          hours: 'hours ago',
          yesterday: 'yesterday',
          days: 'days ago'
        }
      }, options );

      var baseDate = input;

      //date from menssage
      var date = new Date(Date.parse(baseDate)).toLocaleDateString(),
          hour = new Date(Date.parse(baseDate)).toLocaleTimeString(),
          _agoDate = new Date(date + ' ' + hour),
          today = new Date(),

          diff = (today.getTime()-_agoDate.getTime()),
          dataText = '';

      if(diff<(1000*60*60*24)){
          if(diff<(1000*60*60)){
              var minutes = Math.floor(diff/(1000*60));
              if(minutes <= 1)
                  dataText = settings.texts.now;
              else
                  dataText = minutes.toString() + ' ' + settings.texts.minutes;
          }else{
              var hours = Math.floor(diff/(1000*60*60));
              dataText = hours.toString() + (hours==1?' ' + settings.texts.hour:' ' + settings.texts.hours);
          }
      }else{
          var days = Math.floor(diff/(1000*60*60*24));
          if(days==1)
              dataText = settings.texts.yesterday;
          else
              dataText = days.toString() + ' ' + settings.texts.days;
      }

      return dataText;
    }
  });
<|endoftext|>


<commit_before>/**
 * @license Copyright (c) 2011 Cello Software, LLC.
 * All rights reserved.
 * Available via the new BSD License.
 */
/*jshint
	bitwise: false, curly: true, eqeqeq: true, forin: true, immed: true, indent: 4, maxlen: 100,
	newcap: true, noarg: true, noempty: true, onevar: true, passfail: false, strict: true,
	undef: true, white: true
*/
/*global define: false, require: false */

define([
	'compose',
	'promise',
	'lang'
], function (compose, promise, lang) {
	'use strict';
	return compose(compose, function MessageProcessor() {
		this.interceptors = this.interceptors || [];
		this.listeners = this.listeners || [];
		this.msg = this.msg || '';
		this._interceptor = this._listener = 0;
	}, {

		process: function () {
			// process should only be called the first time.
			// next should be called in subsequent calls
			if (!this._processed) {
				this._processed = true;
				return this.next();
			}
		},

		next: function () {
			var dfd = promise.defer(),
				interceptors = this.interceptors,
				listeners = this.listeners,
				interceptor = interceptors[this._interceptor],
				listener = listeners[this._listener],
				processor = this,
				msg = this.msg,
				next = lang.hitch(this, 'next'),
				resolve = lang.hitch(dfd, 'resolve'),
				reject = lang.hitch(dfd, 'reject'),
				results,
				error;

			function proceed() {
				// proceed is called by interceptors to allow processing to continue and also
				// after each listener has been called.  eventually, this chain of promises unwinds
				// and the original promise returned from process is resolved.

				// XXX: is next actually needed/correct as the error callback?
				return processor.next().then(next, next);
			}

			if (interceptor) {
				this._interceptor++;
				// only proceed when the interceptor says to
				interceptor.intercept({
					msg: msg,
					proceed: function () {
						proceed().then(resolve, reject);
					}
				});
			}
			else if (listener) {
				results = listener.results ? lang.hitch(listener, 'results') : null;
				error = listener.error ? lang.hitch(listener, 'error') : null;
				this._listener++;
				// execute the listener - add callbacks if available.  let all async listeners
				// proceed in parallel and don't wait for them to finish
				promise.all([
					// execute this listener right now and...
					promise.when(listener.execute(msg), results, error),
					// execute the rest of the listeners in parallel
					proceed()
				]).then(resolve, reject);
			}
			else {
				resolve();
			}

			return dfd.promise;
		}
	});
});
<commit_msg>have the message processor return the event to the dispatcher.  at least it's consistent<commit_after>/**
 * @license Copyright (c) 2011 Cello Software, LLC.
 * All rights reserved.
 * Available via the new BSD License.
 */
/*jshint
	bitwise: false, curly: true, eqeqeq: true, forin: true, immed: true, indent: 4, maxlen: 100,
	newcap: true, noarg: true, noempty: true, onevar: true, passfail: false, strict: true,
	undef: true, white: true
*/
/*global define: false, require: false */

define([
	'compose',
	'promise',
	'lang'
], function (compose, promise, lang) {
	'use strict';
	return compose(compose, function MessageProcessor() {
		this.interceptors = this.interceptors || [];
		this.listeners = this.listeners || [];
		this.msg = this.msg || '';
		this._interceptor = this._listener = 0;
	}, {

		process: function () {
			// process should only be called the first time.
			// next should be called in subsequent calls
			if (!this._processed) {
				this._processed = true;
				return this.next();
			}
		},

		next: function () {
			var dfd = promise.defer(),
				processor = this,
				// avoid dealing with mutating arrays by calling slice
				interceptors = processor.interceptors.slice(),
				listeners = processor.listeners.slice(),
				interceptor = interceptors[processor._interceptor],
				listener = listeners[processor._listener],
				msg = processor.msg,
				next = lang.hitch(processor, 'next'),
				resolve = lang.hitch(dfd, 'resolve'),
				reject = lang.hitch(dfd, 'reject'),
				results,
				error;

			function proceed() {
				// proceed is called by interceptors to allow processing to continue and also
				// after each listener has been called.  eventually, this chain of promises unwinds
				// and the original promise returned from process is resolved.

				// XXX: is next actually needed/correct as the error callback?
				return processor.next().then(next, next);
			}

			if (interceptor) {
				processor._interceptor++;
				// only proceed when the interceptor says to
				interceptor.intercept({
					msg: msg,
					proceed: function () {
						proceed().then(resolve, reject);
					}
				});
			}
			else if (listener) {
				results = listener.results ? lang.hitch(listener, 'results') : null;
				error = listener.error ? lang.hitch(listener, 'error') : null;
				processor._listener++;
				// execute the listener - add callbacks if available.  let all async listeners
				// proceed in parallel and don't wait for them to finish
				promise.all([
					// execute this listener right now and...
					promise.when(listener.execute(msg), results, error),
					// execute the rest of the listeners in parallel
					proceed()
				]).then(function () {
					// return the original message for anyone listening
					resolve(msg);
				}, reject);
			}
			else {
				resolve(msg);
			}

			return dfd.promise;
		}
	});
});
<|endoftext|>