<commit_before>/*
 * Copyright (c) 2015
 *
 * This file is licensed under the Affero General Public License version 3
 * or later.
 *
 * See the COPYING-README file.
 *
 */

(function() {
	if(!OC.Share) {
		OC.Share = {};
	}

	var TEMPLATE_BASE =
		'

' +
		'{{#if isSharingAllowed}}' +
		'{{shareLabel}}' +
		'
' +
		'    <input id="shareWith-{{cid}}" class="shareWithField" type="text" placeholder="{{sharePlaceholder}}" />' +
		'    '+
		'{{{remoteShareInfo}}}' +
		'
' +
		'{{/if}}' +
		'

' +
		'

' +
		'

' +
		'

' +
		'

';

	var TEMPLATE_REMOTE_SHARE_INFO =
		'';

	/**
	 * @class OCA.Share.ShareDialogView
	 * @member {OC.Share.ShareItemModel} model
	 * @member {jQuery} $el
	 * @memberof OCA.Sharing
	 * @classdesc
	 *
	 * Represents the GUI of the share dialogue
	 *
	 */
	var ShareDialogView = OC.Backbone.View.extend({
		/** @type {Object} **/
		_templates: {},

		/** @type {boolean} **/
		_showLink: true,

		/** @type {string} **/
		tagName: 'div',

		/** @type {OC.Share.ShareConfigModel} **/
		configModel: undefined,

		/** @type {object} **/
		resharerInfoView: undefined,

		/** @type {object} **/
		linkShareView: undefined,

		/** @type {object} **/
		expirationView: undefined,

		/** @type {object} **/
		shareeListView: undefined,

		/** @type {object} **/
		mailView: undefined,

		events: {
			'input .shareWithField': 'onShareWithFieldChanged'
		},

		initialize: function(options) {
			var view = this;

			this.model.on('fetchError', function() {
				OC.Notification.showTemporary(t('core', 'Share details could not be loaded for this item.'));
			});

			if(!_.isUndefined(options.configModel)) {
				this.configModel = options.configModel;
			} else {
				throw 'missing OC.Share.ShareConfigModel';
			}

			this.configModel.on('change:isRemoteShareAllowed', function() {
				view.render();
			});
			this.model.on('change:permissions', function() {
				view.render();
			});

			this.model.on('request', this._onRequest, this);
			this.model.on('sync', this._onEndRequest, this);

			var subViewOptions = {
				model: this.model,
				configModel: this.configModel
			};

			var subViews = {
				resharerInfoView: 'ShareDialogResharerInfoView',
				linkShareView: 'ShareDialogLinkShareView',
				expirationView: 'ShareDialogExpirationView',
				shareeListView: 'ShareDialogShareeListView',
				mailView: 'ShareDialogMailView'
			};

			for(var name in subViews) {
				var className = subViews[name];
				this[name] = _.isUndefined(options[name])
					? new OC.Share[className](subViewOptions)
					: options[name];
			}

			_.bindAll(this,
				'autocompleteHandler',
				'_onSelectRecipient',
				'onShareWithFieldChanged'
			);
		},

		onShareWithFieldChanged: function() {
			var $el = this.$el.find('.shareWithField');
			if ($el.val().length < 2) {
				$el.removeClass('error').tooltip('hide');
			}
		},

		autocompleteHandler: function (search, response) {
			var view = this;
			var $loading = this.$el.find('.shareWithLoading');
			$loading.removeClass('hidden');
			$loading.addClass('inlineblock');
			$.get(
				OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees',
				{
					format: 'json',
					search: search.term.trim(),
					perPage: 200,
					itemType: view.model.get('itemType')
				},
				function (result) {
					$loading.addClass('hidden');
					$loading.removeClass('inlineblock');
					if (result.ocs.meta.statuscode == 100) {
						var users   = result.ocs.data.exact.users.concat(result.ocs.data.users);
						var groups  = result.ocs.data.exact.groups.concat(result.ocs.data.groups);
						var remotes = result.ocs.data.exact.remotes.concat(result.ocs.data.remotes);

						var usersLength;
						var groupsLength;
						var remotesLength;

						var i, j;

						//Filter out the current user
						usersLength = users.length;
						for (i = 0 ; i < usersLength; i++) {
							if (users[i].value.shareWith === OC.currentUser) {
								users.splice(i, 1);
								break;
							}
						}

						// Filter out the owner of the share
						if (view.model.hasReshare()) {
							usersLength = users.length;
							for (i = 0 ; i < usersLength; i++) {
								if (users[i].value.shareWith === view.model.getReshareOwner()) {
									users.splice(i, 1);
									break;
								}
							}
						}

						var shares = view.model.get('shares');
						var sharesLength = shares.length;

						// Now filter out all sharees that are already shared with
						for (i = 0; i < sharesLength; i++) {
							var share = shares[i];

							if (share.share_type === OC.Share.SHARE_TYPE_USER) {
								usersLength = users.length;
								for (j = 0; j < usersLength; j++) {
									if (users[j].value.shareWith === share.share_with) {
										users.splice(j, 1);
										break;
									}
								}
							} else if (share.share_type === OC.Share.SHARE_TYPE_GROUP) {
								groupsLength = groups.length;
								for (j = 0; j < groupsLength; j++) {
									if (groups[j].value.shareWith === share.share_with) {
										groups.splice(j, 1);
										break;
									}
								}
							} else if (share.share_type === OC.Share.SHARE_TYPE_REMOTE) {
								remotesLength = remotes.length;
								for (j = 0; j < remotesLength; j++) {
									if (remotes[j].value.shareWith === share.share_with) {
										remotes.splice(j, 1);
										break;
									}
								}
							}
						}

						var suggestions = users.concat(groups).concat(remotes);

						if (suggestions.length > 0) {
							$('.shareWithField').removeClass('error')
								.tooltip('hide')
								.autocomplete("option", "autoFocus", true);
							response(suggestions);
						} else {
							var title = t('core', 'No users or groups found for {search}', {search: $('.shareWithField').val()});
							if (!view.configModel.get('allowGroupSharing')) {
								title = t('core', 'No users found for {search}', {search: $('.shareWithField').val()});
							}
							$('.shareWithField').addClass('error')
								.attr('data-original-title', title)
								.tooltip('hide')
								.tooltip({
									placement: 'bottom',
									trigger: 'manual'
								})
								.tooltip('fixTitle')
								.tooltip('show');
							response();
						}
					} else {
						response();
					}
				}
			).fail(function() {
				$loading.addClass('hidden');
				$loading.removeClass('inlineblock');
				OC.Notification.show(t('core', 'An error occurred. Please try again'));
				window.setTimeout(OC.Notification.hide, 5000);
			});
		},

		autocompleteRenderItem: function(ul, item) {
			var insert = $("");
			var text = item.label;
			if (item.value.shareType === OC.Share.SHARE_TYPE_GROUP) {
				text = t('core', '{sharee} (group)', {
					sharee: text
				});
			} else if (item.value.shareType === OC.Share.SHARE_TYPE_REMOTE) {
				if (item.value.server) {
					text = t('core', '{sharee} (at {server})', {
						sharee: text,
						server: item.value.server
					});
				} else {
					text = t('core', '{sharee} (remote)', {
						sharee: text
					});
				}
			}
			insert.text(text);
			insert.attr('title', item.value.shareWith);
			if(item.value.shareType === OC.Share.SHARE_TYPE_GROUP) {
				insert = insert.wrapInner('');
			}
			insert.tooltip({
				placement: 'bottom',
				container: 'body'
			});
			return $("
")
				.addClass((item.value.shareType === OC.Share.SHARE_TYPE_GROUP) ? 'group' : 'user')
				.append(insert)
				.appendTo(ul);
		},

		_onSelectRecipient: function(e, s) {
			e.preventDefault();
			$(e.target).attr('disabled', true)
				.val(s.item.label);
			var $loading = this.$el.find('.shareWithLoading');
			$loading.removeClass('hidden')
				.addClass('inlineblock');

			this.model.addShare(s.item.value, {success: function() {
				$(e.target).val('')
					.attr('disabled', false);
				$loading.addClass('hidden')
					.removeClass('inlineblock');
			}, error: function(obj, msg) {
				OC.Notification.showTemporary(msg);
				$(e.target).attr('disabled', false)
					.autocomplete('search', $(e.target).val());
				$loading.addClass('hidden')
					.removeClass('inlineblock');
			}});
		},

		_toggleLoading: function(state) {
			this._loading = state;
			this.$el.find('.subView').toggleClass('hidden', state);
			this.$el.find('.loading').toggleClass('hidden', !state);
		},

		_onRequest: function() {
			// only show the loading spinner for the first request (for now)
			if (!this._loadingOnce) {
				this._toggleLoading(true);
			}
		},

		_onEndRequest: function() {
			var self = this;
			this._toggleLoading(false);
			if (!this._loadingOnce) {
				this._loadingOnce = true;
				// the first time, focus on the share field after the spinner disappeared
				_.defer(function() {
					self.$('.shareWithField').focus();
				});
			}
		},

		render: function() {
			var baseTemplate = this._getTemplate('base', TEMPLATE_BASE);

			this.$el.html(baseTemplate({
				cid: this.cid,
				shareLabel: t('core', 'Share'),
				sharePlaceholder: this._renderSharePlaceholderPart(),
				remoteShareInfo: this._renderRemoteShareInfoPart(),
				isSharingAllowed: this.model.sharePermissionPossible()
			}));

			var $shareField = this.$el.find('.shareWithField');
			if ($shareField.length) {
				$shareField.autocomplete({
					minLength: 1,
					delay: 750,
					focus: function(event) {
						event.preventDefault();
					},
					source: this.autocompleteHandler,
					select: this._onSelectRecipient
				}).data('ui-autocomplete')._renderItem = this.autocompleteRenderItem;
			}

			this.resharerInfoView.$el = this.$el.find('.resharerInfoView');
			this.resharerInfoView.render();

			this.linkShareView.$el = this.$el.find('.linkShareView');
			this.linkShareView.render();

			this.expirationView.$el = this.$el.find('.expirationView');
			this.expirationView.render();

			this.shareeListView.$el = this.$el.find('.shareeListView');
			this.shareeListView.render();

			this.mailView.$el = this.$el.find('.mailView');
			this.mailView.render();

			this.$el.find('.hasTooltip').tooltip();

			return this;
		},

		/**
		 * sets whether share by link should be displayed or not. Default is
		 * true.
		 *
		 * @param {bool} showLink
		 */
		setShowLink: function(showLink) {
			this._showLink = (typeof showLink === 'boolean') ? showLink : true;
			this.linkShareView.showLink = this._showLink;
		},

		_renderRemoteShareInfoPart: function() {
			var remoteShareInfo = '';
			if(this.configModel.get('isRemoteShareAllowed')) {
				var infoTemplate = this._getRemoteShareInfoTemplate();
				remoteShareInfo = infoTemplate({
					docLink: this.configModel.getFederatedShareDocLink(),
					tooltip: t('core', 'Share with people on other ownClouds using the syntax username@example.com/owncloud')
				});
			}

			return remoteShareInfo;
		},

		_renderSharePlaceholderPart: function () {
			var sharePlaceholder = t('core', 'Share with users…');

			if (this.configModel.get('allowGroupSharing')) {
				if (this.configModel.get('isRemoteShareAllowed')) {
					sharePlaceholder = t('core', 'Share with users, groups or remote users…');
				} else {
					sharePlaceholder = t('core', 'Share with users or groups…')
				}
			} else if (this.configModel.get('isRemoteShareAllowed')) {
					sharePlaceholder = t('core', 'Share with users or remote users…');
			}

			return sharePlaceholder;
		},

		/**
		 *
		 * @param {string} key - an identifier for the template
		 * @param {string} template - the HTML to be compiled by Handlebars
		 * @returns {Function} from Handlebars
		 * @private
		 */
		_getTemplate: function (key, template) {
			if (!this._templates[key]) {
				this._templates[key] = Handlebars.compile(template);
			}
			return this._templates[key];
		},

		/**
		 * returns the info template for remote sharing
		 *
		 * @returns {Function}
		 * @private
		 */
		_getRemoteShareInfoTemplate: function() {
			return this._getTemplate('remoteShareInfo', TEMPLATE_REMOTE_SHARE_INFO);
		}
	});

	OC.Share.ShareDialogView = ShareDialogView;

})();
<commit_msg>OCREPORT: disable internal share for files<commit_after>/*
 * Copyright (c) 2015
 *
 * This file is licensed under the Affero General Public License version 3
 * or later.
 *
 * See the COPYING-README file.
 *
 */

(function() {
	if(!OC.Share) {
		OC.Share = {};
	}

	var TEMPLATE_BASE =
		'

' +
		'{{#if isSharingAllowed}}' +
		'{{shareLabel}}' +
		'{{#if isDir}}' +
		'
' +
		'    <input id="shareWith-{{cid}}" class="shareWithField" type="text" placeholder="{{sharePlaceholder}}" />' +
		'    '+
		'{{{remoteShareInfo}}}' +
		'
' +
		'{{/if}}' +
		'{{/if}}' +
		'

' +
		'

' +
		'

' +
		'

' +
		'

';

	var TEMPLATE_REMOTE_SHARE_INFO =
		'';

	/**
	 * @class OCA.Share.ShareDialogView
	 * @member {OC.Share.ShareItemModel} model
	 * @member {jQuery} $el
	 * @memberof OCA.Sharing
	 * @classdesc
	 *
	 * Represents the GUI of the share dialogue
	 *
	 */
	var ShareDialogView = OC.Backbone.View.extend({
		/** @type {Object} **/
		_templates: {},

		/** @type {boolean} **/
		_showLink: true,

		/** @type {string} **/
		tagName: 'div',

		/** @type {OC.Share.ShareConfigModel} **/
		configModel: undefined,

		/** @type {object} **/
		resharerInfoView: undefined,

		/** @type {object} **/
		linkShareView: undefined,

		/** @type {object} **/
		expirationView: undefined,

		/** @type {object} **/
		shareeListView: undefined,

		/** @type {object} **/
		mailView: undefined,

		events: {
			'input .shareWithField': 'onShareWithFieldChanged'
		},

		initialize: function(options) {
			var view = this;

			this.model.on('fetchError', function() {
				OC.Notification.showTemporary(t('core', 'Share details could not be loaded for this item.'));
			});

			if(!_.isUndefined(options.configModel)) {
				this.configModel = options.configModel;
			} else {
				throw 'missing OC.Share.ShareConfigModel';
			}

			this.configModel.on('change:isRemoteShareAllowed', function() {
				view.render();
			});
			this.model.on('change:permissions', function() {
				view.render();
			});

			this.model.on('request', this._onRequest, this);
			this.model.on('sync', this._onEndRequest, this);

			var subViewOptions = {
				model: this.model,
				configModel: this.configModel
			};

			var subViews = {
				resharerInfoView: 'ShareDialogResharerInfoView',
				linkShareView: 'ShareDialogLinkShareView',
				expirationView: 'ShareDialogExpirationView',
				shareeListView: 'ShareDialogShareeListView',
				mailView: 'ShareDialogMailView'
			};

			for(var name in subViews) {
				var className = subViews[name];
				this[name] = _.isUndefined(options[name])
					? new OC.Share[className](subViewOptions)
					: options[name];
			}

			_.bindAll(this,
				'autocompleteHandler',
				'_onSelectRecipient',
				'onShareWithFieldChanged'
			);
		},

		onShareWithFieldChanged: function() {
			var $el = this.$el.find('.shareWithField');
			if ($el.val().length < 2) {
				$el.removeClass('error').tooltip('hide');
			}
		},

		autocompleteHandler: function (search, response) {
			var view = this;
			var $loading = this.$el.find('.shareWithLoading');
			$loading.removeClass('hidden');
			$loading.addClass('inlineblock');
			$.get(
				OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees',
				{
					format: 'json',
					search: search.term.trim(),
					perPage: 200,
					itemType: view.model.get('itemType')
				},
				function (result) {
					$loading.addClass('hidden');
					$loading.removeClass('inlineblock');
					if (result.ocs.meta.statuscode == 100) {
						var users   = result.ocs.data.exact.users.concat(result.ocs.data.users);
						var groups  = result.ocs.data.exact.groups.concat(result.ocs.data.groups);
						var remotes = result.ocs.data.exact.remotes.concat(result.ocs.data.remotes);

						var usersLength;
						var groupsLength;
						var remotesLength;

						var i, j;

						//Filter out the current user
						usersLength = users.length;
						for (i = 0 ; i < usersLength; i++) {
							if (users[i].value.shareWith === OC.currentUser) {
								users.splice(i, 1);
								break;
							}
						}

						// Filter out the owner of the share
						if (view.model.hasReshare()) {
							usersLength = users.length;
							for (i = 0 ; i < usersLength; i++) {
								if (users[i].value.shareWith === view.model.getReshareOwner()) {
									users.splice(i, 1);
									break;
								}
							}
						}

						var shares = view.model.get('shares');
						var sharesLength = shares.length;

						// Now filter out all sharees that are already shared with
						for (i = 0; i < sharesLength; i++) {
							var share = shares[i];

							if (share.share_type === OC.Share.SHARE_TYPE_USER) {
								usersLength = users.length;
								for (j = 0; j < usersLength; j++) {
									if (users[j].value.shareWith === share.share_with) {
										users.splice(j, 1);
										break;
									}
								}
							} else if (share.share_type === OC.Share.SHARE_TYPE_GROUP) {
								groupsLength = groups.length;
								for (j = 0; j < groupsLength; j++) {
									if (groups[j].value.shareWith === share.share_with) {
										groups.splice(j, 1);
										break;
									}
								}
							} else if (share.share_type === OC.Share.SHARE_TYPE_REMOTE) {
								remotesLength = remotes.length;
								for (j = 0; j < remotesLength; j++) {
									if (remotes[j].value.shareWith === share.share_with) {
										remotes.splice(j, 1);
										break;
									}
								}
							}
						}

						var suggestions = users.concat(groups).concat(remotes);

						if (suggestions.length > 0) {
							$('.shareWithField').removeClass('error')
								.tooltip('hide')
								.autocomplete("option", "autoFocus", true);
							response(suggestions);
						} else {
							var title = t('core', 'No users or groups found for {search}', {search: $('.shareWithField').val()});
							if (!view.configModel.get('allowGroupSharing')) {
								title = t('core', 'No users found for {search}', {search: $('.shareWithField').val()});
							}
							$('.shareWithField').addClass('error')
								.attr('data-original-title', title)
								.tooltip('hide')
								.tooltip({
									placement: 'bottom',
									trigger: 'manual'
								})
								.tooltip('fixTitle')
								.tooltip('show');
							response();
						}
					} else {
						response();
					}
				}
			).fail(function() {
				$loading.addClass('hidden');
				$loading.removeClass('inlineblock');
				OC.Notification.show(t('core', 'An error occurred. Please try again'));
				window.setTimeout(OC.Notification.hide, 5000);
			});
		},

		autocompleteRenderItem: function(ul, item) {
			var insert = $("");
			var text = item.label;
			if (item.value.shareType === OC.Share.SHARE_TYPE_GROUP) {
				text = t('core', '{sharee} (group)', {
					sharee: text
				});
			} else if (item.value.shareType === OC.Share.SHARE_TYPE_REMOTE) {
				if (item.value.server) {
					text = t('core', '{sharee} (at {server})', {
						sharee: text,
						server: item.value.server
					});
				} else {
					text = t('core', '{sharee} (remote)', {
						sharee: text
					});
				}
			}
			insert.text(text);
			insert.attr('title', item.value.shareWith);
			if(item.value.shareType === OC.Share.SHARE_TYPE_GROUP) {
				insert = insert.wrapInner('');
			}
			insert.tooltip({
				placement: 'bottom',
				container: 'body'
			});
			return $("
")
				.addClass((item.value.shareType === OC.Share.SHARE_TYPE_GROUP) ? 'group' : 'user')
				.append(insert)
				.appendTo(ul);
		},

		_onSelectRecipient: function(e, s) {
			e.preventDefault();
			$(e.target).attr('disabled', true)
				.val(s.item.label);
			var $loading = this.$el.find('.shareWithLoading');
			$loading.removeClass('hidden')
				.addClass('inlineblock');

			this.model.addShare(s.item.value, {success: function() {
				$(e.target).val('')
					.attr('disabled', false);
				$loading.addClass('hidden')
					.removeClass('inlineblock');
			}, error: function(obj, msg) {
				OC.Notification.showTemporary(msg);
				$(e.target).attr('disabled', false)
					.autocomplete('search', $(e.target).val());
				$loading.addClass('hidden')
					.removeClass('inlineblock');
			}});
		},

		_toggleLoading: function(state) {
			this._loading = state;
			this.$el.find('.subView').toggleClass('hidden', state);
			this.$el.find('.loading').toggleClass('hidden', !state);
		},

		_onRequest: function() {
			// only show the loading spinner for the first request (for now)
			if (!this._loadingOnce) {
				this._toggleLoading(true);
			}
		},

		_onEndRequest: function() {
			var self = this;
			this._toggleLoading(false);
			if (!this._loadingOnce) {
				this._loadingOnce = true;
				// the first time, focus on the share field after the spinner disappeared
				_.defer(function() {
					self.$('.shareWithField').focus();
				});
			}
		},

		render: function() {
			var baseTemplate = this._getTemplate('base', TEMPLATE_BASE);

			console.log(this.model);
			this.$el.html(baseTemplate({
				cid: this.cid,
				shareLabel: t('core', 'Share'),
				sharePlaceholder: this._renderSharePlaceholderPart(),
				remoteShareInfo: this._renderRemoteShareInfoPart(),
				isSharingAllowed: this.model.sharePermissionPossible(),
				isDir: this.model.get('itemType') === 'dir' ? true : false
			}));

			var $shareField = this.$el.find('.shareWithField');
			if ($shareField.length) {
				$shareField.autocomplete({
					minLength: 1,
					delay: 750,
					focus: function(event) {
						event.preventDefault();
					},
					source: this.autocompleteHandler,
					select: this._onSelectRecipient
				}).data('ui-autocomplete')._renderItem = this.autocompleteRenderItem;
			}

			this.resharerInfoView.$el = this.$el.find('.resharerInfoView');
			this.resharerInfoView.render();

			this.linkShareView.$el = this.$el.find('.linkShareView');
			this.linkShareView.render();

			this.expirationView.$el = this.$el.find('.expirationView');
			this.expirationView.render();

			this.shareeListView.$el = this.$el.find('.shareeListView');
			this.shareeListView.render();

			this.mailView.$el = this.$el.find('.mailView');
			this.mailView.render();

			this.$el.find('.hasTooltip').tooltip();

			return this;
		},

		/**
		 * sets whether share by link should be displayed or not. Default is
		 * true.
		 *
		 * @param {bool} showLink
		 */
		setShowLink: function(showLink) {
			this._showLink = (typeof showLink === 'boolean') ? showLink : true;
			this.linkShareView.showLink = this._showLink;
		},

		_renderRemoteShareInfoPart: function() {
			var remoteShareInfo = '';
			if(this.configModel.get('isRemoteShareAllowed')) {
				var infoTemplate = this._getRemoteShareInfoTemplate();
				remoteShareInfo = infoTemplate({
					docLink: this.configModel.getFederatedShareDocLink(),
					tooltip: t('core', 'Share with people on other ownClouds using the syntax username@example.com/owncloud')
				});
			}

			return remoteShareInfo;
		},

		_renderSharePlaceholderPart: function () {
			var sharePlaceholder = t('core', 'Share with users…');

			if (this.configModel.get('allowGroupSharing')) {
				if (this.configModel.get('isRemoteShareAllowed')) {
					sharePlaceholder = t('core', 'Share with users, groups or remote users…');
				} else {
					sharePlaceholder = t('core', 'Share with users or groups…')
				}
			} else if (this.configModel.get('isRemoteShareAllowed')) {
					sharePlaceholder = t('core', 'Share with users or remote users…');
			}

			return sharePlaceholder;
		},

		/**
		 *
		 * @param {string} key - an identifier for the template
		 * @param {string} template - the HTML to be compiled by Handlebars
		 * @returns {Function} from Handlebars
		 * @private
		 */
		_getTemplate: function (key, template) {
			if (!this._templates[key]) {
				this._templates[key] = Handlebars.compile(template);
			}
			return this._templates[key];
		},

		/**
		 * returns the info template for remote sharing
		 *
		 * @returns {Function}
		 * @private
		 */
		_getRemoteShareInfoTemplate: function() {
			return this._getTemplate('remoteShareInfo', TEMPLATE_REMOTE_SHARE_INFO);
		}
	});

	OC.Share.ShareDialogView = ShareDialogView;

})();
<|endoftext|>


<commit_before>var child_process = require('child_process');
var spawn = child_process.spawn;
var exec = child_process.exec;

/**
* Function that takes in an array of tasks that will be individually
*   passed to the spawn function, then runs each task in series. At the
*   end of all the tasks, a final callback will be invoked.
* @function
* @memberof module:helpers
* EXAMPLE
*   spawnSeries([
*    ['ls', ['-lh', '/usr']],
*    ['ls', ['-la']]
*   ], function() { console.log('all done!'); });
*/
var spawnSeries = function(tasks, callback) {
  callback = callback || function() {};
  var completed = 0;
  var iterate = function() {
    if (++completed < tasks.length) {
      run();
    } else {
      callback();
    }
  }
  var run = function() {
    var task = tasks[completed];
    console.log("RUNNING:", task);
    var proc = spawn.apply(null, task);
    proc.stdout.on('data', function(data) {
      console.log(data.toString());
    });
    proc.stderr.on('data', function(data) {
      console.log(data.toString());
    });
    proc.on('exit', function(code) {
      // console.log('EXIT CODE:', code);
      iterate();
    });
  }
  run();
}

/**
* Function that takes in an array of docker commands that will be
*   have docker default parameters mapped to them, so they can
*   properly communicate with the boot2docker VM, then runs each
*   task in series.
*   At the end of all the tasks, a final callback will be invoked.
* @function
* @memberof module:helpers
*/
// EXAMPLE
// dockerSpawnSeries([
//   ['docker', ['pull', 'ubuntu:latest']],
//   ['docker', ['-v']]
// ]);
var dockerSpawnSeries = function(commands, callback) {
  callback = callback || function() {};
  getDockerDefaults(function(defaults) {
    commands.map(function(command) {
      command[1] = defaults.concat(command[1]);
    });
    spawnSeries(commands, callback);
  })
}

var getDockerDefaults = function(callback) {
  exec('boot2docker shellinit', function(err, stdout, stderr) {
    parseDefaults(stdout.split('\n'), callback);
  });
}

var parseDefaults = function(arr, callback) {
  var defaults = ['--tlsverify'];
  arr.forEach(function(val) {
    var param = val.trim().split('=');
    if (param[0] === 'export DOCKER_HOST') {
      defaults.push('-H');
      defaults.push(param[1]);
    } else if (param[0] === 'export DOCKER_CERT_PATH') {
      defaults.push('--tlscacert="' + param[1] + '/ca.pem"');
      defaults.push('--tlscert="' + param[1] + '/cert.pem"');
      defaults.push('--tlskey="' + param[1] + '/key.pem"');
    }
  });
  callback(defaults);
}

module.exports = {
  spawnSeries: spawnSeries,
  dockerSpawnSeries: dockerSpawnSeries
}
<commit_msg>refactor how docker run commands are printed to console<commit_after>var child_process = require('child_process');
var spawn = child_process.spawn;
var exec = child_process.exec;

/**
* Function that takes in an array of tasks that will be individually
*   passed to the spawn function, then runs each task in series. At the
*   end of all the tasks, a final callback will be invoked.
* @function
* @memberof module:helpers
* EXAMPLE
*   spawnSeries([
*    ['ls', ['-lh', '/usr']],
*    ['ls', ['-la']]
*   ], function() { console.log('all done!'); });
*/
var spawnSeries = function(tasks, callback) {
  callback = callback || function() {};
  var completed = 0;
  var iterate = function() {
    if (++completed < tasks.length) {
      run();
    } else {
      callback();
    }
  }
  var run = function() {
    var task = tasks[completed];

    var commandText = "docker ";
      for(var i = 6; i < task[1].length; i++) {
        commandText += task[1][i] + " ";
      }
    console.log("RUNNING:", commandText);

    var proc = spawn.apply(null, task);
    proc.stdout.on('data', function(data) {
      console.log(data.toString());
    });
    proc.stderr.on('data', function(data) {
      console.log(data.toString());
    });
    proc.on('exit', function(code) {
      // show error code if error
      if (code !== 0) {
        console.log('DOCKER COMMAND RAN:');
        console.log(commandText);
        console.log('EXITED WITH CODE:', code);
      }

      iterate();
    });
  }
  run();
}

/**
* Function that takes in an array of docker commands that will be
*   have docker default parameters mapped to them, so they can
*   properly communicate with the boot2docker VM, then runs each
*   task in series.
*   At the end of all the tasks, a final callback will be invoked.
* @function
* @memberof module:helpers
*/
// EXAMPLE
// dockerSpawnSeries([
//   ['docker', ['pull', 'ubuntu:latest']],
//   ['docker', ['-v']]
// ]);
var dockerSpawnSeries = function(commands, callback) {
  callback = callback || function() {};
  getDockerDefaults(function(defaults) {
    commands.map(function(command) {
      command[1] = defaults.concat(command[1]);
    });
    spawnSeries(commands, callback);
  })
}

var getDockerDefaults = function(callback) {
  exec('boot2docker shellinit', function(err, stdout, stderr) {
    parseDefaults(stdout.split('\n'), callback);
  });
}

var parseDefaults = function(arr, callback) {
  var defaults = ['--tlsverify'];
  arr.forEach(function(val) {
    var param = val.trim().split('=');
    if (param[0] === 'export DOCKER_HOST') {
      defaults.push('-H');
      defaults.push(param[1]);
    } else if (param[0] === 'export DOCKER_CERT_PATH') {
      defaults.push('--tlscacert="' + param[1] + '/ca.pem"');
      defaults.push('--tlscert="' + param[1] + '/cert.pem"');
      defaults.push('--tlskey="' + param[1] + '/key.pem"');
    }
  });
  callback(defaults);
}

module.exports = {
  spawnSeries: spawnSeries,
  dockerSpawnSeries: dockerSpawnSeries
}
<|endoftext|>


<commit_before>
buster.testCase('View#add()', {
  "setUp": function() {
    this.view = new helpers.Views.List();
  },

  "Should accept a View instance": function() {
    var pear = new helpers.Views.Pear();
    this.view.add(pear);
    assert.equals(this.view.children.length, 1);
  },

  "Should store a reference to the child via slot if the view added has a slot": function() {
    var apple = new Apple({ slot: 1 });
    var layout = new Layout();

    layout.add(apple);

    assert.equals(layout.slots[1], apple);
  },

  "Should aceept JSON": function() {
    this.view.add({ module: 'pear' });
    assert.equals(this.view.children.length, 1);
  },

  "Should the second parameter should define the slot": function() {
    var apple = new Apple();
    var layout = new Layout();

    layout.add(apple, 1);
    assert.equals(layout.slots[1], apple);
  },

  "Should be able to define the slot in the options object": function() {
    var apple = new Apple();
    var layout = new Layout();

    layout.add(apple, { slot: 1 });
    assert.equals(layout.slots[1], apple);
  },

  "Should remove a module if it already occupies this slot": function() {
    var apple = new Apple();
    var orange = new Orange();
    var layout = new Layout();

    layout.add(apple, 1);

    assert.equals(layout.slots[1], apple);

    layout.add(orange, 1);

    assert.equals(layout.slots[1], orange);
    refute(layout.module('apple'));
  },

  "Should remove the module if it already has parent before being added": function() {
    var apple = new Apple();
    var layout = new Layout();
    var spy = this.spy(apple, 'remove');

    layout.add(apple, 1);

    refute(spy.called);
    assert.equals(layout.slots[1], apple);

    layout.add(apple, 2);

    refute.equals(layout.slots[1], apple);
    assert.equals(layout.slots[2], apple);
    assert(spy.called);
  },

  "tearDown": function() {
    this.view = null;
  }
});<commit_msg>Spelling<commit_after>buster.testCase('View#add()', {
  "setUp": function() {
    this.view = new helpers.Views.List();
  },

  "Should accept a View instance": function() {
    var pear = new helpers.Views.Pear();
    this.view.add(pear);
    assert.equals(this.view.children.length, 1);
  },

  "Should store a reference to the child via slot if the view added has a slot": function() {
    var apple = new Apple({ slot: 1 });
    var layout = new Layout();

    layout.add(apple);

    assert.equals(layout.slots[1], apple);
  },

  "Should aceept JSON": function() {
    this.view.add({ module: 'pear' });
    assert.equals(this.view.children.length, 1);
  },

  "Should allow the second parameter to define the slot": function() {
    var apple = new Apple();
    var layout = new Layout();

    layout.add(apple, 1);
    assert.equals(layout.slots[1], apple);
  },

  "Should be able to define the slot in the options object": function() {
    var apple = new Apple();
    var layout = new Layout();

    layout.add(apple, { slot: 1 });
    assert.equals(layout.slots[1], apple);
  },

  "Should remove a module if it already occupies this slot": function() {
    var apple = new Apple();
    var orange = new Orange();
    var layout = new Layout();

    layout.add(apple, 1);

    assert.equals(layout.slots[1], apple);

    layout.add(orange, 1);

    assert.equals(layout.slots[1], orange);
    refute(layout.module('apple'));
  },

  "Should remove the module if it already has parent before being added": function() {
    var apple = new Apple();
    var layout = new Layout();
    var spy = this.spy(apple, 'remove');

    layout.add(apple, 1);

    refute(spy.called);
    assert.equals(layout.slots[1], apple);

    layout.add(apple, 2);

    refute.equals(layout.slots[1], apple);
    assert.equals(layout.slots[2], apple);
    assert(spy.called);
  },

  "tearDown": function() {
    this.view = null;
  }
});
<|endoftext|>


<commit_before>import Check from "./Check.js";
import defaultValue from "./defaultValue.js";
import Rectangle from "./Rectangle.js";
import Resource from "./Resource.js";
import defined from "./defined.js";
import DeveloperError from "./DeveloperError.js";

var url = "https://dev.virtualearth.net/REST/v1/Locations";

/**
 * Provides geocoding through Bing Maps.
 * @alias BingMapsGeocoderService
 * @constructor
 *
 * @param {Object} options Object with the following properties:
 * @param {String} options.key A key to use with the Bing Maps geocoding service
 * @param {String} [options.culture] A Bing Maps { @link https://docs.microsoft.com/en-us/bingmaps/rest-services/common-parameters-and-types/supported-culture-codes|Culture Code} to return results in a specific culture and language.
 */
function BingMapsGeocoderService(options) {
  options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  var key = options.key;
  //>>includeStart('debug', pragmas.debug);
  if (!defined(key)) {
    throw new DeveloperError("options.key is required.");
  }
  //>>includeEnd('debug');

  this._key = key;

  var queryParameters = {
    key: key,
  };

  if (defined(options.culture)) {
    queryParameters.culture = options.culture;
  }

  this._resource = new Resource({
    url: url,
    queryParameters: queryParameters,
  });
}

Object.defineProperties(BingMapsGeocoderService.prototype, {
  /**
   * The URL endpoint for the Bing geocoder service
   * @type {String}
   * @memberof BingMapsGeocoderService.prototype
   * @readonly
   */
  url: {
    get: function () {
      return url;
    },
  },

  /**
   * The key for the Bing geocoder service
   * @type {String}
   * @memberof BingMapsGeocoderService.prototype
   * @readonly
   */
  key: {
    get: function () {
      return this._key;
    },
  },
});

/**
 * @function
 *
 * @param {String} query The query to be sent to the geocoder service
 * @returns {Promise<GeocoderService.Result[]>}
 */
BingMapsGeocoderService.prototype.geocode = function (query) {
  //>>includeStart('debug', pragmas.debug);
  Check.typeOf.string("query", query);
  //>>includeEnd('debug');

  var resource = this._resource.getDerivedResource({
    queryParameters: {
      query: query,
    },
  });

  return resource.fetchJsonp("jsonp").then(function (result) {
    if (result.resourceSets.length === 0) {
      return [];
    }

    var results = result.resourceSets[0].resources;

    return results.map(function (resource) {
      var bbox = resource.bbox;
      var south = bbox[0];
      var west = bbox[1];
      var north = bbox[2];
      var east = bbox[3];
      return {
        displayName: resource.name,
        destination: Rectangle.fromDegrees(west, south, east, north),
      };
    });
  });
};
export default BingMapsGeocoderService;
<commit_msg>fix @link spacing<commit_after>import Check from "./Check.js";
import defaultValue from "./defaultValue.js";
import Rectangle from "./Rectangle.js";
import Resource from "./Resource.js";
import defined from "./defined.js";
import DeveloperError from "./DeveloperError.js";

var url = "https://dev.virtualearth.net/REST/v1/Locations";

/**
 * Provides geocoding through Bing Maps.
 * @alias BingMapsGeocoderService
 * @constructor
 *
 * @param {Object} options Object with the following properties:
 * @param {String} options.key A key to use with the Bing Maps geocoding service
 * @param {String} [options.culture] A Bing Maps {@link https://docs.microsoft.com/en-us/bingmaps/rest-services/common-parameters-and-types/supported-culture-codes|Culture Code} to return results in a specific culture and language.
 */
function BingMapsGeocoderService(options) {
  options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  var key = options.key;
  //>>includeStart('debug', pragmas.debug);
  if (!defined(key)) {
    throw new DeveloperError("options.key is required.");
  }
  //>>includeEnd('debug');

  this._key = key;

  var queryParameters = {
    key: key,
  };

  if (defined(options.culture)) {
    queryParameters.culture = options.culture;
  }

  this._resource = new Resource({
    url: url,
    queryParameters: queryParameters,
  });
}

Object.defineProperties(BingMapsGeocoderService.prototype, {
  /**
   * The URL endpoint for the Bing geocoder service
   * @type {String}
   * @memberof BingMapsGeocoderService.prototype
   * @readonly
   */
  url: {
    get: function () {
      return url;
    },
  },

  /**
   * The key for the Bing geocoder service
   * @type {String}
   * @memberof BingMapsGeocoderService.prototype
   * @readonly
   */
  key: {
    get: function () {
      return this._key;
    },
  },
});

/**
 * @function
 *
 * @param {String} query The query to be sent to the geocoder service
 * @returns {Promise<GeocoderService.Result[]>}
 */
BingMapsGeocoderService.prototype.geocode = function (query) {
  //>>includeStart('debug', pragmas.debug);
  Check.typeOf.string("query", query);
  //>>includeEnd('debug');

  var resource = this._resource.getDerivedResource({
    queryParameters: {
      query: query,
    },
  });

  return resource.fetchJsonp("jsonp").then(function (result) {
    if (result.resourceSets.length === 0) {
      return [];
    }

    var results = result.resourceSets[0].resources;

    return results.map(function (resource) {
      var bbox = resource.bbox;
      var south = bbox[0];
      var west = bbox[1];
      var north = bbox[2];
      var east = bbox[3];
      return {
        displayName: resource.name,
        destination: Rectangle.fromDegrees(west, south, east, north),
      };
    });
  });
};
export default BingMapsGeocoderService;
<|endoftext|>


<commit_before>import EditorToolBar from './EditorToolBar.js';
import TabbedEditors from './TabbedEditors.js';

//
// EditorPane component
//
class EditorPane extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      repository: null,
      branch: null,
      tree: null,
      recursiveTree: null,
      changedFiles: [],
      addedFiles: [],
      filesOpened: [],
      fileActive: null
    };

    this.handleGenerateClick = this.handleGenerateClick.bind(this);
    this._addFileToRecursiveTree = this._addFileToRecursiveTree.bind(this);
  }

  _addFileToRecursiveTree(recursiveTree, newFile, folders) {
    if(folders.length == 1) {
      // This is the location where we add the file
      // Duplicate Check
      //   Just remove potentially existing duplicate
      //   and just push the new file.
      _.remove(recursiveTree.nodes, function(file) {
        // console.log(file.path, newFile.path);
        return file.path == newFile.path;
      });

      // TODO: Add a leading '/'?
      recursiveTree.nodes.push(newFile);
    }
    else {
      // We should go deeper
      let folderName = folders.shift();
      // Duplicate check
      let targetFolder = _.find(recursiveTree.nodes, {name: folderName, type: 'tree'});
      if(targetFolder) {
        // The target path exists
        this._addFileToRecursiveTree(targetFolder, newFile, folders);
      }
      else {
        // Create a subfolder
        let subdirs = '/' + folders.join('/');
        let path  = '/' + newFile.path.replace(subdirs, '');
        // Create a folder
        let newFolder = {
          name: folderName,
          nodes: [],
          path: path,
          type: 'tree',
          mode: '040000'
        };

        recursiveTree.nodes.push(newFolder);
        this._addFileToRecursiveTree(newFolder, newFile, folders);
      }
    }
  }

  handleGenerateClick() {
    // POST request for Hexo initialization
    let url = '/api/project/generate';
    let self = this;
    let tree = this.state.tree;
    let recursiveTree = this.state.recursiveTree;
    let app = this.props.app;

    $.ajax({
      url: url,
      method: 'POST',
      headers: { 'X-CSRFToken': window.glide.csrfToken },
      dataType: 'json',
      data: JSON.stringify({
        addedFiles: this.state.addedFiles,
        changedFiles: this.state.changedFiles,
        repository: this.state.repository.full_name,
        branch: this.state.branch.name
      }),
      contentType: 'application/json; charset=utf-8',
      success: function(response) {
        console.log(response);
        if('error' in response) {
          // TODO
        }
        else {
          // Create the new file objects created on the server
          let createdFiles = response.createdFiles;
          let addedFiles = app.state.addedFiles;

          _.forEach(createdFiles, function(createdFile) {
            // To match encoding / decoding scheme to blobs through GitHub API
            createdFile.originalContent = atob(createdFile.originalContent);
            // Update the tree
            //   Duplicate check:
            //   Just remove potentially existing duplicate
            //   and just push the new file.
            _.remove(tree.tree, function(file) {
              return file.path == createdFile.path;
            });
            tree.tree.push(createdFile);

            // Push the file into recursiveTree
            let folders = createdFile.path.split('/');
            self._addFileToRecursiveTree(recursiveTree, createdFile, folders);

            // Update addedFiles
            //   Duplicate check:
            //   Just remove potentially existing duplicate
            //   and just push the new file.
            _.remove(addedFiles, function(file) {
              return file.path == createdFile.path;
            });
            addedFiles.push(createdFile);
          });

          self.setState({
            recursiveTree: recursiveTree,
            tree: tree
          }, function() {
            app.setState({
              recursiveTree: recursiveTree,
              tree: tree,
              addedFiles: addedFiles
            });
          });
        }
      }
    });
  }

  componentDidMount() {
    this.setState({
      repository: this.props.repository,
      branch: this.props.branch,
      tree: this.props.tree,
      recursiveTree: this.props.recursiveTree,
      changedFiles: this.props.changedFiles,
      addedFiles: this.props.addedFiles,
      filesOpened: this.props.filesOpened,
      fileActive: this.props.fileActive
    });
  }

  componentWillReceiveProps(nextProps) {
    this.setState({
      repository: nextProps.repository,
      branch: nextProps.branch,
      tree: nextProps.tree,
      recursiveTree: nextProps.recursiveTree,
      changedFiles: nextProps.changedFiles,
      addedFiles: nextProps.addedFiles,
      filesOpened: nextProps.filesOpened,
      fileActive: nextProps.fileActive
    });
  }

  render () {
    return (

Editor

            <button
              style={{paddingTop: 0, paddingBottom: 0, marginTop: 3}}
              className="btn btn-outline-success btn-sm inline-block float-right"
              onClick={this.handleGenerateClick} type="button" >
              Generate & Render
            </button>

          <TabbedEditors
            app={this.props.app}
            repository={this.state.repository}
            branch={this.state.branch}
            tree={this.props.tree}
            recursiveTree={this.props.recursiveTree}
            changedFiles={this.state.changedFiles}
            addedFiles={this.state.addedFiles}
            filesOpened={this.state.filesOpened}
            fileActive={this.state.fileActive} />

    );
  }
}

