<commit_before>/**
 * UI module for server model tool.
 *
 * @author Tim.Liu
 * @created 2013.10.01
 */

;(function(app){

	var context = app.Context.get('_Dev');
	var module = context.module('ServerModelGen');

	_.extend(module, {

		label: _.string.titleize(_.string.humanize(module.moduleName)),
		icon: 'icon-plus-sign',

		View: {
			ModelListItem: Backbone.Marionette.ItemView.extend({
				template: '#custom-module-_dev-servermodelgen-modelitem-tpl',
				tagName: 'span',
				onRender: function(){
					var size = 70;
					this.$el.css({
						backgroundColor: '#eee',
						borderRadius: size + 'px',
						width: size + 'px',
						height: size + 'px',
						textAlign: 'center',
						lineHeight: size * 0.95 + 'px',
						marginLeft: size/10 + 'px',
						cursor:'pointer',
						float: 'left'
					});
				}
			}),
			ModelList: Backbone.Marionette.CompositeView.extend({
				template: '#custom-module-_dev-servermodelgen-modellist-tpl',
				itemViewContainer: '[item-view-ct]',
				initialize: function(options){
					this.itemView = options.itemView || module.View.ModelListItem;
				},
				onShow:function(){
					this.collection.fetch();
				}
			}),

			ModelFormField: Backbone.Marionette.ItemView.extend({
				template: '#custom-module-_dev-servermodelgen-modelform-field-tpl',
				initialize: function(options){
					this.model.set('cid', this.model.cid);
				}
			}),

			ModelForm: Backbone.Marionette.CompositeView.extend({
				template: '#custom-module-_dev-servermodelgen-modelform-tpl',
				itemViewContainer: '[model-field-list]',
				initialize: function(options){
					this.itemView = options.itemView || module.View.ModelFormField;
				},
				onShow: function(){
					this.$el.css({
						padding: '10px',
						borderTop: '5px dotted #eee'
					});
				},
				ui: {
					'modelNameInput': '[name=modelname]'
				}
			}),

			Default: Backbone.Marionette.Layout.extend({
				template: '#custom-module-_dev-servermodelgen-tpl',
				className: 'tab-pane',
				regions: {
					'list': '[region=modellist]',
					'form': '[region=addmodel]'
				},
				onShow: function(){
					this.list.show(new module.View.ModelList({
						collection: new (Backbone.Collection.extend({
							url: '/dev/models/',
							parse: function(res){
								var models = _.map(res, function(modelPath, modelName){
									return {name: modelName, path: modelPath};
								});
								return _.sortBy(models, function(m){
									return m.name;
								}).reverse();
							}
						}))
					}));
					//TBI: hook up the model search input.

				},
				//General Actions
				events: {
					'click [action]': '_doAction'
				},
				_doAction: function(e){
					e.stopPropagation();
					var $el = $(e.currentTarget);
					var doer = this.actions[$el.attr('action')];
					if(doer) {
						doer = _.bind(doer, this);
						doer($el);
					}else throw new Error('DEV::DEV Tools::You have not yet implemented this action');
				},
				actions: {
					showNewModelForm: function($action){
						if($action.hasClass('disabled'))
							return;
						this.form.show(new module.View.ModelForm({
							collection: new Backbone.Collection([{
								fieldName: '',
								type: 'UNKNOWN'
							}])
						}));
						$action.addClass('disabled'); //disable the button
					},

					addField: function($action){
						this.form.currentView.collection.add({
								fieldName: '',
								type: 'UNKNOWN'
						});
					},

					removeField: function($action){
						var target = $action.attr('cid');
						if(this.form.currentView.collection.length > 1)
							this.form.currentView.collection.remove(target);
					},

					cancelModelForm: function($action){
						this.form.close();
						this.list.getEl('span[action=showNewModelForm]').removeClass('disabled');
					},

					submitModelDef: function($action){
						var name = this.form.currentView.ui.modelNameInput.val();
						var fNames = this.form.getEl('[name=fieldname]').map(function(index, el){
							return _.string.slugify($(this).val());
						}).get();
						var fTypes = this.form.getEl('[name=fieldtype]').map(function(index, el){
							return $(this).val();
						}).get();
						var fields = _.object(fNames, fTypes);
						$.ajax({
							url: '/dev/models/',
							type: 'POST',
							notify: true,
							contentType: 'application/json',
							data: JSON.stringify({
								name: _.string.classify(name),
								fields: fields
							}),
							success: _.bind(function(res){
								this.form.getEl('span[action=cancelModelForm]').click();
							}, this)
						})
					},

					refreshModelList: function($action){
						this.list.currentView.collection.fetch();
					}
				}
			})
		}

	});

})(Application);

Template.extend('custom-module-_dev-servermodelgen-modelitem-tpl',
[
	'{{name}}'
]
);

Template.extend('custom-module-_dev-servermodelgen-modellist-tpl',
[
	'

',
	'
',
		'',
		'<input type="text" placeholder="Find Model..." class="input input-medium">', //model search/filter box
		' Server Model', //+ Server Model button, show model form.
		' Refresh List',
	'
'
]
);

Template.extend('custom-module-_dev-servermodelgen-modelform-field-tpl', //single field inputs row
[
	'
',
		'<input class="span3" name="fieldname" type="text" placeholder="Name of the variable/field">', //field name input
		'<input class="span2" name="fieldtype" type="text" placeholder="Type of the field">', //field type input
		'', //remove field
	'
'
]
);

Template.extend('custom-module-_dev-servermodelgen-modelform-tpl',
[
	'
',
		'Name',
		'
',
			'<input type="text" name="modelname" id="inputModelName" placeholder="Your Model Name Here...">', //model name input
		'
',
	'
',
		'
', //help text on available field types [+]
			'
Available Types: String, Number, Date, Buffer, Boolean, Mixed, Objectid, Array
',
			'e.g [String] or [Number]',
			'or [\'Your Model Name\'] - shortcut for [Objectid] ref:\'Your Model\'',
			'or ^[\'Your Model Name\'] - sub:\'Your Model\' see - /util/objectfactory.js',
			'MongooseJS Schema Types see - http://mongoosejs.com/docs/schematypes.html',
		'
', //help text on available field types [.]
	'
Fields
', //add field
	'

',
	'
Submit Cancel
' //submit model or cancel.
]
);

Template.extend('custom-module-_dev-servermodelgen-tpl',
[
	'

',
	'

'
]);
<commit_msg>We sort the models by srcRef path.<commit_after>/**
 * UI module for server model tool.
 *
 * @author Tim.Liu
 * @created 2013.10.01
 */

;(function(app){

	var context = app.Context.get('_Dev');
	var module = context.module('ServerModelGen');

	_.extend(module, {

		label: _.string.titleize(_.string.humanize(module.moduleName)),
		icon: 'icon-plus-sign',

		View: {
			ModelListItem: Backbone.Marionette.ItemView.extend({
				template: '#custom-module-_dev-servermodelgen-modelitem-tpl',
				tagName: 'span',
				onRender: function(){
					var size = 70;
					this.$el.css({
						backgroundColor: '#eee',
						borderRadius: size + 'px',
						width: size + 'px',
						height: size + 'px',
						textAlign: 'center',
						lineHeight: size * 0.95 + 'px',
						marginLeft: size/10 + 'px',
						cursor:'pointer',
						float: 'left'
					});
				}
			}),
			ModelList: Backbone.Marionette.CompositeView.extend({
				template: '#custom-module-_dev-servermodelgen-modellist-tpl',
				itemViewContainer: '[item-view-ct]',
				initialize: function(options){
					this.itemView = options.itemView || module.View.ModelListItem;
				},
				onShow:function(){
					this.collection.fetch();
				}
			}),

			ModelFormField: Backbone.Marionette.ItemView.extend({
				template: '#custom-module-_dev-servermodelgen-modelform-field-tpl',
				initialize: function(options){
					this.model.set('cid', this.model.cid);
				}
			}),

			ModelForm: Backbone.Marionette.CompositeView.extend({
				template: '#custom-module-_dev-servermodelgen-modelform-tpl',
				itemViewContainer: '[model-field-list]',
				initialize: function(options){
					this.itemView = options.itemView || module.View.ModelFormField;
				},
				onShow: function(){
					this.$el.css({
						padding: '10px',
						borderTop: '5px dotted #eee'
					});
				},
				ui: {
					'modelNameInput': '[name=modelname]'
				}
			}),

			Default: Backbone.Marionette.Layout.extend({
				template: '#custom-module-_dev-servermodelgen-tpl',
				className: 'tab-pane',
				regions: {
					'list': '[region=modellist]',
					'form': '[region=addmodel]'
				},
				onShow: function(){
					this.list.show(new module.View.ModelList({
						collection: new (Backbone.Collection.extend({
							url: '/dev/models/',
							parse: function(res){
								var models = _.map(res, function(modelPath, modelName){
									return {name: modelName, path: modelPath};
								});
								return _.sortBy(models, function(m){
									return m.path;
								}).reverse();
							}
						}))
					}));
					//TBI: hook up the model search input.

				},
				//General Actions
				events: {
					'click [action]': '_doAction'
				},
				_doAction: function(e){
					e.stopPropagation();
					var $el = $(e.currentTarget);
					var doer = this.actions[$el.attr('action')];
					if(doer) {
						doer = _.bind(doer, this);
						doer($el);
					}else throw new Error('DEV::DEV Tools::You have not yet implemented this action');
				},
				actions: {
					showNewModelForm: function($action){
						if($action.hasClass('disabled'))
							return;
						this.form.show(new module.View.ModelForm({
							collection: new Backbone.Collection([{
								fieldName: '',
								type: 'UNKNOWN'
							}])
						}));
						$action.addClass('disabled'); //disable the button
					},

					addField: function($action){
						this.form.currentView.collection.add({
								fieldName: '',
								type: 'UNKNOWN'
						});
					},

					removeField: function($action){
						var target = $action.attr('cid');
						if(this.form.currentView.collection.length > 1)
							this.form.currentView.collection.remove(target);
					},

					cancelModelForm: function($action){
						this.form.close();
						this.list.getEl('span[action=showNewModelForm]').removeClass('disabled');
					},

					submitModelDef: function($action){
						var name = this.form.currentView.ui.modelNameInput.val();
						var fNames = this.form.getEl('[name=fieldname]').map(function(index, el){
							return _.string.slugify($(this).val());
						}).get();
						var fTypes = this.form.getEl('[name=fieldtype]').map(function(index, el){
							return $(this).val();
						}).get();
						var fields = _.object(fNames, fTypes);
						$.ajax({
							url: '/dev/models/',
							type: 'POST',
							notify: true,
							contentType: 'application/json',
							data: JSON.stringify({
								name: _.string.classify(name),
								fields: fields
							}),
							success: _.bind(function(res){
								this.form.getEl('span[action=cancelModelForm]').click();
							}, this)
						})
					},

					refreshModelList: function($action){
						this.list.currentView.collection.fetch();
					}
				}
			})
		}

	});

})(Application);

Template.extend('custom-module-_dev-servermodelgen-modelitem-tpl',
[
	'{{name}}'
]
);

Template.extend('custom-module-_dev-servermodelgen-modellist-tpl',
[
	'

',
	'
',
		'',
		'<input type="text" placeholder="Find Model..." class="input input-medium">', //model search/filter box
		' Server Model', //+ Server Model button, show model form.
		' Refresh List',
	'
'
]
);

Template.extend('custom-module-_dev-servermodelgen-modelform-field-tpl', //single field inputs row
[
	'
',
		'<input class="span3" name="fieldname" type="text" placeholder="Name of the variable/field">', //field name input
		'<input class="span2" name="fieldtype" type="text" placeholder="Type of the field">', //field type input
		'', //remove field
	'
'
]
);

Template.extend('custom-module-_dev-servermodelgen-modelform-tpl',
[
	'
',
		'Name',
		'
',
			'<input type="text" name="modelname" id="inputModelName" placeholder="Your Model Name Here...">', //model name input
		'
',
	'
',
		'
', //help text on available field types [+]
			'
Available Types: String, Number, Date, Buffer, Boolean, Mixed, Objectid, Array
',
			'e.g [String] or [Number]',
			'or [\'Your Model Name\'] - shortcut for [Objectid] ref:\'Your Model\'',
			'or ^[\'Your Model Name\'] - sub:\'Your Model\' see - /util/objectfactory.js',
			'MongooseJS Schema Types see - http://mongoosejs.com/docs/schematypes.html',
		'
', //help text on available field types [.]
	'
Fields
', //add field
	'

',
	'
Submit Cancel
' //submit model or cancel.
]
);

Template.extend('custom-module-_dev-servermodelgen-tpl',
[
	'

',
	'

'
]);
<|endoftext|>


<commit_before>'use strict';

describe('TreebankRetriever', function() {
  var retriever;

  beforeEach(function() {
    module("arethusa.core", function($provide) {
      $provide.value('configurator', arethusaMocks.configurator());
    });

    module("arethusa");

    inject(function(TreebankRetriever) {
      retriever = new TreebankRetriever({});
    });
  });

  function makePrefix(pfx) {
    return pfx ? pfx + ':' : '';
  }

  function toWord(idAndForm, pfx) {
    return '<' + makePrefix(pfx) + 'word id="' + idAndForm[0] + '" form="' + idAndForm[1] + '"/>';
  }

  function toSentence(idAndWords, pfx) {
    var ws =  aU.map(idAndWords[1], toWord, pfx).join('');
    return '<' + makePrefix(pfx) + 'sentence id="' + idAndWords[0] + '">' + ws + '</' + makePrefix(pfx) + 'sentence>';
  }

  function toTreebank(sentences) {
    var ss = aU.map(sentences, toSentence).join('');
    return '<treebank>' + ss + '</treebank>';
  }

  function toNsTreebank(sentences) {
    var ss = aU.map(sentences, toSentence, 'ns1').join('');
    return '<ns1:treebank xmlns:ns1="http://example.org/ns">' + ss + '</ns1:treebank>';
  }

  describe('parse', function() {
    var result;
    beforeEach(function() { result = undefined; });

    function callback(sentences) {
      result = sentences;
    }

    it('parses treebank data in XML format and returns an array of sentences', function() {
      var tb = toTreebank([[1, [[1, 'a'], [2, 'b']]], [2, [[1, 'a'], [2, 'b']]]]);
      retriever.parse(tb, callback);
      expect(result.length).toEqual(2); // 2 sentences

      var s1 = result[0];
      var s2 = result[1];

      expect(s1.id).toBeDefined();

      var tokenIds = Object.keys(s1.tokens);
      expect(tokenIds.length).toEqual(2); // 2 tokens
      expect(s1.tokens[tokenIds[0]].string).toEqual('a');
    });

    it('does not fail when a treebank consists of a single sentence', function() {
      var tb = toTreebank([[1, [[1, 'a'], [2, 'b']]]]);
      retriever.parse(tb, callback);
      expect(result.length).toEqual(1); // 1 sentence
    });

    // Tests the bug described in http://github.com/latin-language-toolkit/arethusa/issues/440
    it('does not fail when a sentence consists of a single word', function() {
      var tb = toTreebank([[1, [[1, 'a']]]]);
      retriever.parse(tb, callback);

      var tokenIds = Object.keys(result[0].tokens);
      expect(tokenIds.length).toEqual(1); // 1 token
    });

    // Test that namespaced treebank files are also okay
    it('fails when a treebank is namespace prefixed', function() {
      var tb = toNsTreebank([[1, [[1, 'a']]]]);
      retriever.parse(tb, callback);

      var tokenIds = Object.keys(result[0].tokens);
      var s1 = result[0];
      expect(tokenIds.length).toEqual(1); // nothing parsed
      expect(s1.id).toBeDefined();
      expect(s1.tokens[tokenIds[0]].string).toEqual('a');
    });
  });
});
<commit_msg>fixing description of test<commit_after>'use strict';

describe('TreebankRetriever', function() {
  var retriever;

  beforeEach(function() {
    module("arethusa.core", function($provide) {
      $provide.value('configurator', arethusaMocks.configurator());
    });

    module("arethusa");

    inject(function(TreebankRetriever) {
      retriever = new TreebankRetriever({});
    });
  });

  function makePrefix(pfx) {
    return pfx ? pfx + ':' : '';
  }

  function toWord(idAndForm, pfx) {
    return '<' + makePrefix(pfx) + 'word id="' + idAndForm[0] + '" form="' + idAndForm[1] + '"/>';
  }

  function toSentence(idAndWords, pfx) {
    var ws =  aU.map(idAndWords[1], toWord, pfx).join('');
    return '<' + makePrefix(pfx) + 'sentence id="' + idAndWords[0] + '">' + ws + '</' + makePrefix(pfx) + 'sentence>';
  }

  function toTreebank(sentences) {
    var ss = aU.map(sentences, toSentence).join('');
    return '<treebank>' + ss + '</treebank>';
  }

  function toNsTreebank(sentences) {
    var ss = aU.map(sentences, toSentence, 'ns1').join('');
    return '<ns1:treebank xmlns:ns1="http://example.org/ns">' + ss + '</ns1:treebank>';
  }

  describe('parse', function() {
    var result;
    beforeEach(function() { result = undefined; });

    function callback(sentences) {
      result = sentences;
    }

    it('parses treebank data in XML format and returns an array of sentences', function() {
      var tb = toTreebank([[1, [[1, 'a'], [2, 'b']]], [2, [[1, 'a'], [2, 'b']]]]);
      retriever.parse(tb, callback);
      expect(result.length).toEqual(2); // 2 sentences

      var s1 = result[0];
      var s2 = result[1];

      expect(s1.id).toBeDefined();

      var tokenIds = Object.keys(s1.tokens);
      expect(tokenIds.length).toEqual(2); // 2 tokens
      expect(s1.tokens[tokenIds[0]].string).toEqual('a');
    });

    it('does not fail when a treebank consists of a single sentence', function() {
      var tb = toTreebank([[1, [[1, 'a'], [2, 'b']]]]);
      retriever.parse(tb, callback);
      expect(result.length).toEqual(1); // 1 sentence
    });

    // Tests the bug described in http://github.com/latin-language-toolkit/arethusa/issues/440
    it('does not fail when a sentence consists of a single word', function() {
      var tb = toTreebank([[1, [[1, 'a']]]]);
      retriever.parse(tb, callback);

      var tokenIds = Object.keys(result[0].tokens);
      expect(tokenIds.length).toEqual(1); // 1 token
    });

    // Test that namespaced treebank files are also okay
    // But not that this test is of limited value due to
    // https://github.com/ariya/phantomjs/issues/10428
    it('succeeds when a treebank is namespace prefixed', function() {
      var tb = toNsTreebank([[1, [[1, 'a']]]]);
      retriever.parse(tb, callback);

      var tokenIds = Object.keys(result[0].tokens);
      var s1 = result[0];
      expect(tokenIds.length).toEqual(1);
      expect(s1.id).toBeDefined();
      expect(s1.tokens[tokenIds[0]].string).toEqual('a');
    });
  });
});
<|endoftext|>


<commit_before>/*
 * bootstrap-filestyle
 * doc: http://markusslima.github.io/bootstrap-filestyle/
 * github: https://github.com/markusslima/bootstrap-filestyle
 *
 * Copyright (c) 2014 Markus Vinicius da Silva Lima
 * Version 1.1.2
 * Licensed under the MIT license.
 */