export default EditorPane;
<commit_msg>adds loading pane in running hexo generate<commit_after>import EditorToolBar from './EditorToolBar.js';
import TabbedEditors from './TabbedEditors.js';

//
// EditorPane component
//
class EditorPane extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      repository: null,
      branch: null,
      tree: null,
      recursiveTree: null,
      changedFiles: [],
      addedFiles: [],
      filesOpened: [],
      fileActive: null
    };

    this._addFileToRecursiveTree = this._addFileToRecursiveTree.bind(this);
    this._pushLoadingMsg = this._pushLoadingMsg.bind(this);
    this._popLoadingMsg = this._popLoadingMsg.bind(this);
    this.handleGenerateClick = this.handleGenerateClick.bind(this);
  }

  _addFileToRecursiveTree(recursiveTree, newFile, folders) {
    if(folders.length == 1) {
      // This is the location where we add the file
      // Duplicate Check
      //   Just remove potentially existing duplicate
      //   and just push the new file.
      _.remove(recursiveTree.nodes, function(file) {
        // console.log(file.path, newFile.path);
        return file.path == newFile.path;
      });

      // TODO: Add a leading '/'?
      recursiveTree.nodes.push(newFile);
    }
    else {
      // We should go deeper
      let folderName = folders.shift();
      // Duplicate check
      let targetFolder = _.find(recursiveTree.nodes, {name: folderName, type: 'tree'});
      if(targetFolder) {
        // The target path exists
        this._addFileToRecursiveTree(targetFolder, newFile, folders);
      }
      else {
        // Create a subfolder
        let subdirs = '/' + folders.join('/');
        let path  = '/' + newFile.path.replace(subdirs, '');
        // Create a folder
        let newFolder = {
          name: folderName,
          nodes: [],
          path: path,
          type: 'tree',
          mode: '040000'
        };

        recursiveTree.nodes.push(newFolder);
        this._addFileToRecursiveTree(newFolder, newFile, folders);
      }
    }
  }

  _pushLoadingMsg(msg) {
    let app = this.props.app;
    let messageKey =  Date.now().toString();
    let message = {};
    message[messageKey] = msg;
    let loadingMessages = _.merge(app.state.loadingMessages, message);
    app.setState({
      loadingMessages: loadingMessages
    });

    return messageKey;
  }

  _popLoadingMsg(msgKey) {
    let app = this.props.app;
    let loadingMessages = app.state.loadingMessages;
    delete loadingMessages[msgKey]
    app.setState({
      loadingMessages: loadingMessages
    });
  }

  handleGenerateClick() {
    // POST request for Hexo initialization
    let url = '/api/project/generate';
    let self = this;
    let tree = this.state.tree;
    let recursiveTree = this.state.recursiveTree;
    let app = this.props.app;
    let loadingMsgHandle = this._pushLoadingMsg('Generating website resources in docs folder.');

    $.ajax({
      url: url,
      method: 'POST',
      headers: { 'X-CSRFToken': window.glide.csrfToken },
      dataType: 'json',
      data: JSON.stringify({
        addedFiles: this.state.addedFiles,
        changedFiles: this.state.changedFiles,
        repository: this.state.repository.full_name,
        branch: this.state.branch.name
      }),
      contentType: 'application/json; charset=utf-8',
      success: function(response) {
        console.log(response);
        if('error' in response) {
          // TODO
        }
        else {
          // Create the new file objects created on the server
          let createdFiles = response.createdFiles;
          let addedFiles = app.state.addedFiles;

          _.forEach(createdFiles, function(createdFile) {
            // To match encoding / decoding scheme to blobs through GitHub API
            createdFile.originalContent = atob(createdFile.originalContent);
            // Update the tree
            //   Duplicate check:
            //   Just remove potentially existing duplicate
            //   and just push the new file.
            _.remove(tree.tree, function(file) {
              return file.path == createdFile.path;
            });
            tree.tree.push(createdFile);

            // Push the file into recursiveTree
            let folders = createdFile.path.split('/');
            self._addFileToRecursiveTree(recursiveTree, createdFile, folders);

            // Update addedFiles
            //   Duplicate check:
            //   Just remove potentially existing duplicate
            //   and just push the new file.
            _.remove(addedFiles, function(file) {
              return file.path == createdFile.path;
            });
            addedFiles.push(createdFile);
          });

          self.setState({
            recursiveTree: recursiveTree,
            tree: tree
          }, function() {
            app.setState({
              recursiveTree: recursiveTree,
              tree: tree,
              addedFiles: addedFiles
            }, function() {
              self._popLoadingMsg(loadingMsgHandle);
            });
          });
        }
      }
    });
  }

  componentDidMount() {
    this.setState({
      repository: this.props.repository,
      branch: this.props.branch,
      tree: this.props.tree,
      recursiveTree: this.props.recursiveTree,
      changedFiles: this.props.changedFiles,
      addedFiles: this.props.addedFiles,
      filesOpened: this.props.filesOpened,
      fileActive: this.props.fileActive
    });
  }

  componentWillReceiveProps(nextProps) {
    this.setState({
      repository: nextProps.repository,
      branch: nextProps.branch,
      tree: nextProps.tree,
      recursiveTree: nextProps.recursiveTree,
      changedFiles: nextProps.changedFiles,
      addedFiles: nextProps.addedFiles,
      filesOpened: nextProps.filesOpened,
      fileActive: nextProps.fileActive
    });
  }

  render () {
    return (

Editor

            <button
              style={{paddingTop: 0, paddingBottom: 0, marginTop: 3}}
              className="btn btn-outline-success btn-sm inline-block float-right"
              onClick={this.handleGenerateClick} type="button" >
              Generate & Render
            </button>

          <TabbedEditors
            app={this.props.app}
            repository={this.state.repository}
            branch={this.state.branch}
            tree={this.props.tree}
            recursiveTree={this.props.recursiveTree}
            changedFiles={this.state.changedFiles}
            addedFiles={this.state.addedFiles}
            filesOpened={this.state.filesOpened}
            fileActive={this.state.fileActive} />

    );
  }
}

export default EditorPane;
<|endoftext|>


<commit_before>enyo.kind({
	name: "moon.sample.CalendarSample",
	classes: "moon enyo-unselectable enyo-fit",
	kind: "FittableColumns",
	components: [
		{components: [
			{kind: "moon.Calendar", name: "calendar", onChange: "changed"}
		]},
		{kind: "FittableRows", fit: true, components: [
			{kind: "moon.Scroller", fit:true, components: [
				{kind:"moon.Divider", content:"Set value:"},
				{classes:"moon-hspacing", components: [
					{kind: "moon.InputDecorator", components: [
						{kind: "moon.Input", name:"input", value:"Jan 01 2013 11:22:59"}
					]},
					{kind: "moon.Button", small:true, content:"Set Date", ontap:"setDate"},
					{kind: "moon.Button", small:true, content:"Reset to Current", ontap:"resetDate"}
				]},
				{classes:"moon-1v"},
				{classes:"moon-7h", components: [
					{kind: "moon.DatePicker", name: "picker", noneText: "Pick a Date", content: "Pick a Date"},
					{kind: "moon.ExpandablePicker", name:"localePicker", noneText: "No Language Selected", content: "Choose Locale", onChange: "setLocale", components: [
						{content: "en-US", active:true}, //United States, firstDayOfWeek: 1
						{content: "th-TH"},	//Thailand
						{content: "en-CA"},	//Canada, firstDayOfWeek: 1
						{content: "ko-KO"}, //Korea, firstDayOfWeek: 0
						{content: "und-AE"}, //United Arab Emirates, firstDayOfWeek: 6
						{content: "und-AG"}, //Antigua and Barbuda, firstDayOfWeek: 0
						{content: "und-CA"},//Canada, firstDayOfWeek: 0
						{content: "it-CH"},	//Italian
						{content: "en-MX"},
						{content: "de-DE"},
						{content: "fr-FR"},
						{content: "fr-CA"},
						{content: "it-IT"},
						{content: "es-ES"},
						{content: "es-MX"}
					]},
					{kind: "moon.ExpandablePicker", name:"dowLengthPicker", content: "Choose DOW Label Length", onChange: "setLabelLength", components: [
						{content: "short", active: true},
						{content: "medium"},
						{content: "long"},
						{content: "full"}
					]},
					{kind: "moon.ExpandablePicker", content: "Choose DOW Label Class", onChange: "setLabelStyle", components: [
						{content: "Default", active: true, className:""},
						{content: "Divider", className:"moon-divider moon-divider-text"},
						{content: "Smaller font", className: "moon-calendar-picker-day small"}
					]}
				]}
			]},
			{kind: "moon.Divider", content: "Result"},
			{kind: "moon.BodyText", name: "result", content: "No change yet"}
		]}
	],
	bindings: [
		{from: ".$.calendar.value", to:".$.picker.value", oneWay:false},
		{from: ".$.calendar.value", to:".$.input.value", transform: function(val) {return val.toDateString();} }
	],
	create: function(){
		this.inherited(arguments);
		if (!window.ilib) {
			this.$.localePicker.hide();
			this.$.dowLengthPicker.hide();
			this.log("iLib not present -- hiding locale & dow length picker");
		}
	},
	setLocale: function(inSender, inEvent){
		if (ilib) {
			this.$.calendar.setLocale(inEvent.selected.content);
		}
		return true;
	},
	setLabelLength: function(inSender, inEvent){
		if (inEvent.content){
			this.$.calendar.setDayOfWeekLength(inEvent.content);
			this.removeLabelItem(this.$.dowLabelClass, inEvent, 'Divider', 'full');
		}
		return true;
	},
	setLabelStyle: function(inSender, inEvent){
		if (inEvent.content){
			this.$.calendar.setDayOfWeekClasses(inEvent.selected.className);
			this.removeLabelItem(this.$.dowLengthPicker, inEvent, 'full', 'Divider');
		}
		return true;
	},
	removeLabelItem: function (inControl, inEvent, inLabelName1, inLabelName2) {
		var i,
			c = inControl.getClientControls();
			for (i=0; i<c.length; i++) {
				if (c[i].content == inLabelName1) {
					c[i].addRemoveClass("moon-calendar-dow-lable-nodisplay", Boolean(inEvent.content == inLabelName2));
				}
			}
	},
	changed: function(inSender, inEvent) {
		if (this.$.result && inEvent.value){
			this.$.result.setContent("Current Date" + " changed to " + inEvent.value.toDateString());
		}
	},
	setDate: function(inSender, inEvent){
		this.$.calendar.setValue(new Date(this.$.input.getValue()));
	},
	resetDate: function() {
		this.$.calendar.setValue(null);
	}
});<commit_msg>GF-63361 Fix CalendarSample<commit_after>enyo.kind({
	name: "moon.sample.CalendarSample",
	classes: "moon enyo-unselectable enyo-fit",
	kind: "FittableColumns",
	components: [
		{components: [
			{kind: "moon.Calendar", name: "calendar", onChange: "changed"}
		]},
		{kind: "FittableRows", fit: true, components: [
			{kind: "moon.Scroller", fit:true, components: [
				{kind:"moon.Divider", content:"Set value:"},
				{classes:"moon-hspacing", components: [
					{kind: "moon.InputDecorator", components: [
						{kind: "moon.Input", name:"input", value:"Jan 01 2013 11:22:59"}
					]},
					{kind: "moon.Button", small:true, content:"Set Date", ontap:"setDate"},
					{kind: "moon.Button", small:true, content:"Reset to Current", ontap:"resetDate"}
				]},
				{classes:"moon-1v"},
				{classes:"moon-7h", components: [
					{kind: "moon.DatePicker", name: "picker", noneText: "Pick a Date", content: "Pick a Date"},
					{kind: "moon.ExpandablePicker", name:"localePicker", noneText: "No Language Selected", content: "Choose Locale", onChange: "setLocale", components: [
						{content: "en-US", active:true}, //United States, firstDayOfWeek: 0
						{content: "th-TH"},	//Thailand
						{content: "en-CA"},	//Canada, firstDayOfWeek: 0
						{content: "ko-KO"}, //Korea, firstDayOfWeek: 1
						{content: "und-AE"}, //United Arab Emirates, firstDayOfWeek: 6
						{content: "und-AG"}, //Antigua and Barbuda, firstDayOfWeek: 0
						{content: "und-CA"},//Canada, firstDayOfWeek: 0
						{content: "it-CH"},	//Italian
						{content: "en-MX"},
						{content: "de-DE"},
						{content: "fr-FR"},
						{content: "fr-CA"},
						{content: "it-IT"},
						{content: "es-ES"},
						{content: "es-MX"}
					]},
					{kind: "moon.ExpandablePicker", name:"dowLengthPicker", content: "Choose DOW Label Length", onChange: "setLabelLength", components: [
						{content: "short", active: true},
						{content: "medium"},
						{content: "long"},
						{content: "full"}
					]},
					{kind: "moon.ExpandablePicker", content: "Choose DOW Label Class", onChange: "setLabelStyle", components: [
						{content: "Default", active: true, className:""},
						{content: "Divider", className:"moon-divider moon-divider-text"},
						{content: "Smaller font", className: "moon-calendar-picker-day small"}
					]}
				]}
			]},
			{kind: "moon.Divider", content: "Result"},
			{kind: "moon.BodyText", name: "result", content: "No change yet"}
		]}
	],
	bindings: [
		{from: ".$.calendar.value", to:".$.picker.value", oneWay:false},
		{from: ".$.calendar.value", to:".$.input.value", transform: function(val) {return val.toDateString();} }
	],
	create: function(){
		this.inherited(arguments);
		if (!window.ilib) {
			this.$.localePicker.hide();
			this.$.dowLengthPicker.hide();
			this.log("iLib not present -- hiding locale & dow length picker");
		}
	},
	setLocale: function(inSender, inEvent){
		if (ilib) {
			this.$.calendar.setLocale(inEvent.selected.content);
		}
		return true;
	},
	setLabelLength: function(inSender, inEvent){
		if (inEvent.content){
			this.$.calendar.setDayOfWeekLength(inEvent.content);
			this.removeLabelItem(this.$.dowLabelClass, inEvent, 'Divider', 'full');
		}
		return true;
	},
	setLabelStyle: function(inSender, inEvent){
		if (inEvent.content){
			this.$.calendar.setDayOfWeekClasses(inEvent.selected.className);
			this.removeLabelItem(this.$.dowLengthPicker, inEvent, 'full', 'Divider');
		}
		return true;
	},
	removeLabelItem: function (inControl, inEvent, inLabelName1, inLabelName2) {
		var i,
			c = inControl.getClientControls();
		for (i = 0; i < c.length; i++) {
			if (c[i].content == inLabelName1) {
				c[i].addRemoveClass("moon-calendar-dow-lable-nodisplay", Boolean(inEvent.content == inLabelName2));
			}
		}
	},
	changed: function(inSender, inEvent) {
		if (this.$.result && inEvent.value){
			this.$.result.setContent("Current Date" + " changed to " + inEvent.value.toDateString());
		}
	},
	setDate: function(inSender, inEvent){
		this.$.calendar.setValue(new Date(this.$.input.getValue()));
	},
	resetDate: function() {
		this.$.calendar.setValue(null);
	}
});<|endoftext|>