(function($) {"use strict";

	var Filestyle = function(element, options) {
		this.options = options;
		this.$elementFilestyle = [];
		this.$element = $(element);
	};

	Filestyle.prototype = {
		clear : function() {
			this.$element.val('');
			this.$elementFilestyle.find(':text').val('');
			this.$elementFilestyle.find('.badge').remove();
		},

		destroy : function() {
			this.$element.removeAttr('style').removeData('filestyle');
			this.$elementFilestyle.remove();
		},

		disabled : function(value) {
			if (value === true) {
				if (!this.options.disabled) {
					this.$element.attr('disabled', 'true');
					this.$elementFilestyle.find('label').attr('disabled', 'true');
					this.options.disabled = true;
				}
			} else if (value === false) {
				if (this.options.disabled) {
					this.$element.removeAttr('disabled');
					this.$elementFilestyle.find('label').removeAttr('disabled');
					this.options.disabled = false;
				}
			} else {
				return this.options.disabled;
			}
		},

		buttonBefore : function(value) {
			if (value === true) {
				if (!this.options.buttonBefore) {
					this.options.buttonBefore = true;
					if (this.options.input) {
						this.$elementFilestyle.remove();
						this.constructor();
						this.pushNameFiles();
					}
				}
			} else if (value === false) {
				if (this.options.buttonBefore) {
					this.options.buttonBefore = false;
					if (this.options.input) {
						this.$elementFilestyle.remove();
						this.constructor();
						this.pushNameFiles();
					}
				}
			} else {
				return this.options.buttonBefore;
			}
		},

		icon : function(value) {
			if (value === true) {
				if (!this.options.icon) {
					this.options.icon = true;
					this.$elementFilestyle.find('label').prepend(this.htmlIcon());
				}
			} else if (value === false) {
				if (this.options.icon) {
					this.options.icon = false;
					this.$elementFilestyle.find('.glyphicon').remove();
				}
			} else {
				return this.options.icon;
			}
		},

		input : function(value) {
			if (value === true) {
				if (!this.options.input) {
					this.options.input = true;

					if (this.options.buttonBefore) {
						this.$elementFilestyle.append(this.htmlInput());
					} else {
						this.$elementFilestyle.prepend(this.htmlInput());
					}

					this.$elementFilestyle.find('.badge').remove();

					this.pushNameFiles();

					this.$elementFilestyle.find('.group-span-filestyle').addClass('input-group-btn');
				}
			} else if (value === false) {
				if (this.options.input) {
					this.options.input = false;
					this.$elementFilestyle.find(':text').remove();
					var files = this.pushNameFiles();
					if (files.length > 0 && this.options.badge) {
						this.$elementFilestyle.find('label').append(' ' + files.length + '');
					}
					this.$elementFilestyle.find('.group-span-filestyle').removeClass('input-group-btn');
				}
			} else {
				return this.options.input;
			}
		},

		size : function(value) {
			if (value !== undefined) {
				var btn = this.$elementFilestyle.find('label'), input = this.$elementFilestyle.find('input');

				btn.removeClass('btn-lg btn-sm');
				input.removeClass('input-lg input-sm');
				if (value != 'nr') {
					btn.addClass('btn-' + value);
					input.addClass('input-' + value);
				}
			} else {
				return this.options.size;
			}
		},

		buttonText : function(value) {
			if (value !== undefined) {
				this.options.buttonText = value;
				this.$elementFilestyle.find('label .buttonText').html(this.options.buttonText);
			} else {
				return this.options.buttonText;
			}
		},

		buttonName : function(value) {
			if (value !== undefined) {
				this.options.buttonName = value;
				this.$elementFilestyle.find('label').attr({
					'class' : 'btn ' + this.options.buttonName
				});
			} else {
				return this.options.buttonName;
			}
		},

		iconName : function(value) {
			if (value !== undefined) {
				this.$elementFilestyle.find('.glyphicon').attr({
					'class' : '.glyphicon ' + this.options.iconName
				});
			} else {
				return this.options.iconName;
			}
		},

		htmlIcon : function() {
			if (this.options.icon) {
				return ' ';
			} else {
				return '';
			}
		},

		htmlInput : function() {
			if (this.options.input) {
				return '<input type="text" class="form-control ' + (this.options.size == 'nr' ? '' : 'input-' + this.options.size) + '" disabled> ';
			} else {
				return '';
			}
		},

		// puts the name of the input files
		// return files
		pushNameFiles : function() {
			var content = '', files = [];
			if (this.$element[0].files === undefined) {
				files[0] = {
					'name' : this.$element[0] && this.$element[0].value
				};
			} else {
				files = this.$element[0].files;
			}

			for (var i = 0; i < files.length; i++) {
				content += files[i].name.split("\\").pop() + ', ';
			}

			if (content !== '') {
				this.$elementFilestyle.find(':text').val(content.replace(/\, $/g, ''));
			} else {
				this.$elementFilestyle.find(':text').val('');
			}

			return files;
		},

		constructor : function() {
			var _self = this,
				html = '',
				id = _self.$element.attr('id'),
				files = [],
				btn = '',
				$label;

			if (id === '' || !id) {
				id = 'filestyle-' + $('.bootstrap-filestyle').length;
				_self.$element.attr({
					'id' : id
				});
			}

			btn = '' +
				  '' +
				  		_self.htmlIcon() + '' + _self.options.buttonText + '' +
				  '' +
				  '';

			html = _self.options.buttonBefore ? btn + _self.htmlInput() : _self.htmlInput() + btn;

			_self.$elementFilestyle = $('
' + html + '
');
			_self.$elementFilestyle.find('.group-span-filestyle').attr('tabindex', "0").keypress(function(e) {
				if (e.keyCode === 13 || e.charCode === 32) {
					_self.$elementFilestyle.find('label').click();
					return false;
				}
			});

			// hidding input file and add filestyle
			_self.$element.css({
				'position' : 'absolute',
				'clip' : 'rect(0px 0px 0px 0px)' // using 0px for work in IE8
			}).attr('tabindex', "-1").after(_self.$elementFilestyle);

			if (_self.options.disabled) {
				_self.$element.attr('disabled', 'true');
			}

			// Getting input file value
			_self.$element.change(function() {
				var files = _self.pushNameFiles();

				if (_self.options.input == false && _self.options.badge) {
					if (_self.$elementFilestyle.find('.badge').length == 0) {
						_self.$elementFilestyle.find('label').append(' ' + files.length + '');
					} else if (files.length == 0) {
						_self.$elementFilestyle.find('.badge').remove();
					} else {
						_self.$elementFilestyle.find('.badge').html(files.length);
					}
				} else {
					_self.$elementFilestyle.find('.badge').remove();
				}
			});

			// Check if browser is Firefox
			if (window.navigator.userAgent.search(/firefox/i) > -1) {
				// Simulating choose file for firefox
				_self.$elementFilestyle.find('label').click(function() {
					_self.$element.click();
					return false;
				});
			}
		}
	};

	var old = $.fn.filestyle;

	$.fn.filestyle = function(option, value) {
		var get = '', element = this.each(function() {
			if ($(this).attr('type') === 'file') {
				var $this = $(this), data = $this.data('filestyle'), options = $.extend({}, $.fn.filestyle.defaults, option, typeof option === 'object' && option);

				if (!data) {
					$this.data('filestyle', ( data = new Filestyle(this, options)));
					data.constructor();
				}

				if ( typeof option === 'string') {
					get = data[option](value);
				}
			}
		});

		if ( typeof get !== undefined) {
			return get;
		} else {
			return element;
		}
	};

	$.fn.filestyle.defaults = {
		'buttonText' : 'Choose file',
		'iconName' : 'glyphicon-folder-open',
		'buttonName' : 'btn-default',
		'size' : 'nr',
		'input' : true,
		'badge' : true,
		'icon' : true,
		'buttonBefore' : false,
		'disabled' : false
	};

	$.fn.filestyle.noConflict = function() {
		$.fn.filestyle = old;
		return this;
	};

	// Data attributes register
	$(function() {
		$('.filestyle').each(function() {
			var $this = $(this), options = {

				'input' : $this.attr('data-input') === 'false' ? false : true,
				'icon' : $this.attr('data-icon') === 'false' ? false : true,
				'buttonBefore' : $this.attr('data-buttonBefore') === 'true' ? true : false,
				'disabled' : $this.attr('data-disabled') === 'true' ? true : false,
				'size' : $this.attr('data-size'),
				'buttonText' : $this.attr('data-buttonText'),
				'buttonName' : $this.attr('data-buttonName'),
				'iconName' : $this.attr('data-iconName'),
				'badge' : $this.attr('data-badge') === 'false' ? false : true
			};

			$this.filestyle(options);
		});
	});
})(window.jQuery);
<commit_msg>Allow using third-party icons. Resolves #88.<commit_after>/*
 * bootstrap-filestyle
 * doc: http://markusslima.github.io/bootstrap-filestyle/
 * github: https://github.com/markusslima/bootstrap-filestyle
 *
 * Copyright (c) 2014 Markus Vinicius da Silva Lima
 * Version 1.1.2
 * Licensed under the MIT license.
 */
(function($) {"use strict";

	var Filestyle = function(element, options) {
		this.options = options;
		this.$elementFilestyle = [];
		this.$element = $(element);
	};

	Filestyle.prototype = {
		clear : function() {
			this.$element.val('');
			this.$elementFilestyle.find(':text').val('');
			this.$elementFilestyle.find('.badge').remove();
		},

		destroy : function() {
			this.$element.removeAttr('style').removeData('filestyle');
			this.$elementFilestyle.remove();
		},

		disabled : function(value) {
			if (value === true) {
				if (!this.options.disabled) {
					this.$element.attr('disabled', 'true');
					this.$elementFilestyle.find('label').attr('disabled', 'true');
					this.options.disabled = true;
				}
			} else if (value === false) {
				if (this.options.disabled) {
					this.$element.removeAttr('disabled');
					this.$elementFilestyle.find('label').removeAttr('disabled');
					this.options.disabled = false;
				}
			} else {
				return this.options.disabled;
			}
		},

		buttonBefore : function(value) {
			if (value === true) {
				if (!this.options.buttonBefore) {
					this.options.buttonBefore = true;
					if (this.options.input) {
						this.$elementFilestyle.remove();
						this.constructor();
						this.pushNameFiles();
					}
				}
			} else if (value === false) {
				if (this.options.buttonBefore) {
					this.options.buttonBefore = false;
					if (this.options.input) {
						this.$elementFilestyle.remove();
						this.constructor();
						this.pushNameFiles();
					}
				}
			} else {
				return this.options.buttonBefore;
			}
		},

		icon : function(value) {
			if (value === true) {
				if (!this.options.icon) {
					this.options.icon = true;
					this.$elementFilestyle.find('label').prepend(this.htmlIcon());
				}
			} else if (value === false) {
				if (this.options.icon) {
					this.options.icon = false;
					this.$elementFilestyle.find('.icon-span-filestyle').remove();
				}
			} else {
				return this.options.icon;
			}
		},

		input : function(value) {
			if (value === true) {
				if (!this.options.input) {
					this.options.input = true;

					if (this.options.buttonBefore) {
						this.$elementFilestyle.append(this.htmlInput());
					} else {
						this.$elementFilestyle.prepend(this.htmlInput());
					}

					this.$elementFilestyle.find('.badge').remove();

					this.pushNameFiles();

					this.$elementFilestyle.find('.group-span-filestyle').addClass('input-group-btn');
				}
			} else if (value === false) {
				if (this.options.input) {
					this.options.input = false;
					this.$elementFilestyle.find(':text').remove();
					var files = this.pushNameFiles();
					if (files.length > 0 && this.options.badge) {
						this.$elementFilestyle.find('label').append(' ' + files.length + '');
					}
					this.$elementFilestyle.find('.group-span-filestyle').removeClass('input-group-btn');
				}
			} else {
				return this.options.input;
			}
		},

		size : function(value) {
			if (value !== undefined) {
				var btn = this.$elementFilestyle.find('label'), input = this.$elementFilestyle.find('input');

				btn.removeClass('btn-lg btn-sm');
				input.removeClass('input-lg input-sm');
				if (value != 'nr') {
					btn.addClass('btn-' + value);
					input.addClass('input-' + value);
				}
			} else {
				return this.options.size;
			}
		},

		buttonText : function(value) {
			if (value !== undefined) {
				this.options.buttonText = value;
				this.$elementFilestyle.find('label .buttonText').html(this.options.buttonText);
			} else {
				return this.options.buttonText;
			}
		},

		buttonName : function(value) {
			if (value !== undefined) {
				this.options.buttonName = value;
				this.$elementFilestyle.find('label').attr({
					'class' : 'btn ' + this.options.buttonName
				});
			} else {
				return this.options.buttonName;
			}
		},

		iconName : function(value) {
			if (value !== undefined) {
				this.$elementFilestyle.find('.icon-span-filestyle').attr({
					'class' : 'icon-span-filestyle ' + this.options.iconName
				});
			} else {
				return this.options.iconName;
			}
		},

		htmlIcon : function() {
			if (this.options.icon) {
				return ' ';
			} else {
				return '';
			}
		},

		htmlInput : function() {
			if (this.options.input) {
				return '<input type="text" class="form-control ' + (this.options.size == 'nr' ? '' : 'input-' + this.options.size) + '" disabled> ';
			} else {
				return '';
			}
		},

		// puts the name of the input files
		// return files
		pushNameFiles : function() {
			var content = '', files = [];
			if (this.$element[0].files === undefined) {
				files[0] = {
					'name' : this.$element[0] && this.$element[0].value
				};
			} else {
				files = this.$element[0].files;
			}

			for (var i = 0; i < files.length; i++) {
				content += files[i].name.split("\\").pop() + ', ';
			}

			if (content !== '') {
				this.$elementFilestyle.find(':text').val(content.replace(/\, $/g, ''));
			} else {
				this.$elementFilestyle.find(':text').val('');
			}

			return files;
		},

		constructor : function() {
			var _self = this,
				html = '',
				id = _self.$element.attr('id'),
				files = [],
				btn = '',
				$label;

			if (id === '' || !id) {
				id = 'filestyle-' + $('.bootstrap-filestyle').length;
				_self.$element.attr({
					'id' : id
				});
			}

			btn = '' +
				  '' +
				  		_self.htmlIcon() + '' + _self.options.buttonText + '' +
				  '' +
				  '';

			html = _self.options.buttonBefore ? btn + _self.htmlInput() : _self.htmlInput() + btn;

			_self.$elementFilestyle = $('
' + html + '
');
			_self.$elementFilestyle.find('.group-span-filestyle').attr('tabindex', "0").keypress(function(e) {
				if (e.keyCode === 13 || e.charCode === 32) {
					_self.$elementFilestyle.find('label').click();
					return false;
				}
			});

			// hidding input file and add filestyle
			_self.$element.css({
				'position' : 'absolute',
				'clip' : 'rect(0px 0px 0px 0px)' // using 0px for work in IE8
			}).attr('tabindex', "-1").after(_self.$elementFilestyle);

			if (_self.options.disabled) {
				_self.$element.attr('disabled', 'true');
			}

			// Getting input file value
			_self.$element.change(function() {
				var files = _self.pushNameFiles();

				if (_self.options.input == false && _self.options.badge) {
					if (_self.$elementFilestyle.find('.badge').length == 0) {
						_self.$elementFilestyle.find('label').append(' ' + files.length + '');
					} else if (files.length == 0) {
						_self.$elementFilestyle.find('.badge').remove();
					} else {
						_self.$elementFilestyle.find('.badge').html(files.length);
					}
				} else {
					_self.$elementFilestyle.find('.badge').remove();
				}
			});

			// Check if browser is Firefox
			if (window.navigator.userAgent.search(/firefox/i) > -1) {
				// Simulating choose file for firefox
				_self.$elementFilestyle.find('label').click(function() {
					_self.$element.click();
					return false;
				});
			}
		}
	};

	var old = $.fn.filestyle;

	$.fn.filestyle = function(option, value) {
		var get = '', element = this.each(function() {
			if ($(this).attr('type') === 'file') {
				var $this = $(this), data = $this.data('filestyle'), options = $.extend({}, $.fn.filestyle.defaults, option, typeof option === 'object' && option);

				if (!data) {
					$this.data('filestyle', ( data = new Filestyle(this, options)));
					data.constructor();
				}

				if ( typeof option === 'string') {
					get = data[option](value);
				}
			}
		});

		if ( typeof get !== undefined) {
			return get;
		} else {
			return element;
		}
	};

	$.fn.filestyle.defaults = {
		'buttonText' : 'Choose file',
		'iconName' : 'glyphicon glyphicon-folder-open',
		'buttonName' : 'btn-default',
		'size' : 'nr',
		'input' : true,
		'badge' : true,
		'icon' : true,
		'buttonBefore' : false,
		'disabled' : false
	};

	$.fn.filestyle.noConflict = function() {
		$.fn.filestyle = old;
		return this;
	};

	// Data attributes register
	$(function() {
		$('.filestyle').each(function() {
			var $this = $(this), options = {

				'input' : $this.attr('data-input') === 'false' ? false : true,
				'icon' : $this.attr('data-icon') === 'false' ? false : true,
				'buttonBefore' : $this.attr('data-buttonBefore') === 'true' ? true : false,
				'disabled' : $this.attr('data-disabled') === 'true' ? true : false,
				'size' : $this.attr('data-size'),
				'buttonText' : $this.attr('data-buttonText'),
				'buttonName' : $this.attr('data-buttonName'),
				'iconName' : $this.attr('data-iconName'),
				'badge' : $this.attr('data-badge') === 'false' ? false : true
			};

			$this.filestyle(options);
		});
	});
})(window.jQuery);
<|endoftext|>


<commit_before>/*
---
description: Observable data structures for use with the Moo Template Engine.

license: MIT-style

authors:
- Henrik Cooke (http://null-tech.com)

provides:
- MTEObservableObject
- MTEObservableMap
- MTEObservableArray
- Class.Mutators.MTEObservableAutoProperties

requires:
- core/1.3:
  - Class
  - Class.Extras
  - Element
  - Elements
  - Array
  - Object

...
*/
MTEObservableObject = new Class({
    Binds: ['listenChange', 'triggerChange', 'get'],

    isObservable: true,

    bindings: new Events(),

    get: function (property) {
        if (this['get' + property.capitalize()] != null) {
            return this['get' + property.capitalize()]();
        } else {
            return this[property];
        }
    },

    listenChange: function (property, eventHandler, initTrigger) {
        if (initTrigger) {
            eventHandler(this, property, this.get(property));
        }

        this.bindings.addEvent(property, eventHandler);
    },

    triggerChange: function (property, value) {
        this.bindings.fireEvent(property, [this, property, value]);
    }
});

MTEObservableMap = new Class({
    Extends: Events,

    map: {},

    isObservableMap: true,

    set: function (key, item) {
        var oldItem = this.map[key];
        this.map[key] = item;
        if (oldItem) {
            this.fireEvent('change', [item, key, oldItem, this]);
        } else {
            this.fireEvent('set', [item, key, this]);
        }
    },

    clear: function (key) {
        var item = this.map[key];
        if (item) {
            delete this.map[key];
            this.fireEvent('clear', [item, key, this]);
        }
    }
});

MTEObservableArray = new Class({
    Extends: Events,

    items: [],

    isObservableArray: true,

    add: function (item) {
        this.items.push(item);
        this.fireEvent('add', [item, this.items.length - 1, this]);
    },

    remove: function (item) {
        for (var i = this.items.length - 1; i > -1; i--) {
            if (this.items[i] == item) {
                this.items.splice(i, 1);
                this.fireEvent('remove', [item, i, this]);
            }
        }
    }
});

// Can be used to auto implement getter and setter
Class.Mutators.MTEObservableAutoProperties = function (configuration) {
    var setFunction = function (item) {
        return function (value) {
            this[item] = value;
            this.triggerChange(item, value);
        };
    };

    var getFunction = function (item) {
        return function () { return this[item]; };
    };

    configuration.each(function (item) {
        var getName = ('get' + item.capitalize());
        var setName = ('set' + item.capitalize());
        var getterSetter = {};
        getterSetter[getName] = getFunction(item);
        getterSetter[setName] = setFunction(item);
        this.implement(getterSetter);
    }, this);

    this.implement({
        set: function (prop, value) {
            var setName = ('set' + prop.capitalize());
            this[setName](value);
        },
        get: function (prop) {
            var getName = ('get' + prop.capitalize());
            return this[getName]();
        },
        has: function (prop) {
            var getName = ('get' + prop.capitalize());
            return this[getName] != null;
        }
    });
};<commit_msg>Fixed headers<commit_after>/*
---
description: Observable data structures for use with the Moo Template Engine.

license: MIT-style

authors:
- Henrik Cooke (http://null-tech.com)

provides:
- MTEObservableObject
- MTEObservableMap
- MTEObservableArray
- Class.Mutators.MTEObservableAutoProperties

requires:
- core/1.3: [Class, Class.Extras, Element, Elements, Array, Object]

...
*/
MTEObservableObject = new Class({
    Binds: ['listenChange', 'triggerChange', 'get'],

    isObservable: true,

    bindings: new Events(),

    get: function (property) {
        if (this['get' + property.capitalize()] != null) {
            return this['get' + property.capitalize()]();
        } else {
            return this[property];
        }
    },

    listenChange: function (property, eventHandler, initTrigger) {
        if (initTrigger) {
            eventHandler(this, property, this.get(property));
        }

        this.bindings.addEvent(property, eventHandler);
    },

    triggerChange: function (property, value) {
        this.bindings.fireEvent(property, [this, property, value]);
    }
});

MTEObservableMap = new Class({
    Extends: Events,

    map: {},

    isObservableMap: true,

    set: function (key, item) {
        var oldItem = this.map[key];
        this.map[key] = item;
        if (oldItem) {
            this.fireEvent('change', [item, key, oldItem, this]);
        } else {
            this.fireEvent('set', [item, key, this]);
        }
    },

    clear: function (key) {
        var item = this.map[key];
        if (item) {
            delete this.map[key];
            this.fireEvent('clear', [item, key, this]);
        }
    }
});

MTEObservableArray = new Class({
    Extends: Events,

    items: [],

    isObservableArray: true,

    add: function (item) {
        this.items.push(item);
        this.fireEvent('add', [item, this.items.length - 1, this]);
    },

    remove: function (item) {
        for (var i = this.items.length - 1; i > -1; i--) {
            if (this.items[i] == item) {
                this.items.splice(i, 1);
                this.fireEvent('remove', [item, i, this]);
            }
        }
    }
});

// Can be used to auto implement getter and setter
Class.Mutators.MTEObservableAutoProperties = function (configuration) {
    var setFunction = function (item) {
        return function (value) {
            this[item] = value;
            this.triggerChange(item, value);
        };
    };

    var getFunction = function (item) {
        return function () { return this[item]; };
    };

    configuration.each(function (item) {
        var getName = ('get' + item.capitalize());
        var setName = ('set' + item.capitalize());
        var getterSetter = {};
        getterSetter[getName] = getFunction(item);
        getterSetter[setName] = setFunction(item);
        this.implement(getterSetter);
    }, this);

    this.implement({
        set: function (prop, value) {
            var setName = ('set' + prop.capitalize());
            this[setName](value);
        },
        get: function (prop) {
            var getName = ('get' + prop.capitalize());
            return this[getName]();
        },
        has: function (prop) {
            var getName = ('get' + prop.capitalize());
            return this[getName] != null;
        }
    });
};<|endoftext|>


<commit_before>/* global define */

define([
  'jquery',
  'backbone',
  'marionette',
  'controllers/bus/command-bus',
  'collections/comment-collection',
  'views/archive-view',
  'views/single-post-view',
  'views/not-found-view',
  'views/empty-view',
  'views/loading-view'
], function ($, Backbone, Marionette, CommandBus, Comments, ArchiveView, SinglePostView, NotFoundView, EmptyView, LoadingView) {
  'use strict';

  return Marionette.Controller.extend({
    initialize: function(options) {
      this.app     = options.app;
      this.posts   = options.posts;
      this.user    = options.user;

      if (this.postInitialize) {
        this.postInitialize(options);
      }
    },

    /**
     * Display view.
     *
     * @param {Object} view View to display.
     */
    show: function (view) {
      this.app.main.show(view);
      this.hideLoading();
    },

    /**
     * Triggers a command to display the loading view
     */
    showLoading: function () {
      CommandBus.execute('loading:show');
    },

    /**
     * Triggers a command to hide the loading view
     */
    hideLoading: function () {
      CommandBus.execute('loading:hide');
    },

    /**
     * Creates a new `NotFoundView` instance.
     *
     * @return {NotFoundView} New "Not found" view instance.
     */
    notFoundView: function () {
      return new NotFoundView();
    },

    /**
     * Creates a new `EmptyView` instance.
     *
     * @return {EmptyView} New "Empty" view instance.
     */
    emptyView: function () {
      return new EmptyView();
    },

    /**
     * Creates a new `LoadingView` instance.
     *
     * @return {LoadingView} New "Loading" view instance.
     */
    loadingView: function () {
      return new LoadingView();
    },

    /**
     * Creates a new ArchiveView instance for a post list.
     *
     * @param  {array}       posts Post collection to display.
     * @param  {int}         page  Page number.
     * @param  {Object}      filter The searching filter
     * @return {ArchiveView}       New archive view instance.
     */
    archiveView: function (posts, page, filter) {
      return new ArchiveView({collection: posts, page: page, filter: filter});
    },

    /**
     * Creates a new SinglePostView instance for a single post.
     *
     * @param  {Object}            posts Model to display.
     * @param  {int}               page  Page number.
     * @return {SinglePostView}       New single post view instance.
     */
    singlePostView: function (model, page) {
      return new SinglePostView({model: model, page: page, collection: new Comments(), user: this.user});
    }
  });
});<commit_msg>Inject collection instead of instantiating it<commit_after>/* global define */

define([
  'jquery',
  'backbone',
  'marionette',
  'controllers/bus/command-bus',
  'views/archive-view',
  'views/single-post-view',
  'views/not-found-view',
  'views/empty-view',
  'views/loading-view'
], function ($, Backbone, Marionette, CommandBus, ArchiveView, SinglePostView, NotFoundView, EmptyView, LoadingView) {
  'use strict';

  return Marionette.Controller.extend({
    initialize: function(options) {
      this.app   = options.app;
      this.posts = options.posts;
      this.user  = options.user;

      if (this.postInitialize) {
        this.postInitialize(options);
      }
    },

    /**
     * Display view.
     *
     * @param {Object} view View to display.
     */
    show: function (view) {
      this.app.main.show(view);
      this.hideLoading();
    },

    /**
     * Triggers a command to display the loading view
     */
    showLoading: function () {
      CommandBus.execute('loading:show');
    },

    /**
     * Triggers a command to hide the loading view
     */
    hideLoading: function () {
      CommandBus.execute('loading:hide');
    },

    /**
     * Creates a new `NotFoundView` instance.
     *
     * @return {NotFoundView} New "Not found" view instance.
     */
    notFoundView: function () {
      return new NotFoundView();
    },

    /**
     * Creates a new `EmptyView` instance.
     *
     * @return {EmptyView} New "Empty" view instance.
     */
    emptyView: function () {
      return new EmptyView();
    },

    /**
     * Creates a new `LoadingView` instance.
     *
     * @return {LoadingView} New "Loading" view instance.
     */
    loadingView: function () {
      return new LoadingView();
    },

    /**
     * Creates a new ArchiveView instance for a post list.
     *
     * @param  {array}       posts Post collection to display.
     * @param  {int}         page  Page number.
     * @param  {Object}      filter The searching filter
     * @return {ArchiveView}       New archive view instance.
     */
    archiveView: function (posts, page, filter) {
      return new ArchiveView({collection: posts, page: page, filter: filter});
    },

    /**
     * Creates a new SinglePostView instance for a single post.
     *
     * @param  {Object}            posts Model to display.
     * @param  {int}               page  Page number.
     * @return {SinglePostView}       New single post view instance.
     */
    singlePostView: function (model, collection, page) {
      return new SinglePostView({model: model, page: page, collection: collection, user: this.user});
    }
  });
});<|endoftext|>


<commit_before>
Component = function (args) {
  this.parent = null;
  this.nameInParent = '';
  this.children = {};
  this.isInited = false;
  this.isBuilt = false;
  this.isAttached = false;
  this.isDestroyed = false;

  this.dom = null; // Chunk, if built
  this._fragment = null; // DocumentFragment, if built; empty when attached
  this._uniqueIdCounter = 1;

  this._args = args;
  this._argDeps = {};
};

_.extend(Component.prototype, {
  _requireAlive: function () {
    if (this.isDestroyed)
      throw new Error("Component was destroyed");
  },
  _forceInit: function () {
    this._requireAlive();
    if (! this.isInited) {
      this.init();
      this.isInited = true;
    }
  },
  _build: function () {
    this._forceInit();
    if (this.isBuilt)
      throw new Error("Component already built");

    this._fragment = document.createDocumentFragment();

    this.build(this._fragment);

    if (! this.dom)
      throw new Error("build() must call setBounds()");
    this.isBuilt = true;
    this.built();
  },
  attach: function (parent, before) {
    this._forceInit();
    if (this.isAttached)
      throw new Error("Component already attached");

    if (! this.isBuilt)
      this._build();

    parent.insertBefore(this._fragment, before);

    this.isAttached = true;

    this.attached();

    return this;
  },
  detach: function () {
    this._requireAlive();
    if (! this.isAttached)
      throw new Error("Component not attached");

    var start = this.dom.firstNode();
    var end = this.dom.lastNode();
    var frag = this._fragment;
    // extract start..end into frag
    var parent = start.parentNode;
    var before = start.previousSibling;
    var after = end.nextSibling;
    var n;
    while ((n = (before ? before.nextSibling : parent.firstChild)) &&
           (n !== after))
      frag.appendChild(n);

    this.isAttached = false;

    this.detached();

    return this;
  },
  destroy: function () {
    if (! this.isDestroyed) {
      this.isDestroyed = true;

      // maybe GC the DOM sooner
      this.dom = null;
      this._fragment = null;

      this.destroyed();

      var children = this.children;
      for (var k in children)
        if (children.hasOwnProperty(k))
          children[k].destroy();

      if (this.parent && ! this.parent.isDestroyed)
        delete this.parent.children[this.nameInParent];

      this.children = {};
    }

    return this;
  },
  hasChild: function (name) {
    return this.children.hasOwnProperty(name);
  },
  addChild: function (name, childComponent) {
    if (name instanceof Component) {
      // omitted name arg
      childComponent = name;
      name = null;
    }
    // omitted name, generate unique child ID
    if (name === null || typeof name === 'undefined')
      name = "__child#" + (this._uniqueIdCounter++) + "__";
    name = String(name);

    if (! (childComponent instanceof Component))
      throw new Error("not a Component: " + childComponent);

    this._requireAlive();
    if (this.hasChild(name))
      throw new Error("Already have a child named: " + name);

    if (childComponent.isDestroyed)
      throw new Error("Can't add a destroyed component");
    if (childComponent.isInited)
      throw new Error("Can't add a previously added or built component");

    this.children[name] = childComponent;

    childComponent._added(name, this);
  },
  setChild: function (name, childClass, childArgs) {
    name = String(name);

    this._requireAlive();
    if (this.hasChild(name)) {
      var oldChild = this.children[name];
      if (oldChild.constructor === childClass) {
        // old child present with same class
        oldChild.update(childArgs);
      } else {
        var newChild = new childClass(childArgs);
        if (oldChild.isAttached) {
          var beforeNode = oldChild.lastNode().nextSibling;
          var parentNode = oldChild.parentNode();
          this.removeChild(name);
          this.addChild(name, newChild);
          newChild.attach(parentNode, beforeNode);
        } else {
          this.addChild(newChild);
        }
      }
    } else {
      this.addChild(name, new childClass(childArgs));
    }
  },
  _added: function (name, parent) {
    name = String(name);
    this.nameInParent = name;
    this.parent = parent;

    this._forceInit();
  },
  removeChild: function (name) {
    name = String(name);
    this._requireAlive();
    if (! this.hasChild(name))
      throw new Error("No such child component: " + name);

    var childComponent = this.children[name];

    if (childComponent.isDestroyed) {
      // shouldn't be possible, because destroying a component
      // deletes it from the parent's children dictionary,
      // but just in case...
      delete this.children[name];
    } else {

      if (childComponent.isAttached)
        childComponent.detach();

      childComponent.destroy();

    }
  },
  setBounds: function (start, end) {
    end = end || start;
    if (start instanceof Component)
      start = start.dom;
    if (end instanceof Component)
      end = end.dom;

    if (! (start instanceof Chunk || (start && start.nodeType)))
      throw new Error("setBounds: start must be a built Component or a Node");
    if (! (end instanceof Chunk || (end && end.nodeType)))
      throw new Error("setBounds: end must be a built Component or a Node");

    if (! this.dom) {
      this.dom = new Chunk(start, end);
    } else {
      this.dom.set(start, end);
    }
  },
  setStart: function (start) {
    if (start instanceof Component)
      start = start.dom;

    if (! (start instanceof Chunk || (start && start.nodeType)))
      throw new Error("setStart: start must be a built Component or a Node");
    if (! this.dom)
      throw new Error("Can only call setStart after setBounds has been called");

    this.dom.start = start;
  },
  setEnd: function (end) {
    if (end instanceof Component)
      end = end.dom;

    if (! (end instanceof Chunk || (end && end.nodeType)))
      throw new Error("setEnd: end must be a built Component or a Node");
    if (! this.dom)
      throw new Error("Can only call setEnd after setBounds has been called");

    this.dom.end = end;
  },
  getArg: function (argName) {
    var dep = (this._argDeps.hasOwnProperty(argName) ?
               this._argDeps[argName] :
               (this._argDeps[argName] = new Deps.Dependency));
    dep.depend();
    return this._args[argName];
  },
  update: function (args) {
    var oldArgs = this._args;
    this._args = args;

    var argDeps = this._argDeps;

    for (var k in args) {
      if (args.hasOwnProperty(k) &&
          argDeps.hasOwnProperty(k) &&
          ! EJSON.equal(args[k], oldArgs[k])) {
        argDeps[k].invalidate();
        delete oldArgs[k];
      }
    }
    for (var k in oldArgs) {
      if (oldArgs.hasOwnProperty(k) &&
          argDeps.hasOwnProperty(k)) {
        argDeps[k].invalidate();
      }
    }

    this.updated(args, oldArgs);
  },
  findOne: function (selector) { return this.dom.findOne(selector); },
  findAll: function (selector) { return this.dom.findAll(selector); },
  firstNode: function () { return this.dom.firstNode(); },
  lastNode: function () { return this.dom.lastNode(); },
  parentNode: function () { return this.dom.parentNode(); },
  // Above methods are NOT overridable.
  //
  // These are all overridable, with the behavior that all implementations
  // are executed from super to sub.
  init: function () {},
  build: function (frag) {},
  built: function () {},
  attached: function () {},
  detached: function () {},
  destroyed: function () {},
  updated: function (args, oldArgs) {},
  // This is overridable but should probably get normal override behavior;
  // it has a return value and we only run one implementation.
  toHtml: function () {
    return '';
  }
});

Component.extend = function (options) {
  var superClass = this;
  var baseClass = Component;
  // all constructors just call the base constructor
  var newClass = function CustomComponent(/*args*/) {
    baseClass.apply(this, arguments);
  };

  // Establish a prototype link from newClass.prototype to
  // superClass.prototype.  This is similar to making
  // newClass.prototype a `new superClass` but bypasses
  // the constructor.
  var fakeSuperClass = function () {};
  fakeSuperClass.prototype = superClass.prototype;
  newClass.prototype = new fakeSuperClass;

  // Record the superClass for our future use.
  newClass.superClass = superClass;

  // Inherit class (static) properties from parent.
  _.extend(newClass, superClass);

  // For callbacks, call one in turn from super to sub.
  // Or rather, redefine each callback we are given to call
  // super method first.
  // XXX TODO: clean this up.
  // - General combining mechanism?  Filtering mechanism?
  // - Get the lookup hash out of here!
  _.each(options, function (v, k) {
    // important that we have a closure here to capture
    // each old function!
    var oldFunction = v;
    if ({init:1, build:1, built:1, attached:1, detached:1,
         destroyed:1, updated:1}.hasOwnProperty(k)) {
      options[k] = function () {
        superClass.prototype[k].apply(this, arguments);
        oldFunction.apply(this, arguments);
      };
    }
  });

  // Add instance properties and methods.
  if (options)
    _.extend(newClass.prototype, options);

  // For browsers that don't support it, fill in `obj.constructor`.
  newClass.prototype.constructor = newClass;

  return newClass;
};
<commit_msg>component model next rev WIP<commit_after>Component = function (args) {
  this.stage = Component.UNADDED;

  this._uniqueIdCounter = 1;

  // UNINITED Components get these:
  this._args = args;
  this._argDeps = {};

  // INITED Components get these:
  this.key = '';
  this.parent = null;
  this.children = {};

  // BUILT Components get these:
  this._start = null; // first Component or Node
  this._end = null; // last Component or Node
};

// life stages of a Component
_.extend(Component, {
  UNADDED: ['UNADDED'],
  ADDED: ['ADDED'],
  BUILT: ['BUILT'],
  DESTROYED: ['DESTROYED']
});

_.extend(Component.prototype, {
  _requireStage: function (stage) {
    if (this.stage !== stage)
      throw new Error("Need a " + stage + " Component, found a " +
                      this.stage + " Component.");
  },
  _added: function (key, parent) {
    this._requireStage(Component.UNADDED);
    this.key = key;
    this.parent = parent;
    this.stage = Component.ADDED;
  },
  destroy: function () {
    // Leaves the DOM in place

    if (this.stage === Component.DESTROYED)
      return;

    var oldStage = this.stage;
    this.stage = Component.DESTROYED;

    if (oldStage === Component.UNADDED)
      return;

    // maybe GC sooner
    this._start = null;
    this._end = null;

    this.destroyed();

    var children = this.children;
    for (var k in children)
      if (children.hasOwnProperty(k))
        children[k].destroy();

    if (this.parent)
      delete this.parent.children[this.key];

    this.children = {};
  }
});

// Once the Component is built, if the Component implementation
// modifies the DOM composition of the Component, it must specify
// the new bounds using some combination of these.
_.extend(Component.prototype, {
  setStart: function (start) {
    this._requireStage(Component.BUILT);

    if (! ((start instanceof Component &&
            start.stage === Component.BUILT) ||
           (start && start.nodeType)))
      throw new Error("start must be a built Component or a Node");

    this._start = start;
  },
  setEnd: function (end) {
    this._requireStage(Component.BUILT);

    if (! ((end instanceof Component &&
            end.stage === Component.BUILT) ||
           (end && end.nodeType)))
      throw new Error("end must be a built Component or a Node");

    this._end = end;
  },
  setBounds: function (start, end) {
    end = end || start;
    this.setStart(start);
    this.setEnd(end);
  },
  firstNode: function () {
    this._requireStage(Component.BUILT);
    return this._start instanceof Component ?
      this._start.firstNode() : this._start;
  },
  lastNode: function () {
    this._requireStage(Component.BUILT);
    return this._end instanceof Component ?
      this._end.lastNode() : this._end;
  },
  parentNode: function () {
    return this.firstNode().parentNode;
  },
  findOne: function (selector) {
    return DomUtils.findClipped(
      this.parentNode(), selector,
      this.firstNode(), this.lastNode());
  },
  findAll: function (selector) {
    return DomUtils.findAllClipped(
      this.parentNode(), selector,
      this.firstNode(), this.lastNode());
  }
});

_.extend(Component.prototype, {
  getArg: function (argName) {
    var dep = (this._argDeps.hasOwnProperty(argName) ?
               this._argDeps[argName] :
               (this._argDeps[argName] = new Deps.Dependency));
    dep.depend();
    return this._args[argName];
  },
  update: function (args) {
    var oldArgs = this._args;
    this._args = args;

    var argDeps = this._argDeps;

    for (var k in args) {
      if (args.hasOwnProperty(k) &&
          argDeps.hasOwnProperty(k) &&
          ! EJSON.equal(args[k], oldArgs[k])) {
        argDeps[k].invalidate();
        delete oldArgs[k];
      }
    }
    for (var k in oldArgs) {
      if (oldArgs.hasOwnProperty(k) &&
          argDeps.hasOwnProperty(k)) {
        argDeps[k].invalidate();
      }
    }

    this.updated(args, oldArgs);
  }
});

_.extend(Component.prototype, {
  hasChild: function (key) {
    return this.children.hasOwnProperty(key);
  },
  addChild: function (key, childComponent) {
    if (key instanceof Component) {
      // omitted key arg
      childComponent = key;
      key = null;
    }
    // omitted key, generate unique child key
    if (key === null || typeof key === 'undefined')
      key = "__child#" + (this._uniqueIdCounter++) + "__";
    key = String(key);

    if (! (childComponent instanceof Component))
      throw new Error("not a Component: " + childComponent);

    this._requireStage(Component.ADDED);
    childComponent._requireStage(Component.UNADDED);

    if (this.hasChild(key))
      throw new Error("Already have a child with key: " + key);

    this.children[key] = childComponent;

    childComponent._added(key, this);
  }
});

_.extend(Component.prototype, {
  render: function (builder) {},
  updated: function (args, oldArgs) {},
  destroyed: function () {}
});

//////////////////////////////////////////////////

Component = function (args) {
  this.parent = null;
  this.nameInParent = '';
  this.children = {};
  this.isInited = false;
  this.isBuilt = false;
  this.isAttached = false;
  this.isDestroyed = false;

  this.dom = null; // Chunk, if built
  this._fragment = null; // DocumentFragment, if built; empty when attached
  this._uniqueIdCounter = 1;

  this._args = args;
  this._argDeps = {};
};

_.extend(Component.prototype, {
  _requireAlive: function () {
    if (this.isDestroyed)
      throw new Error("Component was destroyed");
  },
  _forceInit: function () {
    this._requireAlive();
    if (! this.isInited) {
      this.init();
      this.isInited = true;
    }
  },
  _build: function () {
    this._forceInit();
    if (this.isBuilt)
      throw new Error("Component already built");

    this._fragment = document.createDocumentFragment();

    this.build(this._fragment);

    if (! this.dom)
      throw new Error("build() must call setBounds()");
    this.isBuilt = true;
    this.built();
  },
  attach: function (parent, before) {
    this._forceInit();
    if (this.isAttached)
      throw new Error("Component already attached");

    if (! this.isBuilt)
      this._build();

    parent.insertBefore(this._fragment, before);

    this.isAttached = true;

    this.attached();

    return this;
  },
  detach: function () {
    this._requireAlive();
    if (! this.isAttached)
      throw new Error("Component not attached");

    var start = this.dom.firstNode();
    var end = this.dom.lastNode();
    var frag = this._fragment;
    // extract start..end into frag
    var parent = start.parentNode;
    var before = start.previousSibling;
    var after = end.nextSibling;
    var n;
    while ((n = (before ? before.nextSibling : parent.firstChild)) &&
           (n !== after))
      frag.appendChild(n);

    this.isAttached = false;

    this.detached();

    return this;
  },
  destroy: function () {
    if (! this.isDestroyed) {
      this.isDestroyed = true;

      // maybe GC the DOM sooner
      this.dom = null;
      this._fragment = null;

      this.destroyed();

      var children = this.children;
      for (var k in children)
        if (children.hasOwnProperty(k))
          children[k].destroy();

      if (this.parent && ! this.parent.isDestroyed)
        delete this.parent.children[this.nameInParent];

      this.children = {};
    }

    return this;
  },
  hasChild: function (name) {
    return this.children.hasOwnProperty(name);
  },
  addChild: function (name, childComponent) {
    if (name instanceof Component) {
      // omitted name arg
      childComponent = name;
      name = null;
    }
    // omitted name, generate unique child ID
    if (name === null || typeof name === 'undefined')
      name = "__child#" + (this._uniqueIdCounter++) + "__";
    name = String(name);

    if (! (childComponent instanceof Component))
      throw new Error("not a Component: " + childComponent);

    this._requireAlive();
    if (this.hasChild(name))
      throw new Error("Already have a child named: " + name);

    if (childComponent.isDestroyed)
      throw new Error("Can't add a destroyed component");
    if (childComponent.isInited)
      throw new Error("Can't add a previously added or built component");

    this.children[name] = childComponent;

    childComponent._added(name, this);
  },
  setChild: function (name, childClass, childArgs) {
    name = String(name);

    this._requireAlive();
    if (this.hasChild(name)) {
      var oldChild = this.children[name];
      if (oldChild.constructor === childClass) {
        // old child present with same class
        oldChild.update(childArgs);
      } else {
        var newChild = new childClass(childArgs);
        if (oldChild.isAttached) {
          var beforeNode = oldChild.lastNode().nextSibling;
          var parentNode = oldChild.parentNode();
          this.removeChild(name);
          this.addChild(name, newChild);
          newChild.attach(parentNode, beforeNode);
        } else {
          this.addChild(newChild);
        }
      }
    } else {
      this.addChild(name, new childClass(childArgs));
    }
  },
  _added: function (name, parent) {
    name = String(name);
    this.nameInParent = name;
    this.parent = parent;

    this._forceInit();
  },
  removeChild: function (name) {
    name = String(name);
    this._requireAlive();
    if (! this.hasChild(name))
      throw new Error("No such child component: " + name);

    var childComponent = this.children[name];

    if (childComponent.isDestroyed) {
      // shouldn't be possible, because destroying a component
      // deletes it from the parent's children dictionary,
      // but just in case...
      delete this.children[name];
    } else {

      if (childComponent.isAttached)
        childComponent.detach();

      childComponent.destroy();

    }
  },
  setBounds: function (start, end) {
    end = end || start;
    if (start instanceof Component)
      start = start.dom;
    if (end instanceof Component)
      end = end.dom;

    if (! (start instanceof Chunk || (start && start.nodeType)))
      throw new Error("setBounds: start must be a built Component or a Node");
    if (! (end instanceof Chunk || (end && end.nodeType)))
      throw new Error("setBounds: end must be a built Component or a Node");

    if (! this.dom) {
      this.dom = new Chunk(start, end);
    } else {
      this.dom.set(start, end);
    }
  },
  setStart: function (start) {
    if (start instanceof Component)
      start = start.dom;

    if (! (start instanceof Chunk || (start && start.nodeType)))
      throw new Error("setStart: start must be a built Component or a Node");
    if (! this.dom)
      throw new Error("Can only call setStart after setBounds has been called");

    this.dom.start = start;
  },
  setEnd: function (end) {
    if (end instanceof Component)
      end = end.dom;

    if (! (end instanceof Chunk || (end && end.nodeType)))
      throw new Error("setEnd: end must be a built Component or a Node");
    if (! this.dom)
      throw new Error("Can only call setEnd after setBounds has been called");

    this.dom.end = end;
  },
  getArg: function (argName) {
    var dep = (this._argDeps.hasOwnProperty(argName) ?
               this._argDeps[argName] :
               (this._argDeps[argName] = new Deps.Dependency));
    dep.depend();
    return this._args[argName];
  },
  update: function (args) {
    var oldArgs = this._args;
    this._args = args;

    var argDeps = this._argDeps;

    for (var k in args) {
      if (args.hasOwnProperty(k) &&
          argDeps.hasOwnProperty(k) &&
          ! EJSON.equal(args[k], oldArgs[k])) {
        argDeps[k].invalidate();
        delete oldArgs[k];
      }
    }
    for (var k in oldArgs) {
      if (oldArgs.hasOwnProperty(k) &&
          argDeps.hasOwnProperty(k)) {
        argDeps[k].invalidate();
      }
    }

    this.updated(args, oldArgs);
  },
  findOne: function (selector) { return this.dom.findOne(selector); },
  findAll: function (selector) { return this.dom.findAll(selector); },
  firstNode: function () { return this.dom.firstNode(); },
  lastNode: function () { return this.dom.lastNode(); },
  parentNode: function () { return this.dom.parentNode(); },
  // Above methods are NOT overridable.
  //
  // These are all overridable, with the behavior that all implementations
  // are executed from super to sub.
  init: function () {},
  build: function (frag) {},
  built: function () {},
  attached: function () {},
  detached: function () {},
  destroyed: function () {},
  updated: function (args, oldArgs) {},
  // This is overridable but should probably get normal override behavior;
  // it has a return value and we only run one implementation.
  toHtml: function () {
    return '';
  }
});

////////////////////

Component.extend = function (options) {
  var superClass = this;
  var baseClass = Component;
  // all constructors just call the base constructor
  var newClass = function CustomComponent(/*args*/) {
    baseClass.apply(this, arguments);
  };

  // Establish a prototype link from newClass.prototype to
  // superClass.prototype.  This is similar to making
  // newClass.prototype a `new superClass` but bypasses
  // the constructor.
  var fakeSuperClass = function () {};
  fakeSuperClass.prototype = superClass.prototype;
  newClass.prototype = new fakeSuperClass;

  // Record the superClass for our future use.
  newClass.superClass = superClass;

  // Inherit class (static) properties from parent.
  _.extend(newClass, superClass);

  // For callbacks, call one in turn from super to sub.
  // Or rather, redefine each callback we are given to call
  // super method first.
  // XXX TODO: clean this up.
  // - General combining mechanism?  Filtering mechanism?
  // - Get the lookup hash out of here!
  _.each(options, function (v, k) {
    // important that we have a closure here to capture
    // each old function!
    var oldFunction = v;
    if ({init:1, build:1, built:1, attached:1, detached:1,
         destroyed:1, updated:1}.hasOwnProperty(k)) {
      options[k] = function () {
        superClass.prototype[k].apply(this, arguments);
        oldFunction.apply(this, arguments);
      };
    }
  });

  // Add instance properties and methods.
  if (options)
    _.extend(newClass.prototype, options);

  // For browsers that don't support it, fill in `obj.constructor`.
  newClass.prototype.constructor = newClass;

  return newClass;
};
<|endoftext|>


<commit_before>/*
*    Licensed to the Apache Software Foundation (ASF) under one or more
*    contributor license agreements.  See the NOTICE file distributed with
*    this work for additional information regarding copyright ownership.
*    The ASF licenses this file to You 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.
*/
import Ember from 'ember';

export default Ember.Component.extend({
  mkdirORdeleteORtouchz: true,
  mkdir: 1,
  delete: 0,
  touchz: 0,
  chmod: 0,
  move: 0,
  chgrp: 0,
  multivalued: true,
  prepareType: 'mkdir',
  fileBrowser: Ember.inject.service('file-browser'),
  initialize: function() {
    this.on('fileSelected', (fileName)=>{
      var filePathModel = this.get('filePathModel');
      if(filePathModel && filePathModel.hasOwnProperty("index") && filePathModel.hasOwnProperty("property")){
        var fileOperation = this.get('fsOps').objectAt(filePathModel.index);
        var settings = fileOperation.settings;
        Ember.set(settings, filePathModel.property, fileName);
        Ember.set(fileOperation, "settings", settings);
      }else{
        this.set(this.get('filePathModel'), fileName);
      }
    }.bind(this));
    this.on('bindInputPlaceholder', function() {
      this.set('addUnboundValue', true);
    }.bind(this));
    this.sendAction('register', 'fsOps', this);
  }.on('init'),
  bindInputPlaceholder: function() {
    let type = this.get("prepareType");
    if (this.validateOperations(type)) {
      let value = this.get("prepareType");
      if (value === "chgrp" && this.get('path') && this.get('group')) {
        this.addPrepare();
      } else if (value === "move" && this.get('source') && this.get('target')) {
        this.addPrepare();
      } else if (value === "chmod" && this.get('path')) {
        this.addPrepare();
      } else if (value === "mkdir" || value === "delete" || value === "touchz" && this.get('path')) {
        this.addPrepare();
      }
    }
  }.on('willDestroyElement'),
  formPermissions(r, w, e, type){
    var perm = 0, permObj = {};
    if(r){
      perm = perm+4;
      permObj[type+"read"] = true;
    }
    if(w){
      perm = perm+2;
      permObj[type+"write"] = true;
    }
    if(e){
      perm = perm+1;
      permObj[type+"execute"] = true;
    }
    permObj[type+"perm"] = perm;
    return permObj;
  },
  addPrepare: function() {

    let value = this.get("prepareType");
    switch (value) {
      case "mkdir":
      case "delete":
      case "touchz":
      this.get('fsOps').pushObject({
        path :this.get('path'),
        type: value
      });
      break;
      case "chmod":
      var oPerm = this.formPermissions(this.get("oread"), this.get("owrite"), this.get("oexecute"), "o");
      var gPerm = this.formPermissions(this.get("gread"), this.get("gwrite"), this.get("gexecute"), "g");
      var rPerm = this.formPermissions(this.get("rread"), this.get("rwrite"), this.get("rexecute"), "r");
      var permissionsObj = {};
      permissionsObj = Ember.$.extend(true, oPerm, gPerm);
      permissionsObj = Ember.$.extend(true, permissionsObj, rPerm);
      var perm = oPerm.operm + ""+ gPerm.gperm + ""+ rPerm.rperm;
      this.get('fsOps').pushObject({
          path: this.get('path'),
          permissions: perm,
          permissionsObj: permissionsObj,
          recursive: this.get('recursive'),
          dirfiles: this.get('dirFiles'),
        type: value
      });
      break;
      case "chgrp":
      this.get('fsOps').pushObject({
          path: this.get('path'),
          group: this.get('group'),
          recursive: this.get('recursive'),
          dirfiles: this.get('dirFiles'),
        type: value
      });
      break;
      case "move":
      this.get('fsOps').pushObject({
          source: this.get('source'),
          target: this.get('target'),
        type: value
      });
      break;
    }
    this.resetFields();
  },
  resetFields: function() {
    this.set('prepareType', "mkdir");
    this.set('path', "");
    this.set('source', "");
    this.set('target', "");
    this.set('group', "");
    this.set('permissions', "");
    this.set('recursive', false);
    this.set('dirFiles', false);
  },
  toggleAllFields: function() {
    this.set("mkdir", 0);
    this.set("delete", 0);
    this.set("chmod", 0);
    this.set("touchz", 0);
    this.set("chmod", 0);
    this.set("move", 0);
    this.set("chgrp", 0);
  },
  validateOperations: function(type) {
    var flag = true;
    switch (type) {
      case "mkdir":
      case "delete":
      case "touchz":
      if (!this.get('path')) {
        flag = false;
      }
      break;
      case "chmod":
      if (!this.get('path')) {
        flag = false;
      }
      break;
      case "chgrp":
      if (!this.get('path') || !this.get('group')) {
        flag = false;
      }
      break;
      case "move":
      if (!this.get('source') || !this.get('target')) {
        flag = false;
      }
      break;
    }
    return flag;
  },
  actions: {
    onPrepareTypeChange(value) {
      this.set('prepareType', value);
      this.toggleAllFields();
      this.set(value, 1);
      if (value === "mkdir" || value === "delete" || value === "touchz") {
        this.set("mkdirORdeleteORtouchz", true);
      } else {
        this.set("mkdirORdeleteORtouchz", false);
      }
    },
    addPrepare() {
      this.addPrepare();
    },
    deletePrepare(index) {
      this.get('fsOps').removeAt(index);
    },
    openFileBrowser(model) {
      this.set('filePathModel', model);
      this.sendAction("openFileBrowser", model, this);
    },
    openFileBrowserForListItem(index, property){
      this.set('filePathModel',{index:index, property:property});
      this.sendAction("openFileBrowser", this.get('filePathModel'), this);
    }
  }
});
<commit_msg>AMBARI-19729: Workflow Manager: Path does not get set to selected directory when creating FS action node. (sangeetar)<commit_after>/*
*    Licensed to the Apache Software Foundation (ASF) under one or more
*    contributor license agreements.  See the NOTICE file distributed with
*    this work for additional information regarding copyright ownership.
*    The ASF licenses this file to You 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.
*/
import Ember from 'ember';

export default Ember.Component.extend({
  mkdirORdeleteORtouchz: true,
  mkdir: 1,
  delete: 0,
  touchz: 0,
  chmod: 0,
  move: 0,
  chgrp: 0,
  multivalued: true,
  prepareType: 'mkdir',
  fileBrowser: Ember.inject.service('file-browser'),
  initialize: function() {
    this.on('fileSelected', (fileName)=>{
      var filePathModel = this.get('filePathModel');
      if(filePathModel && filePathModel.hasOwnProperty("index") && filePathModel.hasOwnProperty("property")){
        var fileOperation = this.get('fsOps').objectAt(filePathModel.index);
        Ember.set(fileOperation, filePathModel.property, fileName);
      }else{
        this.set(this.get('filePathModel'), fileName);
      }
    }.bind(this));
    this.on('bindInputPlaceholder', function() {
      this.set('addUnboundValue', true);
    }.bind(this));
    this.sendAction('register', 'fsOps', this);
  }.on('init'),
  bindInputPlaceholder: function() {
    let type = this.get("prepareType");
    if (this.validateOperations(type)) {
      let value = this.get("prepareType");
      if (value === "chgrp" && this.get('path') && this.get('group')) {
        this.addPrepare();
      } else if (value === "move" && this.get('source') && this.get('target')) {
        this.addPrepare();
      } else if (value === "chmod" && this.get('path')) {
        this.addPrepare();
      } else if (value === "mkdir" || value === "delete" || value === "touchz" && this.get('path')) {
        this.addPrepare();
      }
    }
  }.on('willDestroyElement'),
  formPermissions(r, w, e, type){
    var perm = 0, permObj = {};
    if(r){
      perm = perm+4;
      permObj[type+"read"] = true;
    }
    if(w){
      perm = perm+2;
      permObj[type+"write"] = true;
    }
    if(e){
      perm = perm+1;
      permObj[type+"execute"] = true;
    }
    permObj[type+"perm"] = perm;
    return permObj;
  },
  addPrepare: function() {

    let value = this.get("prepareType");
    switch (value) {
      case "mkdir":
      case "delete":
      case "touchz":
      this.get('fsOps').pushObject({
        path :this.get('path'),
        type: value
      });
      break;
      case "chmod":
      var oPerm = this.formPermissions(this.get("oread"), this.get("owrite"), this.get("oexecute"), "o");
      var gPerm = this.formPermissions(this.get("gread"), this.get("gwrite"), this.get("gexecute"), "g");
      var rPerm = this.formPermissions(this.get("rread"), this.get("rwrite"), this.get("rexecute"), "r");
      var permissionsObj = {};
      permissionsObj = Ember.$.extend(true, oPerm, gPerm);
      permissionsObj = Ember.$.extend(true, permissionsObj, rPerm);
      var perm = oPerm.operm + ""+ gPerm.gperm + ""+ rPerm.rperm;
      this.get('fsOps').pushObject({
          path: this.get('path'),
          permissions: perm,
          permissionsObj: permissionsObj,
          recursive: this.get('recursive'),
          dirfiles: this.get('dirFiles'),
        type: value
      });
      break;
      case "chgrp":
      this.get('fsOps').pushObject({
          path: this.get('path'),
          group: this.get('group'),
          recursive: this.get('recursive'),
          dirfiles: this.get('dirFiles'),
        type: value
      });
      break;
      case "move":
      this.get('fsOps').pushObject({
          source: this.get('source'),
          target: this.get('target'),
        type: value
      });
      break;
    }
    this.resetFields();
  },
  resetFields: function() {
    this.set('prepareType', "mkdir");
    this.set('path', "");
    this.set('source', "");
    this.set('target', "");
    this.set('group', "");
    this.set('permissions', "");
    this.set('recursive', false);
    this.set('dirFiles', false);
  },
  toggleAllFields: function() {
    this.set("mkdir", 0);
    this.set("delete", 0);
    this.set("chmod", 0);
    this.set("touchz", 0);
    this.set("chmod", 0);
    this.set("move", 0);
    this.set("chgrp", 0);
  },
  validateOperations: function(type) {
    var flag = true;
    switch (type) {
      case "mkdir":
      case "delete":
      case "touchz":
      if (!this.get('path')) {
        flag = false;
      }
      break;
      case "chmod":
      if (!this.get('path')) {
        flag = false;
      }
      break;
      case "chgrp":
      if (!this.get('path') || !this.get('group')) {
        flag = false;
      }
      break;
      case "move":
      if (!this.get('source') || !this.get('target')) {
        flag = false;
      }
      break;
    }
    return flag;
  },
  actions: {
    onPrepareTypeChange(value) {
      this.set('prepareType', value);
      this.toggleAllFields();
      this.set(value, 1);
      if (value === "mkdir" || value === "delete" || value === "touchz") {
        this.set("mkdirORdeleteORtouchz", true);
      } else {
        this.set("mkdirORdeleteORtouchz", false);
      }
    },
    addPrepare() {
      this.addPrepare();
    },
    deletePrepare(index) {
      this.get('fsOps').removeAt(index);
    },
    openFileBrowser(model) {
      this.set('filePathModel', model);
      this.sendAction("openFileBrowser", model, this);
    },
    openFileBrowserForListItem(index, property){
      this.set('filePathModel',{index:index, property:property});
      this.sendAction("openFileBrowser", this.get('filePathModel'), this);
    }
  }
});
<|endoftext|>