<commit_before>/**
 * Copyright 2015 Mozilla
 *
 * 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.
 */

'use strict';

// Import this first so we can use it to wrap other modules we import.
var promisify = require('promisify-node');

var fs = require('fs');
var path = require('path');
var swPrecache = require('sw-precache');
var gutil = require('gulp-util');
var ghslug = promisify(require('github-slug'));
var glob = require('glob');

module.exports = promisify(function(config, callback) {
  var rootDir = config.rootDir || './';

  // Ensure root directory ends with slash so we strip leading slash from paths
  // of files to cache, so they're relative paths, and the offline worker
  // will match them regardless of whether the app is deployed to a top-level
  // directory for a custom domain (f.e. https://example.com/) or a subdirectory
  // of a GitHub Pages domain (f.e. https://mykmelez.github.io/example/).
  if (rootDir.lastIndexOf('/') !== rootDir.length -1) {
    rootDir = rootDir + "/";
  }

  var fileGlobs = config.fileGlobs || ['**/*'];

  // Remove the existing service worker, if any, so sw-precache doesn't include
  // it in the list of files to cache.
  try {
    fs.unlinkSync(path.join(rootDir, 'offline-worker.js'));
  } catch (ex) {
    // Only ignore the error if it's a 'file not found' error.
    if (!ex.code || ex.code !== 'ENOENT') {
      throw ex;
    }
  }

  ghslug('./').catch(function() {
    // Use the name from package.json if there's an error while fetching the GitHub slug.
    try {
      return JSON.parse(fs.readFileSync('package.json')).name;
    } catch (ex) {
      return '';
    }
  }).then(function(cacheId) {
    var staticFileGlobs = fileGlobs.map(function(v) {
      return path.join(rootDir, v)
    });

    staticFileGlobs.forEach(function(globPattern) {
      glob.sync(globPattern.replace(path.sep, '/')).forEach(function(file) {
        var stat = fs.statSync(file);

        if (stat.isFile() && stat.size > 2 * 1024 * 1024) {
          gutil.log(gutil.colors.red.bold(file + ' is bigger than 2 MiB. Are you sure you want to cache it?'));
        }
      });
    });

    swPrecache.write(path.join(rootDir, 'offline-worker.js'), {
      staticFileGlobs: staticFileGlobs,
      stripPrefix: rootDir,
      verbose: true,
      logger: gutil.log,
      importScripts: config.importScripts || [],
      cacheId: cacheId,
      ignoreUrlParametersMatching: config.ignoreUrlParametersMatching || [/./],
      maximumFileSizeToCacheInBytes: Infinity,
    }, callback);
  });
});
<commit_msg>Don't warn about explicitely included files<commit_after>/**
 * Copyright 2015 Mozilla
 *
 * 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.
 */

'use strict';

// Import this first so we can use it to wrap other modules we import.
var promisify = require('promisify-node');

var fs = require('fs');
var path = require('path');
var swPrecache = require('sw-precache');
var gutil = require('gulp-util');
var ghslug = promisify(require('github-slug'));
var glob = require('glob');

module.exports = promisify(function(config, callback) {
  var rootDir = config.rootDir || './';

  // Ensure root directory ends with slash so we strip leading slash from paths
  // of files to cache, so they're relative paths, and the offline worker
  // will match them regardless of whether the app is deployed to a top-level
  // directory for a custom domain (f.e. https://example.com/) or a subdirectory
  // of a GitHub Pages domain (f.e. https://mykmelez.github.io/example/).
  if (rootDir.lastIndexOf('/') !== rootDir.length -1) {
    rootDir = rootDir + "/";
  }

  var fileGlobs = config.fileGlobs || ['**/*'];

  // Remove the existing service worker, if any, so sw-precache doesn't include
  // it in the list of files to cache.
  try {
    fs.unlinkSync(path.join(rootDir, 'offline-worker.js'));
  } catch (ex) {
    // Only ignore the error if it's a 'file not found' error.
    if (!ex.code || ex.code !== 'ENOENT') {
      throw ex;
    }
  }

  ghslug('./').catch(function() {
    // Use the name from package.json if there's an error while fetching the GitHub slug.
    try {
      return JSON.parse(fs.readFileSync('package.json')).name;
    } catch (ex) {
      return '';
    }
  }).then(function(cacheId) {
    var staticFileGlobs = fileGlobs.map(function(v) {
      return path.join(rootDir, v)
    });

    staticFileGlobs.forEach(function(globPattern) {
      glob.sync(globPattern.replace(path.sep, '/')).forEach(function(file) {
        var stat = fs.statSync(file);

        if (stat.isFile() && stat.size > 2 * 1024 * 1024 && staticFileGlobs.indexOf(file) === -1) {
          gutil.log(gutil.colors.red.bold(file + ' is bigger than 2 MiB. Are you sure you want to cache it?'));
        }
      });
    });

    swPrecache.write(path.join(rootDir, 'offline-worker.js'), {
      staticFileGlobs: staticFileGlobs,
      stripPrefix: rootDir,
      verbose: true,
      logger: gutil.log,
      importScripts: config.importScripts || [],
      cacheId: cacheId,
      ignoreUrlParametersMatching: config.ignoreUrlParametersMatching || [/./],
      maximumFileSizeToCacheInBytes: Infinity,
    }, callback);
  });
});
<|endoftext|>


<commit_before>(function($){
    $.fn.app.comment = function(method) {

        var sandbox,
            comments_count_for_post = Constants.comments_count_for_post;

        var methods = {
            init: function(options) {
                sandbox = $.extend(true, {}, this.app.comment.defaults, options);
                return this.each(function() {
                    var $this = $(this);
                    helpers.initComments($this);
                    helpers.initSendForm($this);
                    helpers.initShowAllComments($this);
                });
            }
        };

        var helpers = {
            initComments: function() {
                $(document).on('focus', '.write-comment', function() {
                    $(this).addClass('focus');

                    setTimeout( function() {

                        reloadMasonry(300);

                    }, 200 );
                }).on("blur", '.write-comment', function() {

                        var $this = $(this);
                        setTimeout( function() {
                            $this.removeClass('focus');

                            reloadMasonry(500);

                        }, 500 );

                });
            },
            initSendForm: function(document) {
                $(document).on('click', '.comment-now-btn', function(e) {
                        helpers.sendData(this,e);
                    }
                );
            },
            sendData: function(button, e){
                //Посылаем асинхронный запрос на сервер, и получаем блок поста
                var $form = $(button).closest('form');
                var text = $form.find('textarea').val();
                var commentsContainer = $form.parent('.ribbon-comments');

                if (text.length > 0) {

                    var options = {
//                        target: '.main-ribbon.clearfix',   // target element(s) to be updated with server response
                        beforeSubmit:  showAjaxAnimation,  // pre-submit callback
                        complete: hideAjaxAnimation,
                        success: function(response, status) {
                            if (status == "success" && response.view) {
                                commentsContainer.html(response.view);
                                $('.scroll-pane').jScrollPane({
                                    mouseWheelSpeed: 60
                                });
                                initCustomCheckRadio();
                            }
                        }
                    };

                    e.preventDefault();
                    $form.sendForm(options);
                } else {
                    alert('Сообщение не может быть пустым');
                }
                return false;
            },
            initShowAllComments: function(document) {
                var active_text = "Скрыть комментарии",
                    plain_text = "Показать все комментарии";

                $(document).on('click', '.show-all-comments', function(){
                    // меняем текст
                    var $el_text = $(this).find('span');
                    var $that = $(this);

                    if ($(this).hasClass('active')) {
                        // Скрываем
                        $el_text.html(plain_text).stop(true,true).hide().fadeIn();
                        $(this).removeClass('active');

                        var container = $that.siblings('.all-comments');
                        var len = container.find(".comment").length;
                        $(".comment:lt(" + (len - comments_count_for_post) + ")", container).remove();

                        $that.siblings('.scroll-pane').html($that.siblings('.scroll-pane').find('.jspPane').html()).jScrollPane({
                            mouseWheelSpeed: 60
                        });
                    }
                    else {
                        // Показываем
                        $el_text.html(active_text).stop(true,true).hide().fadeIn();
                        $(this).addClass('active');
                        var postId = $(this).data('postId');

                        $.sendPost({
                            url: Routing.showAllComments,
                            data: { postId: postId },
                            success: function(response, status) {
                                if (status == "success") {
                                    if (response.view) {
                                        $that.siblings('.all-comments').replaceWith(response.view);
                                        $that.siblings('.scroll-pane').jScrollPane({
                                            mouseWheelSpeed: 60
                                        });
                                    }
                                }
                            }
                        })
                    }

                    reloadMasonry();
                });

                $(document).on('click', '.toggle-all-comments', function(){
                    $(this).toggleClass('active');

                    // меняем текст
                    var $el_text = $(this).find('span');

                    if ($(this).hasClass('active')) {
                        $el_text.html(active_text).stop(true,true).hide().fadeIn();
                    }
                    else {
                        $el_text.html(plain_text).stop(true,true).hide().fadeIn();
                    }

                    // показываем/скрываем все комментарии
                    $(this).next('.all-comments.scroll-pane').stop(true,true).toggle(500);
                    reloadMasonry();
                });
            }
        };

        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        }
        else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        }
        else {
            $.error('Method ' +  method + ' does not exist in app.comment plugin.');
        }
    };

    $.fn.app.comment.defaults = {
    };
})(jQuery);

var app = app || {};

$(document).ready(function() {
    if (typeof app.comment === 'undefined') {
        $('body').app('comment', app.comment);
    }
});
<commit_msg>Исправление переключения вида при комментировании<commit_after>(function($){
    $.fn.app.comment = function(method) {

        var sandbox,
            comments_count_for_post = Constants.comments_count_for_post;

        var methods = {
            init: function(options) {
                sandbox = $.extend(true, {}, this.app.comment.defaults, options);
                return this.each(function() {
                    var $this = $(this);
                    helpers.initComments($this);
                    helpers.initSendForm($this);
                    helpers.initShowAllComments($this);
                });
            }
        };

        var helpers = {
            initComments: function() {
                $(document).on('focus', '.write-comment', function() {
                    $(this).addClass('focus');

                    setTimeout( function() {

                        //reloadMasonry(300);

                    }, 200 );
                }).on("blur", '.write-comment', function() {

                        var $this = $(this);
                        setTimeout( function() {
                            $this.removeClass('focus');

                            reloadMasonry(500);

                        }, 500 );

                });
            },
            initSendForm: function(document) {
                $(document).on('click', '.comment-now-btn', function(e) {
                        helpers.sendData(this,e);
                    }
                );
            },
            sendData: function(button, e){
                //Посылаем асинхронный запрос на сервер, и получаем блок поста
                var $form = $(button).closest('form');
                var text = $form.find('textarea').val();
                var commentsContainer = $form.parent('.ribbon-comments');

                if (text.length > 0) {

                    var options = {
//                        target: '.main-ribbon.clearfix',   // target element(s) to be updated with server response
                        beforeSubmit:  showAjaxAnimation,  // pre-submit callback
                        complete: hideAjaxAnimation,
                        success: function(response, status) {
                            if (status == "success" && response.view) {
                                commentsContainer.html(response.view);
                                $('.scroll-pane').jScrollPane({
                                    mouseWheelSpeed: 60
                                });
                                initCustomCheckRadio();
                            }
                        }
                    };

                    e.preventDefault();
                    $form.sendForm(options);
                } else {
                    alert('Сообщение не может быть пустым');
                }
                return false;
            },
            initShowAllComments: function(document) {
                var active_text = "Скрыть комментарии",
                    plain_text = "Показать все комментарии";

                $(document).on('click', '.show-all-comments', function(){
                    // меняем текст
                    var $el_text = $(this).find('span');
                    var $that = $(this);

                    if ($(this).hasClass('active')) {
                        // Скрываем
                        $el_text.html(plain_text).stop(true,true).hide().fadeIn();
                        $(this).removeClass('active');

                        var container = $that.siblings('.all-comments');
                        var len = container.find(".comment").length;
                        $(".comment:lt(" + (len - comments_count_for_post) + ")", container).remove();

                        $that.siblings('.scroll-pane').html($that.siblings('.scroll-pane').find('.jspPane').html()).jScrollPane({
                            mouseWheelSpeed: 60
                        });
                    }
                    else {
                        // Показываем
                        $el_text.html(active_text).stop(true,true).hide().fadeIn();
                        $(this).addClass('active');
                        var postId = $(this).data('postId');

                        $.sendPost({
                            url: Routing.showAllComments,
                            data: { postId: postId },
                            success: function(response, status) {
                                if (status == "success") {
                                    if (response.view) {
                                        $that.siblings('.all-comments').replaceWith(response.view);
                                        $that.siblings('.scroll-pane').jScrollPane({
                                            mouseWheelSpeed: 60
                                        });
                                    }
                                }
                            }
                        })
                    }

                    reloadMasonry();
                });

                $(document).on('click', '.toggle-all-comments', function(){
                    $(this).toggleClass('active');

                    // меняем текст
                    var $el_text = $(this).find('span');

                    if ($(this).hasClass('active')) {
                        $el_text.html(active_text).stop(true,true).hide().fadeIn();
                    }
                    else {
                        $el_text.html(plain_text).stop(true,true).hide().fadeIn();
                    }

                    // показываем/скрываем все комментарии
                    $(this).next('.all-comments.scroll-pane').stop(true,true).toggle(500);
                    reloadMasonry();
                });
            }
        };

        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        }
        else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        }
        else {
            $.error('Method ' +  method + ' does not exist in app.comment plugin.');
        }
    };

    $.fn.app.comment.defaults = {
    };
})(jQuery);

var app = app || {};

$(document).ready(function() {
    if (typeof app.comment === 'undefined') {
        $('body').app('comment', app.comment);
    }
});
<|endoftext|>


<commit_before>/** @jsx React.DOM */

define(
  [
    'react'
  ],
  function (React) {

    var resources = [
      {
        title: "User Manual",
        href: "https://pods.iplantcollaborative.org/wiki/x/Iaxm",
        description: "Complete documentation for using Atmosphere"
      },
      {
        title: "User Forums",
        href: "http://ask.iplantcollaborative.org",
        description: "Get answers from iPlant users and staff"
      },
      {
        title: "FAQs",
        href: "https://pods.iplantcollaborative.org/wiki/display/atmman/Atmosphere+FAQs",
        description: "Atmosphere's most frequently asked questions"
      },
      {
        title: "VNC Viewer Tutorial",
        href: "https://pods.iplantcollaborative.org/wiki/display/atmman/Using+VNC+Viewer+to+Connect+to+an+Atmosphere+VM",
        description: "Instructions for downloading and using VNC Viewer"
      }
    ];

    return React.createClass({

      render: function () {

        var resourceElements = _.map(resources, function (resource) {
          return (

              {resource.title}
              {" " + resource.description}

          );
        });

        return (

External resources

              {resourceElements}

Contact

                {"You can contact the Atmosphere support staff by sending an email to "}
                support@iplantcollaborative.org

        );
      }
    });

  });
<commit_msg>Mention the feedback button on the help page<commit_after>/** @jsx React.DOM */

define(
  [
    'react'
  ],
  function (React) {

    var resources = [
      {
        title: "User Manual",
        href: "https://pods.iplantcollaborative.org/wiki/x/Iaxm",
        description: "Complete documentation for using Atmosphere"
      },
      {
        title: "User Forums",
        href: "http://ask.iplantcollaborative.org",
        description: "Get answers from iPlant users and staff"
      },
      {
        title: "FAQs",
        href: "https://pods.iplantcollaborative.org/wiki/display/atmman/Atmosphere+FAQs",
        description: "Atmosphere's most frequently asked questions"
      },
      {
        title: "VNC Viewer Tutorial",
        href: "https://pods.iplantcollaborative.org/wiki/display/atmman/Using+VNC+Viewer+to+Connect+to+an+Atmosphere+VM",
        description: "Instructions for downloading and using VNC Viewer"
      }
    ];

    return React.createClass({

      render: function () {

        var resourceElements = _.map(resources, function (resource) {
          return (

              {resource.title}
              {" " + resource.description}

          );
        });

        return (

External resources

              {resourceElements}

Contact

                {"You can contact the Atmosphere support staff by clicking on the "}
                {"Feedback & Support"}
                {" button at the bottom of the page to enter a help request online."}

                {"Alternatively, you can also contact the support staff by sending an email to "}
                support@iplantcollaborative.org

        );
      }
    });

  });
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var allocCluster = require('./lib/alloc-cluster.js');

allocCluster.test('request() with zero timeout', {
    numPeers: 2
}, function t(cluster, assert) {
    cluster.logger.whitelist('info', 'resetting connection');

    var one = cluster.channels[0];
    var two = cluster.channels[1];

    var subTwo = two.makeSubChannel({
        serviceName: 'server'
    });

    subTwo.waitForIdentified({
        host: one.hostPort
    }, function onIdentified(err) {
        assert.ifError(err);

        var peer = subTwo.peers.add(one.hostPort);
        var conn = peer.connect();

        // fff magic test
        var req = conn.buildOutRequest({
            channel: conn.channel,
            remoteAddr: conn.remoteName,
            peerState: peer.state,
            timeout: 0,
            tracer: conn.tracer,
            serviceName: 'server',
            host: one.hostPort,
            hasNoParent: true,
            checksumType: null,
            timers: conn.channel.timers,
            headers: {
                'as': 'raw',
                'cn': 'wat'
            }
        });
        conn.ops.addOutReq(req);

        req.send('echo', '', '', onResponse);
    });

    function onResponse(err, resp) {
        assert.ok(err);
        assert.equal(err.type, 'tchannel.connection.reset');
        assert.equal(err.message,
            'tchannel: tchannel write failure: Got an invalid ttl. Expected positive ttl but got 0'
        );

        assert.equal(resp, null);

        process.nextTick(checkLog);
    }

    function checkLog() {
        assert.equal(cluster.logger.items().length, 1);
        var logLine = cluster.logger.items()[0];
        assert.equal(logLine.levelName, 'info');
        assert.equal(logLine.meta.error.type, 'tchannel.protocol.write-failed');

        assert.end();
    }
});

allocCluster.test('request() with zero timeout', {
    numPeers: 2
}, function t(cluster, assert) {
    cluster.logger.whitelist('info', 'resetting connection');

    var one = cluster.channels[0];
    var two = cluster.channels[1];

    var subTwo = two.makeSubChannel({
        serviceName: 'server'
    });

    subTwo.waitForIdentified({
        host: one.hostPort
    }, function onIdentified(err) {
        assert.ifError(err);

        var peer = subTwo.peers.add(one.hostPort);
        var conn = peer.connect();

        var req = conn.buildOutRequest({
            channel: conn.channel,
            remoteAddr: conn.remoteName,
            peerState: peer.state,
            timeout: -10,
            tracer: conn.tracer,
            serviceName: 'server',
            host: one.hostPort,
            hasNoParent: true,
            checksumType: null,
            timers: conn.channel.timers,
            headers: {
                'as': 'raw',
                'cn': 'wat'
            }
        });
        conn.ops.addOutReq(req);

        req.send('echo', '', '', onResponse);
    });

    function onResponse(err, resp) {
        assert.ok(err);
        assert.equal(err.type, 'tchannel.connection.reset');
        assert.equal(err.message,
            'tchannel: tchannel write failure: Got an invalid ttl. Expected positive ttl but got -10'
        );

        assert.equal(resp, null);

        process.nextTick(checkLog);
    }

    function checkLog() {
        assert.equal(cluster.logger.items().length, 1);
        var logLine = cluster.logger.items()[0];
        assert.equal(logLine.levelName, 'info');
        assert.equal(logLine.meta.error.type, 'tchannel.protocol.write-failed');

        assert.end();
    }
});
<commit_msg>test/non-zero-ttl: harden log assertion<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var allocCluster = require('./lib/alloc-cluster.js');

allocCluster.test('request() with zero timeout', {
    numPeers: 2
}, function t(cluster, assert) {
    cluster.logger.whitelist('info', 'resetting connection');

    var one = cluster.channels[0];
    var two = cluster.channels[1];

    var subTwo = two.makeSubChannel({
        serviceName: 'server'
    });

    subTwo.waitForIdentified({
        host: one.hostPort
    }, function onIdentified(err) {
        assert.ifError(err);

        var peer = subTwo.peers.add(one.hostPort);
        var conn = peer.connect();

        // fff magic test
        var req = conn.buildOutRequest({
            channel: conn.channel,
            remoteAddr: conn.remoteName,
            peerState: peer.state,
            timeout: 0,
            tracer: conn.tracer,
            serviceName: 'server',
            host: one.hostPort,
            hasNoParent: true,
            checksumType: null,
            timers: conn.channel.timers,
            headers: {
                'as': 'raw',
                'cn': 'wat'
            }
        });
        conn.ops.addOutReq(req);

        req.send('echo', '', '', onResponse);
    });

    function onResponse(err, resp) {
        assert.ok(err);
        assert.equal(err.type, 'tchannel.connection.reset');
        assert.equal(err.message,
            'tchannel: tchannel write failure: Got an invalid ttl. Expected positive ttl but got 0'
        );

        assert.equal(resp, null);

        process.nextTick(checkLog);
    }

    function checkLog() {
        assert.equal(cluster.logger.items().length, 1);
        var logLine = cluster.logger.items()[0];
        assert.equal(logLine && logLine.levelName, 'info');
        assert.equal(logLine && logLine.meta.error.type, 'tchannel.protocol.write-failed');

        assert.end();
    }
});

allocCluster.test('request() with zero timeout', {
    numPeers: 2
}, function t(cluster, assert) {
    cluster.logger.whitelist('info', 'resetting connection');

    var one = cluster.channels[0];
    var two = cluster.channels[1];

    var subTwo = two.makeSubChannel({
        serviceName: 'server'
    });

    subTwo.waitForIdentified({
        host: one.hostPort
    }, function onIdentified(err) {
        assert.ifError(err);

        var peer = subTwo.peers.add(one.hostPort);
        var conn = peer.connect();

        var req = conn.buildOutRequest({
            channel: conn.channel,
            remoteAddr: conn.remoteName,
            peerState: peer.state,
            timeout: -10,
            tracer: conn.tracer,
            serviceName: 'server',
            host: one.hostPort,
            hasNoParent: true,
            checksumType: null,
            timers: conn.channel.timers,
            headers: {
                'as': 'raw',
                'cn': 'wat'
            }
        });
        conn.ops.addOutReq(req);

        req.send('echo', '', '', onResponse);
    });

    function onResponse(err, resp) {
        assert.ok(err);
        assert.equal(err.type, 'tchannel.connection.reset');
        assert.equal(err.message,
            'tchannel: tchannel write failure: Got an invalid ttl. Expected positive ttl but got -10'
        );

        assert.equal(resp, null);

        process.nextTick(checkLog);
    }

    function checkLog() {
        assert.equal(cluster.logger.items().length, 1);
        var logLine = cluster.logger.items()[0];
        assert.equal(logLine && logLine.levelName, 'info');
        assert.equal(logLine && logLine.meta.error.type, 'tchannel.protocol.write-failed');

        assert.end();
    }
});
<|endoftext|>