<commit_before>
/* Extend jQuery with functions for PUT and DELETE requests. */

function _ajax_request(url, data, callback, type, method) {
    if (jQuery.isFunction(data)) {
        callback = data;
        data = {};
    }
    return jQuery.ajax({
        type: method,
        url: url,
        data: data,
        success: callback,
        dataType: type
        });
}

jQuery.extend({
    put: function(url, data, callback, type) {
        return _ajax_request(url, data, callback, type, 'PUT');
    },
    delete_: function(url, data, callback, type) {
        return _ajax_request(url, data, callback, type, 'DELETE');
    }
});

jQuery.fn.centerOnScreen = function(){
    var win_width      = jQuery(window).width();
    var scrollToLeft   = jQuery(window).scrollLeft();
    var win_height     = jQuery(window).height();
    var scrollToBottom = jQuery(window).scrollTop();
	var box_width = 200;
	var box_height = 200;

	this.css('position', 'absolute');
	this.css('z-index', (1000+(Math.round(Math.random() * 5000))));

	var x = ((jQuery(window).width() / 2) - (this.width() / 2)) + jQuery(window).scrollLeft();
	var y  = ((jQuery(window).height() / 2) - (this.height() / 2)) + jQuery(window).scrollTop();
	if(x < 0) { x = 0; }; if(y < 0) { y = 0; }

	this.css({ left: x+"px", top: y+"px" });

	return this;
}

function jRichTextArea(textArea, options){
	this.textArea = textArea;

	// Default options
	settings = jQuery.extend({
	     className: "richTextToolbar"
	}, options);

	this.toolbar = {
		settings : settings,
		textArea : textArea,
		listElement : false,
		buttons : new Array(),
		addButton : function(name, callback, options) {
			// Default options
			settings = jQuery.extend({
			     className: name.replace(/[\s]+/, '')+"Button"
			}, options);
			var li = document.createElement("li");
			var a = document.createElement("a");
			a.title = name;
			a.textArea = this.textArea;
			//callback.this = this;
			jQuery(a).click(callback);
			jQuery(a).addClass(settings.className);
			jQuery(li).append(a).appendTo(this.listElement);
			this.buttons.push(li);
			return this;
		},
		create : function() {
			if(!this.listElement) {
				this.listElement = document.createElement("ul");
				jQuery(this.listElement).addClass(this.settings.className);
				jQuery(this.listElement).insertBefore(this.textArea);
			}
		}
	}

	this.textArea.selectedText = function() {
		return jQuery(this).getSelection().text;
	}
	this.textArea.replaceSelection = function(replacement) {
		return jQuery(this).replaceSelection(replacement);
	}
	this.textArea.wrapSelection = function() {
		var prepend = arguments[0];
		var append = (arguments.length > 1) ? arguments[1] : prepend
		return this.replaceSelection(prepend + this.selectedText() + append);
	}

	// Delegates
	this.textArea.toolbar = this.toolbar;
	this.toolbar.create();
}

function EditableImage(link, options){

	// Default options
	settings = jQuery.extend({
		resourceURL: link.href,
		width: 550
	}, options);

	this.editableImage = {
		settings : settings,
		link : link,
		linkedImage : jQuery(link).children('img')[0],
		resourceURL : settings.resourceURL,
		editorDialog : false,
		imageData : false,
		previewURL : false,
		cropStartX : false,
		cropStartY : false,
		cropWidth : false,
		cropHeight : false,
		getScale : function() {
			return (this.settings.width / this.imageData.original_width);
		},
		openEditor : function() {
			// Dim the screen and create the loading dialog
			jQuery.dimScreen(200, 0.90);
			jQuery('body').append("
 Loading image editor…
");
			jQuery('#modalLoadingNotice').centerOnScreen().hide().fadeIn(200);

			// Create the container
			jQuery('#editableImageEditor').remove();
			jQuery('body').append("

");

			// Load data
			var binding = this;
			if(!this.imageData){
				jQuery.getJSON(this.resourceURL+".js", function(json){
					binding.imageData = json;
					binding.populateEditor();
				});
			} else {
				this.populateEditor();
			}
		},
		populateEditor : function() {
			jQuery('#editableImageEditor')
				.empty()
				.append("")
				.append("
")
				.hide();
			jQuery('#editableImageEditorControls')
				.append("<input type=\"button\" id=\"editableImageEditorSubmit\" value=\"Save\" />")
				.append("<input type=\"button\" id=\"editableImageEditorClose\" value=\"Cancel\" />")

			this.previewURL = this.linkedImage.src.replace(this.linkedImage.src.match(/([\d]*x[\d]*)/)[1], 'original/'+this.settings.width+'x');

			var binding = this;
			jQuery('#editableImageEditorImage').each(function(){
				this.src = binding.previewURL;
			});
			jQuery('#editableImageEditorSubmit').click(function(){
				binding.submit();
			});
			jQuery('#editableImageEditorClose').click(function(){
				binding.closeEditor();
			});

			var onCrop = function(coords) {
				binding.cropStartX = coords.x;
				binding.cropStartY = coords.y;
				binding.cropWidth = coords.w;
				binding.cropHeight = coords.h;
			}
			jQuery('#editableImageEditorImage').load(function(){
				jQuery('#modalLoadingNotice').fadeOut(100);
				jQuery('#editableImageEditor').show().centerOnScreen();
				var jCropOptions = {
					onChange: onCrop,
					onSelect: onCrop
				}
				var imageData = binding.imageData;
				if(imageData.cropped) {
					var crop_start_x = Math.round(imageData.crop_start_x * binding.getScale());
					var crop_start_y = Math.round(imageData.crop_start_y * binding.getScale());
					var crop_end_x = crop_start_x + Math.round(imageData.crop_width * binding.getScale());
					var crop_end_y = crop_start_y + Math.round(imageData.crop_height * binding.getScale());
					jCropOptions['setSelect'] = [crop_start_x, crop_start_y, crop_end_x, crop_end_y];
				}
				console.log(jCropOptions);
				jQuery('#editableImageEditorImage').Jcrop(jCropOptions);
			});

		},
		closeEditor : function() {
			jQuery('#modalLoadingNotice').remove();
			jQuery('#editableImageEditor').remove();
			this.imageData = false;
			jQuery.dimScreenStop();
		},
		refreshLinkedImage : function() {
			var newURL = this.linkedImage.src.toString();
			newURL = newURL+"?"+Math.round(Math.random() * 65535);
			this.linkedImage.src = newURL;
		},
		submit : function() {
			var cropped = (!this.cropWidth || !this.cropHeight) ? 0 : 1;
			var crop_start = false;
			var crop_size  = false;
			var put_options = false;
			if(cropped) {
				crop_size = Math.floor(this.cropWidth/this.getScale())+"x"+Math.floor(this.cropHeight/this.getScale());
				crop_start = Math.floor(this.cropStartX/this.getScale())+"x"+Math.floor(this.cropStartY/this.getScale());
				put_options = { 'image[cropped]': cropped, 'image[crop_size]': crop_size, 'image[crop_start]': crop_start }
			} else {
				put_options = { 'image[cropped]': cropped }
			}
			var binding = this;
			jQuery.put(this.resourceURL+".js", put_options, function(){
				binding.refreshLinkedImage();
				binding.closeEditor();
			})
		}
	}

	// Apply onClick behaviour
	link.editableImage = this.editableImage;
	jQuery(link).click(function(){
		this.editableImage.openEditor();
		return false;
	});

	//this.editableImage.openEditor(); // debug
}

var PagesAdmin = {

	controller : false,
	action : false,

	sniffBrowser : function() {
		if(navigator) {
			jQuery.each(Array("WebKit","Gecko","Firefox"), function(){
				if( navigator.userAgent.match( new RegExp(this+"\\/[\\d]+", 'i'))) {
					jQuery(document.body).addClass(this.toLowerCase());
				}
			});
			if(navigator.userAgent.match("MSIE")) {
				jQuery(document.body).addClass('msie')
			};
			if( navigator.userAgent.match("MSIE 7") ) {
				jQuery(document.body).addClass('msie7');
			}
		}
	},

	applyTextAreas : function() {
		jQuery('textarea.rich').each(function(){
			var ta = new jRichTextArea(this);

			// Add buttons to the field
			ta.toolbar
				// Bold
				.addButton("Bold", function(){ this.textArea.wrapSelection('*'); })
				// Italic
				.addButton("Italics", function(){ this.textArea.wrapSelection('_'); })
				// Headings
				.addButton("Heading 2", function(){ this.textArea.wrapSelection('h2. ',''); })
				.addButton("Heading 3", function(){ this.textArea.wrapSelection('h3. ',''); })
				.addButton("Heading 4", function(){ this.textArea.wrapSelection('h4. ',''); })
				// Links
				.addButton("Link", function(){
				    var selection = this.textArea.selectedText();
				    var response = prompt('Enter link URL','');
				    this.textArea.replaceSelection(
						'"' + (selection == '' ? "Link text" : selection) + '":' +
						(response == '' ? 'http://link_url/' : response).replace(/^(?!(f|ht)tps?:\/\/)/,'http://')
					);
				})
				// Email links
				.addButton("Email", function(){
				    var selection = this.textArea.selectedText();
				    var response = prompt('Enter mail address','');
				    this.textArea.replaceSelection(
						'"' + (selection == '' ? "Link text" : selection) + '":mailto:' +
						(response == '' ? 'support@manualdesign.no' : response)
					);
				})
				// Image tag
				.addButton("Image", function(){
				    var selection = this.textArea.selectedText();
					if( selection == '') {
					    var response = prompt('Enter image URL','');
					    if(response == null)
					        return;
						this.textArea.replaceSelection('!'+response+'!');
					} else {
						this.textArea.replaceSelection('!'+selection+'!');
					}
				})
			;
		});
	},

	applyEditableImages : function() {
		jQuery('a.editableImage').each(function(){
			new EditableImage(this);
		});
	},

	applyStyles : function() {
		// Detect the sidebar and add the appropriate class to the document element.
		if(jQuery('#sidebar').length > 0){
			jQuery(document.body).addClass('with_sidebar');
		}

		// Add input_$type class to inputs.
		jQuery('input').each(function(i){jQuery(this).addClass("input_"+this.type);});

		// Inject buttons with

		jQuery('button').wrapInner('

');

	},

	init : function() {
		PagesAdmin.sniffBrowser();
		PagesAdmin.applyStyles();
		PagesAdmin.applyEditableImages();
		PagesAdmin.applyTextAreas();
		if(PagesAdmin.contentTabs) {
			PagesAdmin.contentTabs.init();
		}

		// Call the controller action
		if(PagesAdmin.controller) {
			if(PagesAdmin.controller.init){
				PagesAdmin.controller.init();
			}
			if(PagesAdmin.action && PagesAdmin.controller[PagesAdmin.action]) {
				PagesAdmin.controller[PagesAdmin.action]();
			}
		}
	}
}
var Admin = PagesAdmin;

PagesAdmin.contentTabs = {

	tabs : new Array(),
	ids : new Array(),

	show : function(tab_id) {
		var tabs = PagesAdmin.contentTabs.tabs;
		var tab = tabs[tab_id];
		if(tab) {
			jQuery.each(PagesAdmin.contentTabs.ids, function(i){
				if(tabs[this]) {
					jQuery(tabs[this]).hide();
				} else {
					console.log("Could not hide tab: "+this);
				}
				jQuery("#content-tab-link-"+this).removeClass('current');
			});
			jQuery(tab).show();
			jQuery("#content-tab-link-"+tab_id).addClass('current');
		}
	},

	showFromURL : function(url) {
		var tab_expression = /#(.*)$/
		if(url.toString().match(tab_expression)){
			var tab_id = url.toString().match(tab_expression)[1];
			if(PagesAdmin.contentTabs.tabs[tab_id]){
				PagesAdmin.contentTabs.show(tab_id);
			}
		}
	},

	enable : function(tab_ids) {
		//PagesAdmin.contentTabs.tabs = new Array();
		var tabs = PagesAdmin.contentTabs.tabs;
		PagesAdmin.contentTabs.ids = tab_ids;
		jQuery.each(tab_ids, function(i) {
			var tab_id = this;
			jQuery("#content-tab-"+this).each(function(i){
				this.tab_id = tab_id;
				tabs[tab_id] = this;
			});
		});
		PagesAdmin.contentTabs.show(tab_ids[0]);
		PagesAdmin.contentTabs.showFromURL(document.location);
	},

	init : function() {
		if(jQuery('#content-tabs').length > 0) {
			jQuery('#content-tabs a').each(function(){
				jQuery(this).click(function(){
					PagesAdmin.contentTabs.showFromURL(this.href);
				});
			});
		}
		window.showContentTab = PagesAdmin.contentTabs.show;
	}
}

FastInit.addOnLoad(PagesAdmin.init);<commit_msg>pages: admin.js fix<commit_after>
/* Extend jQuery with functions for PUT and DELETE requests. */

function _ajax_request(url, data, callback, type, method) {
    if (jQuery.isFunction(data)) {
        callback = data;
        data = {};
    }
    return jQuery.ajax({
        type: method,
        url: url,
        data: data,
        success: callback,
        dataType: type
        });
}

jQuery.extend({
    put: function(url, data, callback, type) {
        return _ajax_request(url, data, callback, type, 'PUT');
    },
    delete_: function(url, data, callback, type) {
        return _ajax_request(url, data, callback, type, 'DELETE');
    }
});

jQuery.fn.centerOnScreen = function(){
    var win_width      = jQuery(window).width();
    var scrollToLeft   = jQuery(window).scrollLeft();
    var win_height     = jQuery(window).height();
    var scrollToBottom = jQuery(window).scrollTop();
	var box_width = 200;
	var box_height = 200;

	this.css('position', 'absolute');
	this.css('z-index', (1000+(Math.round(Math.random() * 5000))));

	var x = ((jQuery(window).width() / 2) - (this.width() / 2)) + jQuery(window).scrollLeft();
	var y  = ((jQuery(window).height() / 2) - (this.height() / 2)) + jQuery(window).scrollTop();
	if(x < 0) { x = 0; }; if(y < 0) { y = 0; }

	this.css({ left: x+"px", top: y+"px" });

	return this;
}

function jRichTextArea(textArea, options){
	this.textArea = textArea;

	// Default options
	settings = jQuery.extend({
	     className: "richTextToolbar"
	}, options);

	this.toolbar = {
		settings : settings,
		textArea : textArea,
		listElement : false,
		buttons : new Array(),
		addButton : function(name, callback, options) {
			// Default options
			settings = jQuery.extend({
			     className: name.replace(/[\s]+/, '')+"Button"
			}, options);
			var li = document.createElement("li");
			var a = document.createElement("a");
			a.title = name;
			a.textArea = this.textArea;
			//callback.this = this;
			jQuery(a).click(callback);
			jQuery(a).addClass(settings.className);
			jQuery(li).append(a).appendTo(this.listElement);
			this.buttons.push(li);
			return this;
		},
		create : function() {
			if(!this.listElement) {
				this.listElement = document.createElement("ul");
				jQuery(this.listElement).addClass(this.settings.className);
				jQuery(this.listElement).insertBefore(this.textArea);
			}
		}
	}

	this.textArea.selectedText = function() {
		return jQuery(this).getSelection().text;
	}
	this.textArea.replaceSelection = function(replacement) {
		return jQuery(this).replaceSelection(replacement);
	}
	this.textArea.wrapSelection = function() {
		var prepend = arguments[0];
		var append = (arguments.length > 1) ? arguments[1] : prepend
		return this.replaceSelection(prepend + this.selectedText() + append);
	}

	// Delegates
	this.textArea.toolbar = this.toolbar;
	this.toolbar.create();
}

function EditableImage(link, options){

	// Default options
	settings = jQuery.extend({
		resourceURL: link.href,
		width: 550
	}, options);

	this.editableImage = {
		settings : settings,
		link : link,
		linkedImage : jQuery(link).children('img')[0],
		resourceURL : settings.resourceURL,
		editorDialog : false,
		imageData : false,
		previewURL : false,
		cropStartX : false,
		cropStartY : false,
		cropWidth : false,
		cropHeight : false,
		getScale : function() {
			return (this.settings.width / this.imageData.original_width);
		},
		openEditor : function() {
			// Dim the screen and create the loading dialog
			jQuery.dimScreen(200, 0.90);
			jQuery('body').append("
 Loading image editor…
");
			jQuery('#modalLoadingNotice').centerOnScreen().hide().fadeIn(200);

			// Create the container
			jQuery('#editableImageEditor').remove();
			jQuery('body').append("

");

			// Load data
			var binding = this;
			if(!this.imageData){
				jQuery.getJSON(this.resourceURL+".js", function(json){
					binding.imageData = json;
					binding.populateEditor();
				});
			} else {
				this.populateEditor();
			}
		},
		populateEditor : function() {
			jQuery('#editableImageEditor')
				.empty()
				.append("")
				.append("
")
				.hide();
			jQuery('#editableImageEditorControls')
				.append("<input type=\"button\" id=\"editableImageEditorSubmit\" value=\"Save\" />")
				.append("<input type=\"button\" id=\"editableImageEditorClose\" value=\"Cancel\" />")

			this.previewURL = this.linkedImage.src.replace(this.linkedImage.src.match(/([\d]*x[\d]*)/)[1], 'original/'+this.settings.width+'x');
			this.previewURL = this.previewURL.replace(/([\?\d])*$/, '');

			var binding = this;
			jQuery('#editableImageEditorImage').each(function(){
				this.src = binding.previewURL;
			});
			jQuery('#editableImageEditorSubmit').click(function(){
				binding.submit();
			});
			jQuery('#editableImageEditorClose').click(function(){
				binding.closeEditor();
			});

			var onCrop = function(coords) {
				binding.cropStartX = coords.x;
				binding.cropStartY = coords.y;
				binding.cropWidth = coords.w;
				binding.cropHeight = coords.h;
			}
			jQuery('#editableImageEditorImage').load(function(){
				jQuery('#modalLoadingNotice').fadeOut(100);
				jQuery('#editableImageEditor').show().centerOnScreen();
				var jCropOptions = {
					onChange: onCrop,
					onSelect: onCrop
				}
				var imageData = binding.imageData;
				if(imageData.cropped) {
					var crop_start_x = Math.round(imageData.crop_start_x * binding.getScale());
					var crop_start_y = Math.round(imageData.crop_start_y * binding.getScale());
					var crop_end_x = crop_start_x + Math.round(imageData.crop_width * binding.getScale());
					var crop_end_y = crop_start_y + Math.round(imageData.crop_height * binding.getScale());
					jCropOptions['setSelect'] = [crop_start_x, crop_start_y, crop_end_x, crop_end_y];
				}
				console.log(jCropOptions);
				jQuery('#editableImageEditorImage').Jcrop(jCropOptions);
			});

		},
		closeEditor : function() {
			jQuery('#modalLoadingNotice').remove();
			jQuery('#editableImageEditor').remove();
			this.imageData = false;
			jQuery.dimScreenStop();
		},
		refreshLinkedImage : function() {
			var newURL = this.linkedImage.src.toString();
			newURL = newURL+"?"+Math.round(Math.random() * 65535);
			this.linkedImage.src = newURL;
		},
		submit : function() {
			var cropped = (!this.cropWidth || !this.cropHeight) ? 0 : 1;
			var crop_start = false;
			var crop_size  = false;
			var put_options = false;
			if(cropped) {
				crop_size = Math.floor(this.cropWidth/this.getScale())+"x"+Math.floor(this.cropHeight/this.getScale());
				crop_start = Math.floor(this.cropStartX/this.getScale())+"x"+Math.floor(this.cropStartY/this.getScale());
				put_options = { 'image[cropped]': cropped, 'image[crop_size]': crop_size, 'image[crop_start]': crop_start }
			} else {
				put_options = { 'image[cropped]': cropped }
			}
			var binding = this;
			jQuery.put(this.resourceURL+".js", put_options, function(){
				binding.refreshLinkedImage();
				binding.closeEditor();
			})
		}
	}

	// Apply onClick behaviour
	link.editableImage = this.editableImage;
	jQuery(link).click(function(){
		this.editableImage.openEditor();
		return false;
	});

	//this.editableImage.openEditor(); // debug
}

var PagesAdmin = {

	controller : false,
	action : false,

	sniffBrowser : function() {
		if(navigator) {
			jQuery.each(Array("WebKit","Gecko","Firefox"), function(){
				if( navigator.userAgent.match( new RegExp(this+"\\/[\\d]+", 'i'))) {
					jQuery(document.body).addClass(this.toLowerCase());
				}
			});
			if(navigator.userAgent.match("MSIE")) {
				jQuery(document.body).addClass('msie')
			};
			if( navigator.userAgent.match("MSIE 7") ) {
				jQuery(document.body).addClass('msie7');
			}
		}
	},

	applyTextAreas : function() {
		jQuery('textarea.rich').each(function(){
			var ta = new jRichTextArea(this);

			// Add buttons to the field
			ta.toolbar
				// Bold
				.addButton("Bold", function(){ this.textArea.wrapSelection('*'); })
				// Italic
				.addButton("Italics", function(){ this.textArea.wrapSelection('_'); })
				// Headings
				.addButton("Heading 2", function(){ this.textArea.wrapSelection('h2. ',''); })
				.addButton("Heading 3", function(){ this.textArea.wrapSelection('h3. ',''); })
				.addButton("Heading 4", function(){ this.textArea.wrapSelection('h4. ',''); })
				// Links
				.addButton("Link", function(){
				    var selection = this.textArea.selectedText();
				    var response = prompt('Enter link URL','');
				    this.textArea.replaceSelection(
						'"' + (selection == '' ? "Link text" : selection) + '":' +
						(response == '' ? 'http://link_url/' : response).replace(/^(?!(f|ht)tps?:\/\/)/,'http://')
					);
				})
				// Email links
				.addButton("Email", function(){
				    var selection = this.textArea.selectedText();
				    var response = prompt('Enter mail address','');
				    this.textArea.replaceSelection(
						'"' + (selection == '' ? "Link text" : selection) + '":mailto:' +
						(response == '' ? 'support@manualdesign.no' : response)
					);
				})
				// Image tag
				.addButton("Image", function(){
				    var selection = this.textArea.selectedText();
					if( selection == '') {
					    var response = prompt('Enter image URL','');
					    if(response == null)
					        return;
						this.textArea.replaceSelection('!'+response+'!');
					} else {
						this.textArea.replaceSelection('!'+selection+'!');
					}
				})
			;
		});
	},

	applyEditableImages : function() {
		jQuery('a.editableImage').each(function(){
			new EditableImage(this);
		});
	},

	applyStyles : function() {
		// Detect the sidebar and add the appropriate class to the document element.
		if(jQuery('#sidebar').length > 0){
			jQuery(document.body).addClass('with_sidebar');
		}

		// Add input_$type class to inputs.
		jQuery('input').each(function(i){jQuery(this).addClass("input_"+this.type);});

		// Inject buttons with

		jQuery('button').wrapInner('

');

	},

	init : function() {
		PagesAdmin.sniffBrowser();
		PagesAdmin.applyStyles();
		PagesAdmin.applyEditableImages();
		PagesAdmin.applyTextAreas();
		if(PagesAdmin.contentTabs) {
			PagesAdmin.contentTabs.init();
		}

		// Call the controller action
		if(PagesAdmin.controller) {
			if(PagesAdmin.controller.init){
				PagesAdmin.controller.init();
			}
			if(PagesAdmin.action && PagesAdmin.controller[PagesAdmin.action]) {
				PagesAdmin.controller[PagesAdmin.action]();
			}
		}
	}
}
var Admin = PagesAdmin;

PagesAdmin.contentTabs = {

	tabs : new Array(),
	ids : new Array(),

	show : function(tab_id) {
		var tabs = PagesAdmin.contentTabs.tabs;
		var tab = tabs[tab_id];
		if(tab) {
			jQuery.each(PagesAdmin.contentTabs.ids, function(i){
				if(tabs[this]) {
					jQuery(tabs[this]).hide();
				} else {
					console.log("Could not hide tab: "+this);
				}
				jQuery("#content-tab-link-"+this).removeClass('current');
			});
			jQuery(tab).show();
			jQuery("#content-tab-link-"+tab_id).addClass('current');
		}
	},

	showFromURL : function(url) {
		var tab_expression = /#(.*)$/
		if(url.toString().match(tab_expression)){
			var tab_id = url.toString().match(tab_expression)[1];
			if(PagesAdmin.contentTabs.tabs[tab_id]){
				PagesAdmin.contentTabs.show(tab_id);
			}
		}
	},

	enable : function(tab_ids) {
		//PagesAdmin.contentTabs.tabs = new Array();
		var tabs = PagesAdmin.contentTabs.tabs;
		PagesAdmin.contentTabs.ids = tab_ids;
		jQuery.each(tab_ids, function(i) {
			var tab_id = this;
			jQuery("#content-tab-"+this).each(function(i){
				this.tab_id = tab_id;
				tabs[tab_id] = this;
			});
		});
		PagesAdmin.contentTabs.show(tab_ids[0]);
		PagesAdmin.contentTabs.showFromURL(document.location);
	},

	init : function() {
		if(jQuery('#content-tabs').length > 0) {
			jQuery('#content-tabs a').each(function(){
				jQuery(this).click(function(){
					PagesAdmin.contentTabs.showFromURL(this.href);
				});
			});
		}
		window.showContentTab = PagesAdmin.contentTabs.show;
	}
}

FastInit.addOnLoad(PagesAdmin.init);<|endoftext|>


<commit_before>const app = angular.module('scrumApp', []);

app.config(function($locationProvider) {
  $locationProvider.html5Mode({
                                enabled: true,
                                requireBase: false
                              });
});

app.controller('CtrlSkills', function($scope, $http) {

  $scope.skills = [];

  $scope.rankings = [{value: 'Junior'},
                    {value: 'Master'},
                    {value: 'Senior'}];

  $scope.addSkill = function() {
    $scope.skills.push({description: $scope.skillDescription, ranking: $scope.rankingSelected.value});
    $scope.skillDescription = '';
    $scope.postSkills();
  }

  $scope.removeSkill = function(index){
    $scope.skills.splice(index, 1);
    $scope.postSkills();
  }

  $scope.postSkills = function() {
    $http.post('/users/skills', {skills: $scope.skills})
      .success(
          function(success){
              console.log(success)
          })
      .error(
          function(error){
              console.log(error)
          });
  }

  // Esta funcion obtiene los datos del usuario en forma de JSON del endpoint
  //api/users/me, extrae el arreglo de skills y lo asigna a su variable scope

  $http.get("/api/users/me")
    .then(function(user){
      $scope.skills = user.data.skills;
      console.log($scope.skills);
  });

});

app.controller('CtrlCollaborators', function($scope, $http, $location){
  let path = $location.path();
  let id = path.split('/')[2]

  $scope.projects = {};
  $scope.users = [];
  $scope.collaborators = [];

  function getIds(){
    let collaborators = [];
    for(let i in $scope.collaborators){
      collaborators.push($scope.collaborators[i]._id);
    }
    return collaborators;
  };

  $scope.addCollaborator = function(user) {
    $scope.collaborators.push(user);
    $scope.postCollaborators();
  }

  $scope.removeCollaborator = function(index){
    $scope.collaborators.splice(index, 1);
    $scope.postCollaborators();
  }

  $scope.postCollaborators = function() {
    let collaborators = [];
    collaborators = getIds();
    $http.post('/projects/collaborators', {collaborators: collaborators})
      .success(
          function(success){
              console.log(success)
          })
      .error(
          function(error){
              console.log(error)
          });
  }

  $http.get("/api/users")
    .then(function(users){
      $scope.users = users.data;
      console.log($scope.users);
  });

  $http.get("/api/projects/" + id)
    .then(function(projects){
      $scope.projects = projects.data;
      console.log($scope.projects);
  });

});
<commit_msg>projects edit form can load development team<commit_after>const app = angular.module('scrumApp', []);

app.config(function($locationProvider) {
  $locationProvider.html5Mode({
                                enabled: true,
                                requireBase: false
                              });
});

app.controller('CtrlSkills', function($scope, $http) {

  $scope.skills = [];

  $scope.rankings = [{value: 'Junior'},
                    {value: 'Master'},
                    {value: 'Senior'}];

  $scope.addSkill = function() {
    $scope.skills.push({description: $scope.skillDescription, ranking: $scope.rankingSelected.value});
    $scope.skillDescription = '';
    $scope.postSkills();
  }

  $scope.removeSkill = function(index){
    $scope.skills.splice(index, 1);
    $scope.postSkills();
  }

  $scope.postSkills = function() {
    $http.post('/users/skills', {skills: $scope.skills})
      .success(
          function(success){
              console.log(success)
          })
      .error(
          function(error){
              console.log(error)
          });
  }

  // Esta funcion obtiene los datos del usuario en forma de JSON del endpoint
  //api/users/me, extrae el arreglo de skills y lo asigna a su variable scope

  $http.get("/api/users/me")
    .then(function(user){
      $scope.skills = user.data.skills;
      console.log($scope.skills);
  });

});

app.controller('CtrlCollaborators', function($scope, $http, $location){
  let path = $location.path();
  let id = path.split('/')[2]

  $scope.projects = {};
  $scope.users = [];
  $scope.collaborators = [];

  function getIds(){
    let collaborators = [];
    for(let i in $scope.collaborators){
      collaborators.push($scope.collaborators[i]._id);
    }
    return collaborators;
  };

  $scope.addCollaborator = function(user) {
    $scope.collaborators.push(user);
    $scope.postCollaborators();
  }

  $scope.removeCollaborator = function(index){
    $scope.collaborators.splice(index, 1);
    $scope.postCollaborators();
  }

  $scope.postCollaborators = function() {
    let collaborators = [];
    collaborators = getIds();
    $http.post('/projects/collaborators', {collaborators: collaborators})
      .success(
          function(success){
              console.log(success)
          })
      .error(
          function(error){
              console.log(error)
          });
  }

  $http.get("/api/users")
    .then(function(users){
      $scope.users = users.data;
      console.log($scope.users);
  });

  $http.get("/api/projects/" + id)
    .then(function(projects){
      $scope.projects = projects.data;
      $scope.collaborators = $scope.projects.equipoDesarrollo;
     console.log($scope.projects);
  });

});
<|endoftext|>


<commit_before>'use strict';
const fs = require('fs');
const path = require('path');
const Database = require('../.');

describe('new Database()', function () {
	afterEach(function () {
		if (this.db) this.db.close();
	});

	it('should throw when given invalid argument types', function () {
		expect(() => (this.db = new Database('', ''))).to.throw(TypeError);
		expect(() => (this.db = new Database({}, ''))).to.throw(TypeError);
		expect(() => (this.db = new Database({}, {}))).to.throw(TypeError);
		expect(() => (this.db = new Database({}))).to.throw(TypeError);
		expect(() => (this.db = new Database(0))).to.throw(TypeError);
		expect(() => (this.db = new Database(123))).to.throw(TypeError);
		expect(() => (this.db = new Database(new String(util.next())))).to.throw(TypeError);
		expect(() => (this.db = new Database(() => util.next()))).to.throw(TypeError);
		expect(() => (this.db = new Database([util.next()]))).to.throw(TypeError);
	});
	it('should throw when boolean options are provided as non-booleans', function () {
		expect(() => (this.db = new Database(util.next(), { readOnly: false }))).to.throw(TypeError);
		expect(() => (this.db = new Database(util.next(), { readonly: undefined }))).to.throw(TypeError);
		expect(() => (this.db = new Database(util.next(), { fileMustExist: undefined }))).to.throw(TypeError);
	});
	it('should allow anonymous temporary databases to be created', function () {
		for (const args of [[''], [], [null], [undefined], ['', { timeout: 2000 }]]) {
			const db = this.db = new Database(...args);
			expect(db.name).to.equal('');
			expect(db.memory).to.be.true;
			expect(db.readonly).to.be.false;
			expect(db.open).to.be.true;
			expect(db.inTransaction).to.be.false;
			expect(fs.existsSync('')).to.be.false;
			expect(fs.existsSync('null')).to.be.false;
			expect(fs.existsSync('undefined')).to.be.false;
			expect(fs.existsSync('[object Object]')).to.be.false;
			db.close();
		}
	});
	it('should allow anonymous in-memory databases to be created', function () {
		const db = this.db = new Database(':memory:');
		expect(db.name).to.equal(':memory:');
		expect(db.memory).to.be.true;
		expect(db.readonly).to.be.false;
		expect(db.open).to.be.true;
		expect(db.inTransaction).to.be.false;
		expect(fs.existsSync(':memory:')).to.be.false;
	});
	it('should allow disk-bound databases to be created', function () {
		expect(fs.existsSync(util.next())).to.be.false;
		const db = this.db = new Database(util.current());
		expect(db.name).to.equal(util.current());
		expect(db.memory).to.be.false;
		expect(db.readonly).to.be.false;
		expect(db.open).to.be.true;
		expect(db.inTransaction).to.be.false;
		expect(fs.existsSync(util.current())).to.be.true;
	});
	it('should allow readonly database connections to be created', function () {
		expect(fs.existsSync(util.next())).to.be.false;
		expect(() => (this.db = new Database(util.current(), { readonly: true }))).to.throw(Database.SqliteError).with.property('code', 'SQLITE_CANTOPEN');
		(new Database(util.current())).close();
		expect(fs.existsSync(util.current())).to.be.true;
		const db = this.db = new Database(util.current(), { readonly: true });
		expect(db.name).to.equal(util.current());
		expect(db.memory).to.be.false;
		expect(db.readonly).to.be.true;
		expect(db.open).to.be.true;
		expect(db.inTransaction).to.be.false;
		expect(fs.existsSync(util.current())).to.be.true;
	});
	it('should not allow the "readonly" option for in-memory databases', function () {
		expect(fs.existsSync(util.next())).to.be.false;
		expect(() => (this.db = new Database(':memory:', { readonly: true }))).to.throw(TypeError);
		expect(() => (this.db = new Database('', { readonly: true }))).to.throw(TypeError);
		expect(fs.existsSync(util.current())).to.be.false;
	});
	it('should accept the "fileMustExist" option', function () {
		expect(fs.existsSync(util.next())).to.be.false;
		expect(() => (this.db = new Database(util.current(), { fileMustExist: true }))).to.throw(Database.SqliteError).with.property('code', 'SQLITE_CANTOPEN');
		(new Database(util.current())).close();
		expect(fs.existsSync(util.current())).to.be.true;
		const db = this.db = new Database(util.current(), { fileMustExist: true });
		expect(db.name).to.equal(util.current());
		expect(db.memory).to.be.false;
		expect(db.readonly).to.be.false;
		expect(db.open).to.be.true;
		expect(db.inTransaction).to.be.false;
		expect(fs.existsSync(util.current())).to.be.true;
	});
	util.itUnix('should accept the "timeout" option', function () {
		this.slow(4000);
		const testTimeout = (timeout) => {
			const db = new Database(util.current(), { timeout });
			try {
				const start = Date.now();
				expect(() => db.exec('BEGIN EXCLUSIVE')).to.throw(Database.SqliteError).with.property('code', 'SQLITE_BUSY');
				const end = Date.now();
				expect(end - start).to.be.closeTo(timeout, 200);
			} finally {
				db.close();
			}
		};
		const blocker = this.db = new Database(util.next(), { timeout: 0x7fffffff });
		blocker.exec('BEGIN EXCLUSIVE');
		testTimeout(0);
		testTimeout(1000);
		blocker.close();
		expect(() => (this.db = new Database(util.current(), { timeout: undefined }))).to.throw(TypeError);
		expect(() => (this.db = new Database(util.current(), { timeout: null }))).to.throw(TypeError);
		expect(() => (this.db = new Database(util.current(), { timeout: NaN }))).to.throw(TypeError);
		expect(() => (this.db = new Database(util.current(), { timeout: '75' }))).to.throw(TypeError);
		expect(() => (this.db = new Database(util.current(), { timeout: -1 }))).to.throw(TypeError);
		expect(() => (this.db = new Database(util.current(), { timeout: 75.01 }))).to.throw(TypeError);
		expect(() => (this.db = new Database(util.current(), { timeout: 0x80000000 }))).to.throw(RangeError);
	});
	it('should accept the "nativeBinding" option', function () {
		this.slow(500);
		const oldBinding = require('bindings')({ bindings: 'better_sqlite3.node', path: true });
		const newBinding = path.join(__dirname, '..', 'temp', 'foo.node');
		expect(oldBinding).to.be.a('string');
		fs.copyFileSync(oldBinding, newBinding);
		const getBinding = db => db[Object.getOwnPropertySymbols(db)[0]].constructor;
		let db1;
		let db2;
		let db3;
		try {
			db1 = new Database('');
			db2 = new Database('', { nativeBinding: oldBinding });
			db3 = new Database('', { nativeBinding: newBinding });
			expect(db1.open).to.be.true;
			expect(db2.open).to.be.true;
			expect(db3.open).to.be.true;
			expect(getBinding(db1)).to.equal(getBinding(db2));
			expect(getBinding(db1)).to.not.equal(getBinding(db3));
			expect(getBinding(db2)).to.not.equal(getBinding(db3));
		} finally {
			if (db1) db1.close();
			if (db2) db2.close();
			if (db3) db3.close();
		}
	});
	it('should throw an Error if the directory does not exist', function () {
		expect(fs.existsSync(util.next())).to.be.false;
		const filepath = `temp/nonexistent/abcfoobar123/${util.current()}`;
		expect(() => (this.db = new Database(filepath))).to.throw(TypeError);
		expect(fs.existsSync(filepath)).to.be.false;
		expect(fs.existsSync(util.current())).to.be.false;
	});
	it('should have a proper prototype chain', function () {
		const db = this.db = new Database(util.next());
		expect(db).to.be.an.instanceof(Database);
		expect(db.constructor).to.equal(Database);
		expect(Database.prototype.constructor).to.equal(Database);
		expect(Database.prototype.close).to.be.a('function');
		expect(Database.prototype.close).to.equal(db.close);
		expect(Database.prototype).to.equal(Object.getPrototypeOf(db));
	});
	it('should work properly when called as a function', function () {
		const db = this.db = Database(util.next());
		expect(db).to.be.an.instanceof(Database);
		expect(db.constructor).to.equal(Database);
		expect(Database.prototype.close).to.equal(db.close);
		expect(Database.prototype).to.equal(Object.getPrototypeOf(db));
	});
	it('should work properly when subclassed', function () {
		class MyDatabase extends Database {
			foo() {
				return 999;
			}
		}
		const db = this.db = new MyDatabase(util.next());
		expect(db).to.be.an.instanceof(Database);
		expect(db).to.be.an.instanceof(MyDatabase);
		expect(db.constructor).to.equal(MyDatabase);
		expect(Database.prototype.close).to.equal(db.close);
		expect(MyDatabase.prototype.close).to.equal(db.close);
		expect(Database.prototype.foo).to.be.undefined;
		expect(MyDatabase.prototype.foo).to.equal(db.foo);
		expect(Database.prototype).to.equal(Object.getPrototypeOf(MyDatabase.prototype));
		expect(MyDatabase.prototype).to.equal(Object.getPrototypeOf(db));
		expect(db.foo()).to.equal(999);
	});
});
<commit_msg>fixed test<commit_after>'use strict';
const fs = require('fs');
const path = require('path');
const Database = require('../.');

describe('new Database()', function () {
	afterEach(function () {
		if (this.db) this.db.close();
	});

	it('should throw when given invalid argument types', function () {
		expect(() => (this.db = new Database('', ''))).to.throw(TypeError);
		expect(() => (this.db = new Database({}, ''))).to.throw(TypeError);
		expect(() => (this.db = new Database({}, {}))).to.throw(TypeError);
		expect(() => (this.db = new Database({}))).to.throw(TypeError);
		expect(() => (this.db = new Database(0))).to.throw(TypeError);
		expect(() => (this.db = new Database(123))).to.throw(TypeError);
		expect(() => (this.db = new Database(new String(util.next())))).to.throw(TypeError);
		expect(() => (this.db = new Database(() => util.next()))).to.throw(TypeError);
		expect(() => (this.db = new Database([util.next()]))).to.throw(TypeError);
	});
	it('should throw when boolean options are provided as non-booleans', function () {
		expect(() => (this.db = new Database(util.next(), { readOnly: false }))).to.throw(TypeError);
		expect(() => (this.db = new Database(util.next(), { readonly: undefined }))).to.throw(TypeError);
		expect(() => (this.db = new Database(util.next(), { fileMustExist: undefined }))).to.throw(TypeError);
	});
	it('should allow anonymous temporary databases to be created', function () {
		for (const args of [[''], [], [null], [undefined], ['', { timeout: 2000 }]]) {
			const db = this.db = new Database(...args);
			expect(db.name).to.equal('');
			expect(db.memory).to.be.true;
			expect(db.readonly).to.be.false;
			expect(db.open).to.be.true;
			expect(db.inTransaction).to.be.false;
			expect(fs.existsSync('')).to.be.false;
			expect(fs.existsSync('null')).to.be.false;
			expect(fs.existsSync('undefined')).to.be.false;
			expect(fs.existsSync('[object Object]')).to.be.false;
			db.close();
		}
	});
	it('should allow anonymous in-memory databases to be created', function () {
		const db = this.db = new Database(':memory:');
		expect(db.name).to.equal(':memory:');
		expect(db.memory).to.be.true;
		expect(db.readonly).to.be.false;
		expect(db.open).to.be.true;
		expect(db.inTransaction).to.be.false;
		expect(fs.existsSync(':memory:')).to.be.false;
	});
	it('should allow disk-bound databases to be created', function () {
		expect(fs.existsSync(util.next())).to.be.false;
		const db = this.db = new Database(util.current());
		expect(db.name).to.equal(util.current());
		expect(db.memory).to.be.false;
		expect(db.readonly).to.be.false;
		expect(db.open).to.be.true;
		expect(db.inTransaction).to.be.false;
		expect(fs.existsSync(util.current())).to.be.true;
	});
	it('should allow readonly database connections to be created', function () {
		expect(fs.existsSync(util.next())).to.be.false;
		expect(() => (this.db = new Database(util.current(), { readonly: true }))).to.throw(Database.SqliteError).with.property('code', 'SQLITE_CANTOPEN');
		(new Database(util.current())).close();
		expect(fs.existsSync(util.current())).to.be.true;
		const db = this.db = new Database(util.current(), { readonly: true });
		expect(db.name).to.equal(util.current());
		expect(db.memory).to.be.false;
		expect(db.readonly).to.be.true;
		expect(db.open).to.be.true;
		expect(db.inTransaction).to.be.false;
		expect(fs.existsSync(util.current())).to.be.true;
	});
	it('should not allow the "readonly" option for in-memory databases', function () {
		expect(fs.existsSync(util.next())).to.be.false;
		expect(() => (this.db = new Database(':memory:', { readonly: true }))).to.throw(TypeError);
		expect(() => (this.db = new Database('', { readonly: true }))).to.throw(TypeError);
		expect(fs.existsSync(util.current())).to.be.false;
	});
	it('should accept the "fileMustExist" option', function () {
		expect(fs.existsSync(util.next())).to.be.false;
		expect(() => (this.db = new Database(util.current(), { fileMustExist: true }))).to.throw(Database.SqliteError).with.property('code', 'SQLITE_CANTOPEN');
		(new Database(util.current())).close();
		expect(fs.existsSync(util.current())).to.be.true;
		const db = this.db = new Database(util.current(), { fileMustExist: true });
		expect(db.name).to.equal(util.current());
		expect(db.memory).to.be.false;
		expect(db.readonly).to.be.false;
		expect(db.open).to.be.true;
		expect(db.inTransaction).to.be.false;
		expect(fs.existsSync(util.current())).to.be.true;
	});
	util.itUnix('should accept the "timeout" option', function () {
		this.slow(4000);
		const testTimeout = (timeout) => {
			const db = new Database(util.current(), { timeout });
			try {
				const start = Date.now();
				expect(() => db.exec('BEGIN EXCLUSIVE')).to.throw(Database.SqliteError).with.property('code', 'SQLITE_BUSY');
				const end = Date.now();
				expect(end - start).to.be.closeTo(timeout, 200);
			} finally {
				db.close();
			}
		};
		const blocker = this.db = new Database(util.next(), { timeout: 0x7fffffff });
		blocker.exec('BEGIN EXCLUSIVE');
		testTimeout(0);
		testTimeout(1000);
		blocker.close();
		expect(() => (this.db = new Database(util.current(), { timeout: undefined }))).to.throw(TypeError);
		expect(() => (this.db = new Database(util.current(), { timeout: null }))).to.throw(TypeError);
		expect(() => (this.db = new Database(util.current(), { timeout: NaN }))).to.throw(TypeError);
		expect(() => (this.db = new Database(util.current(), { timeout: '75' }))).to.throw(TypeError);
		expect(() => (this.db = new Database(util.current(), { timeout: -1 }))).to.throw(TypeError);
		expect(() => (this.db = new Database(util.current(), { timeout: 75.01 }))).to.throw(TypeError);
		expect(() => (this.db = new Database(util.current(), { timeout: 0x80000000 }))).to.throw(RangeError);
	});
	it('should accept the "nativeBinding" option', function () {
		this.slow(500);
		const oldBinding = require('bindings')({ bindings: 'better_sqlite3.node', path: true });
		const newBinding = path.join(path.dirname(oldBinding), 'test.node');
		expect(oldBinding).to.be.a('string');
		fs.copyFileSync(oldBinding, newBinding);
		const getBinding = db => db[Object.getOwnPropertySymbols(db)[0]].constructor;
		let db1;
		let db2;
		let db3;
		try {
			db1 = new Database('');
			db2 = new Database('', { nativeBinding: oldBinding });
			db3 = new Database('', { nativeBinding: newBinding });
			expect(db1.open).to.be.true;
			expect(db2.open).to.be.true;
			expect(db3.open).to.be.true;
			expect(getBinding(db1)).to.equal(getBinding(db2));
			expect(getBinding(db1)).to.not.equal(getBinding(db3));
			expect(getBinding(db2)).to.not.equal(getBinding(db3));
		} finally {
			if (db1) db1.close();
			if (db2) db2.close();
			if (db3) db3.close();
		}
	});
	it('should throw an Error if the directory does not exist', function () {
		expect(fs.existsSync(util.next())).to.be.false;
		const filepath = `temp/nonexistent/abcfoobar123/${util.current()}`;
		expect(() => (this.db = new Database(filepath))).to.throw(TypeError);
		expect(fs.existsSync(filepath)).to.be.false;
		expect(fs.existsSync(util.current())).to.be.false;
	});
	it('should have a proper prototype chain', function () {
		const db = this.db = new Database(util.next());
		expect(db).to.be.an.instanceof(Database);
		expect(db.constructor).to.equal(Database);
		expect(Database.prototype.constructor).to.equal(Database);
		expect(Database.prototype.close).to.be.a('function');
		expect(Database.prototype.close).to.equal(db.close);
		expect(Database.prototype).to.equal(Object.getPrototypeOf(db));
	});
	it('should work properly when called as a function', function () {
		const db = this.db = Database(util.next());
		expect(db).to.be.an.instanceof(Database);
		expect(db.constructor).to.equal(Database);
		expect(Database.prototype.close).to.equal(db.close);
		expect(Database.prototype).to.equal(Object.getPrototypeOf(db));
	});
	it('should work properly when subclassed', function () {
		class MyDatabase extends Database {
			foo() {
				return 999;
			}
		}
		const db = this.db = new MyDatabase(util.next());
		expect(db).to.be.an.instanceof(Database);
		expect(db).to.be.an.instanceof(MyDatabase);
		expect(db.constructor).to.equal(MyDatabase);
		expect(Database.prototype.close).to.equal(db.close);
		expect(MyDatabase.prototype.close).to.equal(db.close);
		expect(Database.prototype.foo).to.be.undefined;
		expect(MyDatabase.prototype.foo).to.equal(db.foo);
		expect(Database.prototype).to.equal(Object.getPrototypeOf(MyDatabase.prototype));
		expect(MyDatabase.prototype).to.equal(Object.getPrototypeOf(db));
		expect(db.foo()).to.equal(999);
	});
});
<|endoftext|>


<commit_before>var assert = require('assert');
var expect = require('chai').expect;

var cheerio = require('cheerio');
var request = require('supertest');
var rest = require('restler');
var WebSocket = require('ws');
var JSONRPC = require('maki-jsonrpc');

var config = require('../config');

config.services.http.port = 9201;
config.services.spdy.port = config.services.http.port + 443 - 80;
config.database.name = 'maki-test';

var Maki = require('../lib/Maki');
var maki = new Maki( config );

/*var Sessions = require('maki-sessions');
var sessions = new Sessions({
  resource: 'Person'
});

maki.use( sessions );*/

maki.define('Person', {
  name: 'Person',
  attributes: {
    username: { type: String , max: 80 , required: true , id: true },
    description: { type: String , max: 500 },
    hash: { type: String , default: 'asdf', required: true , restricted: true }
  }
});

maki.define('Example', {
  attributes: {
    name:    { type: String , max: 80 },
    slug:    { type: String , max: 80 , id: true },
    content: { type: String }
  },
  source: 'test/fixtures/examples.json',
  icon: 'idea'
});

function resource( path , options ) {
  var options  = options || {};
  var protocol = (options.ssl) ? 'https' : 'http';
  var host     = (options.ssl) ? maki.config.services.spdy.host : maki.config.services.http.host;
  var port     = (options.ssl) ? maki.config.services.spdy.port : maki.config.services.http.port;

  return protocol + '://' + host + ':' + port + path;
}
function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

before(function(ready) {
  process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
  maki.start();
  maki.on('ready', ready );
});

describe('Maki', function() {

  it('should expose a constructor', function(){
    assert(typeof maki, 'function');
  });

  it('should expose a map of resources', function() {
    assert(typeof maki.resources, 'object');
  });

  it('should expose a list of resources', function() {
    expect( Object.keys(maki.resources).length ).to.be.at.least(1);
  });

  it('should expose a job queue', function() {
    assert( typeof maki.Queue , 'object' );
  });

  it('should be able to queue a job', function( done ) {
    maki.queue.enqueue( 'test' , {
      foo: 'bar'
    }, done );
  });

  it('should be able to process a queued job', function( done ) {
    // TODO: eliminate need for timeout by solving cttnlsn/monq#38
    this.timeout( 6000 );

    var jobData = { id: getRandomInt( 1000 , 10000 ) };

    var worker = new maki.queue.Worker( config.database.name );
    worker.register({
      'test': function( data , jobIsDone ) {
        jobIsDone();
        if (data.id == jobData.id ) return done();
      }
    });
    worker.start();

    maki.queue.enqueue( 'test' , jobData , new Function() );

  });

});

describe('http', function(){

  function nonZeroArray(res) {
    if (!res.body) throw new Error('no body');
    if (res.body.length < 1) throw new Error('no resources exposed');

    return false;
  }

  it('should be listening for http', function() {
    request( maki.app )
      .get('/')
      .expect(200)
      .end(function(err, res) {
        if (err) throw err;
      });
  });

  it('should expose a list of resources', function() {
    request( maki.app )
      .options('/')
      .expect(200)
      .expect( nonZeroArray )
      .end(function(err, res) {
        if (err) throw err;
      });
  });

  it('should return 404 for non-existent resources', function( done ) {
    request( maki.app )
      .get('/this-should-never-exist')
      .end(function(err, res) {
        assert.equal( res.status , 404 );
        done();
      });
  });

  it('should allow for resources to be queried', function( done ) {
    request( maki.app )
      .get('/people')
      .expect(200)
      .end(function(err, res) {
        if (err) throw err;
        done();
      });
  });

  it('should allow for a resource to be created via POST (single call)', function( done ) {
    var randomNum = getRandomInt( 100000 , 1000000 );
    request( maki.app )
      .post('/people')
      .set('Accept', 'application/json')
      .send({ username: 'test-user-'+randomNum })
      .expect(303)
      .end(function(err, res) {
        if (err) throw err;
        done();
      });
  });

  it('should allow for a resource to be created via PUT (single call)', function( done ) {
    var randomNum = getRandomInt( 100000 , 1000000 );
    var username = 'test-user-'+randomNum;

    rest.put( resource('/people/' + username) , {
      data: { username: username },
      headers: { accept: 'application/json' }
    }).on('complete', function(data, res) {
      assert( res.statusCode , 200 );
      done();
    });

  });

  // TODO: evaluate this from a standards perspective.  Should HTML clients
  // be treated differently?
  it('should allow for a resource to be created (html client)', function( done ) {
    var randomNum = getRandomInt( 100000 , 1000000 );
    request( maki.app )
    .post('/people')
    .set('Accept', 'text/html')
    .send({ username: 'test-user-'+randomNum })
    .expect(303)
    .end(function(err, res) {
      if (err) throw err;
      done();
    });
  });

  it('should allow for a resource to be updated via PATCH (single call)', function( done ) {
    var randomNum = getRandomInt( 100000 , 1000000 );
    var username = 'test-user-'+randomNum;

    rest.put( resource('/people/' + username) , {
      data: { username: username },
      headers: { accept: 'application/json' }
    }).on('complete', function(data, res) {
      rest.patch( resource('/people/' + username) , {
        data: { username: username + '-patched' },
        headers: { accept: 'application/json' }
      }).on('complete', function(data, res) {
        assert( data.username , username + '-patched' );
        done();
      });
    });
  });

  it('should return a created resource from an appropriate location', function( done ) {
    var randomNum = getRandomInt( 100000 , 1000000 );
    var username = 'test-user-'+randomNum;

    request( maki.app )
      .post('/people')
      .set('Accept', 'application/json')
      .send({ username: username })
      .expect(303)
      .end(function(err, res) {
        if (err) throw err;

        request( maki.app )
          .get('/people/' + username )
          .set('Accept', 'application/json')
          .expect(200)
          .end(function(err, res) {
            if (err) throw err;
            if (res.body.username !== username) throw 'no result';

            done();
          });
      });
  });

  it('should not expose restricted fields', function(done) {
    var randomNum = getRandomInt( 100000 , 1000000 );
    rest.post( resource('/people') , {
      data: {
        username: 'test-user-'+randomNum,
        hash: 'fooooooooo'
      }
    }).on('complete', function(createdDoc) {
      expect(createdDoc.hash).to.equal( undefined );
      done();
    });
  });

  it('should expose JSON when requested', function(done) {
    var randomNum = getRandomInt( 100000 , 1000000 );
    rest.post( resource('/people') , {
      data: {
        username: 'test-user-'+randomNum,
        hash: 'fooooooooo'
      }
    }).on('complete', function(createdDoc) {
      rest.get( resource('/people') , {
        headers: {
          'Accept': 'application/json'
        }
      }).on('complete', function( people ) {
        assert.ok( people.length );
        done();
      });
    });
  });

  it('should inform clients about unsupported methods', function(done) {
    rest.post( resource('/examples') , {
      headers: {
        'Accept': 'application/json'
      },
      data: {
        name: 'this-should-never-exist'
      }
    }).on('complete', function(doc, res) {
      assert( res.statusCode === 405 );
      done();
    });
  });

});

describe('https', function(){
  var https = require('https');
  var uri = resource('/', { ssl: true });

  it('should be listening for https', function() {
    https.get( uri , function(res) {
      assert.equal( res.statusCode , 200 );
    });
  });
});

describe('spdy', function(){
  var spdy = require('spdy');
  var https = require('https');
  var http = require('http');

  var agent = spdy.createAgent({
    host: '127.0.0.1',
    port: config.services.spdy.port
  });

  xit('should be listening for spdy', function( next ) {
    http.get({
      host: config.services.spdy.host,
      path: '/',
      agent: agent
    }, function(res) {

      assert.equal( res.statusCode , 201 );
      agent.close();

      next()

    }).end();
  });
});

describe('ws', function() {

  it('should allow for a websocket upgrade', function( done ) {
    var ws = new WebSocket( resource('/') );
    ws.on('open', done );
  });

  it('should correctly clean up closed sockets', function( done ) {
    var ws = new WebSocket( resource('/') );

    var orig = Object.keys(maki.clients).length;
    var prev = null;
    var curr = null;

    ws.on('close', function() {
      now = Object.keys(maki.clients).length;
      assert.ok( now < prev );
      done();
    });

    ws.on('open', function() {
      prev = Object.keys(maki.clients).length;
      ws.close();
    });

  });

  it('should respond to subscription messages', function( done ) {
    var ws = new WebSocket( resource('/') );

    ws.on('message', function(data) {
      ws.close();
      return done();
    });
    ws.on('open', function() {
      var message = new JSONRPC('subscribe', { channel: '/' });
      ws.send( message.toJSON() );
    });

  });

  it('should respond to unsubscription messages', function( done ) {
    var ws = new WebSocket( resource('/') );

    ws.on('message', function(data) {
      ws.close();
      return done();
    });
    ws.on('open', function() {
      var message = new JSONRPC('unsubscribe', { channel: '/' });
      ws.send( message.toJSON() );
    });

  });

  it('should receive pings', function( done ) {
    var ws = new WebSocket( resource('/') );

    ws.on('message', function(data) {
      var message = JSON.parse( data );
      if (message.method === 'ping') {
        ws.close();
        return done();
      }
    });
    ws.on('open', function() {
      maki.socks.markAndSweep();
    });
  });

  it('should receive a patch event for new documents', function( done ) {
    var ws = new WebSocket( resource('/people') );
    var randomNum = getRandomInt( 100000 , 1000000 );

    ws.on('message', function(data) {
      var message = JSON.parse( data );
      if (message.method === 'patch') {
        ws.close();
        return done();
      };
    });
    ws.on('open', function() {
      rest.post( resource('/people') , {
        data: { username: 'test-user-'+randomNum }
      });
    });
  });

  it('should receive a patch event for changed documents', function( done ) {
    var randomNum = getRandomInt( 100000 , 1000000 );
    var personName = 'test-user-'+randomNum;
    var personURL = resource('/people/' + personName );

    rest.post( resource('/people') , {
      data: { username: personName }
    }).on('complete', function(created) {
      var ws = new WebSocket( personURL );

      ws.on('message', function(data) {
        var message = JSON.parse( data );
        if (message.method === 'patch') {
          ws.close();
          return done();
        };
      });

      ws.on('open', function() {
        rest.patch( personURL , {
          data: { description: Math.random() }
        } );
      });
    });
  });

  it('should reject incorrect JSON', function( done ) {
    var ws = new WebSocket( resource('/') );

    ws.on('message', function(data) {
      // see http://www.jsonrpc.org/specification#error_object
      var message = JSON.parse( data );
      assert.equal( message.error.code , 32700 );
      done();
    });

    ws.on('open', function() {
      ws.send( 'fail me, I dare you' );
    });

  });

  it('should reject non-JSONRPC messages', function( done ) {
    var ws = new WebSocket( resource('/') );

    ws.on('message', function(data) {
      // see http://www.jsonrpc.org/specification#error_object
      var message = JSON.parse( data );
      assert.equal( message.error.code , 32600 );
      done();
    });

    ws.on('open', function() {
      ws.send('{}');
    });

  });

});

describe('browser', function() {
  var self = this;

  it('should correctly connect', function(done) {
    rest.get( resource('/people') , {
      headers: {
        accept: 'text/html'
      }
    }).on('complete', function(data) {
      var $ = cheerio.load(data);
      assert.ok( $.html() );
      done();
    });
  });
  it('should have a page title', function(done) {
    rest.get( resource('/people') , {
      headers: {
        accept: 'text/html'
      }
    }).on('complete', function(data) {
      var $ = cheerio.load(data);
      assert.ok( $('title').html() );
      done();
    });
  });
  it('should have a content in the content div', function( done ) {
    rest.get( resource('/people') , {
      headers: {
        accept: 'text/html'
      }
    }).on('complete', function(data) {
      var $ = cheerio.load(data);
      assert.ok( $('div.content > *').html() );
      done();
    });
  });
});

describe('browser with javascript', function() {

});

describe('cleanup', function() {
  xit('should clean up after itself', function( done ) {
    maki.destroy( done );
  });
});
<commit_msg>Temporary fix for unit tests.<commit_after>var assert = require('assert');
var expect = require('chai').expect;

var cheerio = require('cheerio');
var request = require('supertest');
var rest = require('restler');
var WebSocket = require('ws');
var JSONRPC = require('maki-jsonrpc');

var config = require('../config');

config.services.http.port = 9201;
config.services.spdy.port = config.services.http.port + 443 - 80;
config.database.name = 'maki-test';

var Maki = require('../lib/Maki');
var maki = new Maki( config );

/*var Sessions = require('maki-sessions');
var sessions = new Sessions({
  resource: 'Person'
});

maki.use( sessions );*/

maki.define('Person', {
  name: 'Person',
  attributes: {
    username: { type: String , max: 80 , required: true , id: true },
    description: { type: String , max: 500 },
    hash: { type: String , default: 'asdf', required: true , restricted: true }
  }
});

maki.define('Example', {
  attributes: {
    name:    { type: String , max: 80 },
    slug:    { type: String , max: 80 , id: true },
    content: { type: String }
  },
  source: 'test/fixtures/examples.json',
  icon: 'idea'
});

function resource( path , options ) {
  var options  = options || {};
  var protocol = (options.ssl) ? 'https' : 'http';
  var host     = (options.ssl) ? maki.config.services.spdy.host : maki.config.services.http.host;
  var port     = (options.ssl) ? maki.config.services.spdy.port : maki.config.services.http.port;

  return protocol + '://' + host + ':' + port + path;
}
function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
maki.start();

describe('Maki', function() {

  before(function(ready) {
    setTimeout(function() {
      ready();
    }, 1900);
  });

  it('should expose a constructor', function(){
    assert(typeof maki, 'function');
  });

  it('should expose a map of resources', function() {
    assert(typeof maki.resources, 'object');
  });

  it('should expose a list of resources', function() {
    expect( Object.keys(maki.resources).length ).to.be.at.least(1);
  });

  it('should expose a job queue', function() {
    assert( typeof maki.Queue , 'object' );
  });

  it('should be able to queue a job', function( done ) {
    maki.queue.enqueue( 'test' , {
      foo: 'bar'
    }, done );
  });

  it('should be able to process a queued job', function( done ) {
    // TODO: eliminate need for timeout by solving cttnlsn/monq#38
    this.timeout( 6000 );

    var jobData = { id: getRandomInt( 1000 , 10000 ) };

    var worker = new maki.queue.Worker( config.database.name );
    worker.register({
      'test': function( data , jobIsDone ) {
        jobIsDone();
        if (data.id == jobData.id ) return done();
      }
    });
    worker.start();

    maki.queue.enqueue( 'test' , jobData , new Function() );

  });

});

describe('http', function(){

  before(function(ready) {
    setTimeout(function() {
      ready();
    }, 1900);
  });

  function nonZeroArray(res) {
    if (!res.body) throw new Error('no body');
    if (res.body.length < 1) throw new Error('no resources exposed');

    return false;
  }

  it('should be listening for http', function() {
    request( maki.app )
      .get('/')
      .expect(200)
      .end(function(err, res) {
        if (err) throw err;
      });
  });

  it('should expose a list of resources', function() {
    request( maki.app )
      .options('/')
      .expect(200)
      .expect( nonZeroArray )
      .end(function(err, res) {
        if (err) throw err;
      });
  });

  it('should return 404 for non-existent resources', function( done ) {
    request( maki.app )
      .get('/this-should-never-exist')
      .end(function(err, res) {
        assert.equal( res.status , 404 );
        done();
      });
  });

  it('should allow for resources to be queried', function( done ) {
    request( maki.app )
      .get('/people')
      .expect(200)
      .end(function(err, res) {
        if (err) throw err;
        done();
      });
  });

  it('should allow for a resource to be created via POST (single call)', function( done ) {
    var randomNum = getRandomInt( 100000 , 1000000 );
    request( maki.app )
      .post('/people')
      .set('Accept', 'application/json')
      .send({ username: 'test-user-'+randomNum })
      .expect(303)
      .end(function(err, res) {
        if (err) throw err;
        done();
      });
  });

  it('should allow for a resource to be created via PUT (single call)', function( done ) {
    var randomNum = getRandomInt( 100000 , 1000000 );
    var username = 'test-user-'+randomNum;

    rest.put( resource('/people/' + username) , {
      data: { username: username },
      headers: { accept: 'application/json' }
    }).on('complete', function(data, res) {
      assert( res.statusCode , 200 );
      done();
    });

  });

  // TODO: evaluate this from a standards perspective.  Should HTML clients
  // be treated differently?
  it('should allow for a resource to be created (html client)', function( done ) {
    var randomNum = getRandomInt( 100000 , 1000000 );
    request( maki.app )
    .post('/people')
    .set('Accept', 'text/html')
    .send({ username: 'test-user-'+randomNum })
    .expect(303)
    .end(function(err, res) {
      if (err) throw err;
      done();
    });
  });

  it('should allow for a resource to be updated via PATCH (single call)', function( done ) {
    var randomNum = getRandomInt( 100000 , 1000000 );
    var username = 'test-user-'+randomNum;

    rest.put( resource('/people/' + username) , {
      data: { username: username },
      headers: { accept: 'application/json' }
    }).on('complete', function(data, res) {
      rest.patch( resource('/people/' + username) , {
        data: { username: username + '-patched' },
        headers: { accept: 'application/json' }
      }).on('complete', function(data, res) {
        assert( data.username , username + '-patched' );
        done();
      });
    });
  });

  it('should return a created resource from an appropriate location', function( done ) {
    var randomNum = getRandomInt( 100000 , 1000000 );
    var username = 'test-user-'+randomNum;

    request( maki.app )
      .post('/people')
      .set('Accept', 'application/json')
      .send({ username: username })
      .expect(303)
      .end(function(err, res) {
        if (err) throw err;

        request( maki.app )
          .get('/people/' + username )
          .set('Accept', 'application/json')
          .expect(200)
          .end(function(err, res) {
            if (err) throw err;
            if (res.body.username !== username) throw 'no result';

            done();
          });
      });
  });

  it('should not expose restricted fields', function(done) {
    var randomNum = getRandomInt( 100000 , 1000000 );
    rest.post( resource('/people') , {
      data: {
        username: 'test-user-'+randomNum,
        hash: 'fooooooooo'
      }
    }).on('complete', function(createdDoc) {
      expect(createdDoc.hash).to.equal( undefined );
      done();
    });
  });

  it('should expose JSON when requested', function(done) {
    var randomNum = getRandomInt( 100000 , 1000000 );
    rest.post( resource('/people') , {
      data: {
        username: 'test-user-'+randomNum,
        hash: 'fooooooooo'
      }
    }).on('complete', function(createdDoc) {
      rest.get( resource('/people') , {
        headers: {
          'Accept': 'application/json'
        }
      }).on('complete', function( people ) {
        assert.ok( people.length );
        done();
      });
    });
  });

  it('should inform clients about unsupported methods', function(done) {
    rest.post( resource('/examples') , {
      headers: {
        'Accept': 'application/json'
      },
      data: {
        name: 'this-should-never-exist'
      }
    }).on('complete', function(doc, res) {
      assert( res.statusCode === 405 );
      done();
    });
  });

});

describe('https', function(){
  var https = require('https');
  var uri = resource('/', { ssl: true });

  it('should be listening for https', function() {
    https.get( uri , function(res) {
      assert.equal( res.statusCode , 200 );
    });
  });
});

describe('spdy', function(){
  var spdy = require('spdy');
  var https = require('https');
  var http = require('http');

  var agent = spdy.createAgent({
    host: '127.0.0.1',
    port: config.services.spdy.port
  });

  xit('should be listening for spdy', function( next ) {
    http.get({
      host: config.services.spdy.host,
      path: '/',
      agent: agent
    }, function(res) {

      assert.equal( res.statusCode , 201 );
      agent.close();

      next()

    }).end();
  });
});

describe('ws', function() {

  it('should allow for a websocket upgrade', function( done ) {
    var ws = new WebSocket( resource('/') );
    ws.on('open', done );
  });

  it('should correctly clean up closed sockets', function( done ) {
    var ws = new WebSocket( resource('/') );

    var orig = Object.keys(maki.clients).length;
    var prev = null;
    var curr = null;

    ws.on('close', function() {
      now = Object.keys(maki.clients).length;
      assert.ok( now < prev );
      done();
    });

    ws.on('open', function() {
      prev = Object.keys(maki.clients).length;
      ws.close();
    });

  });

  it('should respond to subscription messages', function( done ) {
    var ws = new WebSocket( resource('/') );

    ws.on('message', function(data) {
      ws.close();
      return done();
    });
    ws.on('open', function() {
      var message = new JSONRPC('subscribe', { channel: '/' });
      ws.send( message.toJSON() );
    });

  });

  it('should respond to unsubscription messages', function( done ) {
    var ws = new WebSocket( resource('/') );

    ws.on('message', function(data) {
      ws.close();
      return done();
    });
    ws.on('open', function() {
      var message = new JSONRPC('unsubscribe', { channel: '/' });
      ws.send( message.toJSON() );
    });

  });

  it('should receive pings', function( done ) {
    var ws = new WebSocket( resource('/') );

    ws.on('message', function(data) {
      var message = JSON.parse( data );
      if (message.method === 'ping') {
        ws.close();
        return done();
      }
    });
    ws.on('open', function() {
      maki.socks.markAndSweep();
    });
  });

  it('should receive a patch event for new documents', function( done ) {
    var ws = new WebSocket( resource('/people') );
    var randomNum = getRandomInt( 100000 , 1000000 );

    ws.on('message', function(data) {
      var message = JSON.parse( data );
      if (message.method === 'patch') {
        ws.close();
        return done();
      };
    });
    ws.on('open', function() {
      rest.post( resource('/people') , {
        data: { username: 'test-user-'+randomNum }
      });
    });
  });

  it('should receive a patch event for changed documents', function( done ) {
    var randomNum = getRandomInt( 100000 , 1000000 );
    var personName = 'test-user-'+randomNum;
    var personURL = resource('/people/' + personName );

    rest.post( resource('/people') , {
      data: { username: personName }
    }).on('complete', function(created) {
      var ws = new WebSocket( personURL );

      ws.on('message', function(data) {
        var message = JSON.parse( data );
        if (message.method === 'patch') {
          ws.close();
          return done();
        };
      });

      ws.on('open', function() {
        rest.patch( personURL , {
          data: { description: Math.random() }
        } );
      });
    });
  });

  it('should reject incorrect JSON', function( done ) {
    var ws = new WebSocket( resource('/') );

    ws.on('message', function(data) {
      // see http://www.jsonrpc.org/specification#error_object
      var message = JSON.parse( data );
      assert.equal( message.error.code , 32700 );
      done();
    });

    ws.on('open', function() {
      ws.send( 'fail me, I dare you' );
    });

  });

  it('should reject non-JSONRPC messages', function( done ) {
    var ws = new WebSocket( resource('/') );

    ws.on('message', function(data) {
      // see http://www.jsonrpc.org/specification#error_object
      var message = JSON.parse( data );
      assert.equal( message.error.code , 32600 );
      done();
    });

    ws.on('open', function() {
      ws.send('{}');
    });

  });

});

describe('browser', function() {
  var self = this;

  it('should correctly connect', function(done) {
    rest.get( resource('/people') , {
      headers: {
        accept: 'text/html'
      }
    }).on('complete', function(data) {
      var $ = cheerio.load(data);
      assert.ok( $.html() );
      done();
    });
  });
  it('should have a page title', function(done) {
    rest.get( resource('/people') , {
      headers: {
        accept: 'text/html'
      }
    }).on('complete', function(data) {
      var $ = cheerio.load(data);
      assert.ok( $('title').html() );
      done();
    });
  });
  it('should have a content in the content div', function( done ) {
    rest.get( resource('/people') , {
      headers: {
        accept: 'text/html'
      }
    }).on('complete', function(data) {
      var $ = cheerio.load(data);
      assert.ok( $('div.content > *').html() );
      done();
    });
  });
});

describe('browser with javascript', function() {

});

describe('cleanup', function() {
  xit('should clean up after itself', function( done ) {
    maki.destroy( done );
  });
});
<|endoftext|>


<commit_before>/*******************************
Some global helper functions:
*******************************/
debug = function (message) {
  if(console && typeof console.log != 'undefined') {
    console.log(message);
  }
}

css_attr = function(selector,attr) {
  $$(selector).each(
    function(elem) {
      debug(elem.getStyle(attr));
    }
  );
}

zindex = function(selector) {
  css_attr(selector,'z-index');
}

auth_token = function () {
  if (typeof(AUTH_TOKEN) == "undefined") {
    return false;
  }
  return AUTH_TOKEN;
}

flatten_sortables = function() {
  $$('.sortable').each(
    function(i) {
      i.setStyle({zIndex: 'auto'});
    }
  );
}

// take a extended dom_element and return a model name and id
decode_model = function(elem) {
  var dom_id = elem.identify()
  var match = dom_id.gsub(/(.*)_([0-9]+)/, function(match){
    return match;
  });
  var matches = match.split(",");
  return {type:matches[1], id: matches[2]};
 }

focus_first_field = function() {
  // This will only work if there is one and only one
  // form in the document... there is probably a better way..
  if (document.forms.size ==1) {
    var first_form = document.forms[0];
    var inputs = first_form.getInputs('text');
    if (inputs && inputs[0]) {
      inputs[0].activate();
    }
  }
}

is_mac = function() {
  if (navigator) {
    if (navigator.platform) {
      return (navigator.platform.indexOf("Mac") > -1);
    }
  }
  return false;
}

show_alert = function(elem, force) {
  if (force || (!readCookie(elem.identify()))) {
    Effect.toggle(elem, 'blind', {});
    new Effect.Opacity('wrapper', { from: 1.0, to: 0.25, duration: 0.25 });
    elem.observe('click', function(event) {
      Effect.toggle(elem, 'blind', {});
      new Effect.Opacity('wrapper', { from: 0.25, to: 1.0, duration: 0.25 });
      elem.stopObserving();
    });
  };
};

// show/hide project sign in form labels on field blur/focus
document.observe("dom:loaded", function() {
	if ($("project-signin")) {
		// username field listeners
		Event.observe('login', 'focus', function(event) {
			$("login").previous(0).setStyle({"display": "none"});
		});
		Event.observe('login', 'blur', function(event) {
			if ($("login").value == "") $("login").previous(0).setStyle({"display": "block"});
		});
		// password field listeners
		Event.observe('password', 'focus', function(event) {
			$("password").previous(0).setStyle({"display": "none"});
		});
		Event.observe('password', 'blur', function(event) {
			if ($("password").value == "") $("password").previous(0).setStyle({"display": "block"});
		});
		// check for username value on page load
		if ($("login").value != '') {
			$("login").previous(0).setStyle({"display": "none"});
		}
	}
});<commit_msg>Made login value check on page load also check for password value<commit_after>/*******************************
Some global helper functions:
*******************************/
debug = function (message) {
  if(console && typeof console.log != 'undefined') {
    console.log(message);
  }
}

css_attr = function(selector,attr) {
  $$(selector).each(
    function(elem) {
      debug(elem.getStyle(attr));
    }
  );
}

zindex = function(selector) {
  css_attr(selector,'z-index');
}

auth_token = function () {
  if (typeof(AUTH_TOKEN) == "undefined") {
    return false;
  }
  return AUTH_TOKEN;
}

flatten_sortables = function() {
  $$('.sortable').each(
    function(i) {
      i.setStyle({zIndex: 'auto'});
    }
  );
}

// take a extended dom_element and return a model name and id
decode_model = function(elem) {
  var dom_id = elem.identify()
  var match = dom_id.gsub(/(.*)_([0-9]+)/, function(match){
    return match;
  });
  var matches = match.split(",");
  return {type:matches[1], id: matches[2]};
 }

focus_first_field = function() {
  // This will only work if there is one and only one
  // form in the document... there is probably a better way..
  if (document.forms.size ==1) {
    var first_form = document.forms[0];
    var inputs = first_form.getInputs('text');
    if (inputs && inputs[0]) {
      inputs[0].activate();
    }
  }
}

is_mac = function() {
  if (navigator) {
    if (navigator.platform) {
      return (navigator.platform.indexOf("Mac") > -1);
    }
  }
  return false;
}

show_alert = function(elem, force) {
  if (force || (!readCookie(elem.identify()))) {
    Effect.toggle(elem, 'blind', {});
    new Effect.Opacity('wrapper', { from: 1.0, to: 0.25, duration: 0.25 });
    elem.observe('click', function(event) {
      Effect.toggle(elem, 'blind', {});
      new Effect.Opacity('wrapper', { from: 0.25, to: 1.0, duration: 0.25 });
      elem.stopObserving();
    });
  };
};

// show/hide project-signin form labels on field blur/focus
document.observe("dom:loaded", function() {
	if ($("project-signin")) {
		// username field listeners
		Event.observe('login', 'focus', function(event) {
			$("login").previous(0).setStyle({"display": "none"});
		});
		Event.observe('login', 'blur', function(event) {
			if ($("login").value == "") $("login").previous(0).setStyle({"display": "block"});
		});
		// password field listeners
		Event.observe('password', 'focus', function(event) {
			$("password").previous(0).setStyle({"display": "none"});
		});
		Event.observe('password', 'blur', function(event) {
			if ($("password").value == "") $("password").previous(0).setStyle({"display": "block"});
		});
		// check for username and password values on page load
		if ($("login").value != '') {
			$("login").previous(0).setStyle({"display": "none"});
		}
		if ($("password").value != '') {
			$("password").previous(0).setStyle({"display": "none"});
		}
	}
});<|endoftext|>


<commit_before>// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults

function confirm_page_change() {
  alert('test');
  }

function createCookie(name,value,days) {
    if (days) {
        var date = new Date();
        date.setTime(date.getTime()+(days*24*60*60*1000));
        var expires = "; expires="+date.toGMTString();
    }
    else var expires = "";
    document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}

function eraseCookie(name) {
    createCookie(name,"",-1);
}

function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}

// http://code.google.com/p/simile-widgets/wiki/Timeline_GettingStarted
/*
var tl;
var resizeTimerID = null;
function onResize() {
   if (resizeTimerID == null) {
       resizeTimerID = window.setTimeout(function() {
           resizeTimerID = null;
           tl.layout();
       }, 500);
   }
}
*/

function change_context() {
  document.body.style.cursor = 'wait';
  value = $('context_select').value
  new Ajax.Request('/application/change_context', {
    parameters: { context: value },
    onComplete: function(r) {
      if(value=='reporting') location = '/projects';
      if(value=='workloads') location = '/workloads';
      if(value=='tools')     location = '/tools/sdp_index';
      if(value=='ci_projects')  location = '/ci_projects';
      if(value=='logout')    location = '/sessions/logout';
      }
    });
  }

function open_checklist(milestone_id) {
  content = $('checklist_popup_content');
  content.innerHTML = "
";
  popup = $('checklist_popup')
  popup.style.width = "600px";
  popup.show();
  new Ajax.Request('/checklists/show/'+milestone_id, {
    //parameters: { context: value },
    onComplete: function(r) {
      content.innerHTML = r.responseText
      }
    });
  }

function checklist_item_set_next_status(id) {
  $('cl_image_'+id).src = '/images/loading2.gif';
  new Ajax.Request('/checklists/set_next_status', {
    parameters: { id: id}
    });
  }

function refresh_projects(sort) {
  $('loading').show();
  new Ajax.Request('/projects/refresh_projects', {
    parameters: { sort: sort },
    onComplete: function(r) {
      $('timeline').update(r.responseText);
      $('loading').hide();
      }
    });

  }

function deploy_question(id,value) {
  value = (value==true? 1 : 0)
  new Ajax.Updater('q_'+id, '/generic_risk_questions/deploy', {
    parameters: { id: id, value: value }
    });
  }

function check_requirement(form) {
  if($('req_req_category_id').value=="") {
    alert('Category can not be blank');
    return false;
    }
  if($('req_req_wave_id').value=="") {
    alert('Wave can not be blank');
    return false;
    }
  return true;
  }

function check_list_per_wp(){
  $$('.milestone_title').each(function(item,index){
    if (item.next("ul") && (item.next("ul").childElements().length==0))
    {
      item.hide();
    }
  });
		// $$('.checklist_item_template_title').each(function(item,index){
		// 		console.log(item.select("ul")[0]);
		// 	if (item.select("ul").length > 1 && (item.select("ul")[0].childElements().length==0))
		// 	{
		// 		//item.hide();
		// 		console.log(item.innerHTML + "--->" + item.next("ul").childElements());
		// 	}
		// });
}

function check_submit_form_list_per_wp()
{
  $("list_per_wp_filter_submit").observe('click', function() {
    if(($('workpackages').selectedIndex!=-1)&&($('milestones').selectedIndex!=-1)&&($('checklists').selectedIndex!=-1))
    {
      $("list_per_wp_form").submit();
    }
    else
    {
	  alert("Select one or more elements in each list.");
    }
  });
}
<commit_msg>0000531<commit_after>// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults

function confirm_page_change() {
  alert('test');
  }

function createCookie(name,value,days) {
    if (days) {
        var date = new Date();
        date.setTime(date.getTime()+(days*24*60*60*1000));
        var expires = "; expires="+date.toGMTString();
    }
    else var expires = "";
    document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}

function eraseCookie(name) {
    createCookie(name,"",-1);
}

function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}

// http://code.google.com/p/simile-widgets/wiki/Timeline_GettingStarted
/*
var tl;
var resizeTimerID = null;
function onResize() {
   if (resizeTimerID == null) {
       resizeTimerID = window.setTimeout(function() {
           resizeTimerID = null;
           tl.layout();
       }, 500);
   }
}
*/

function change_context() {
  document.body.style.cursor = 'wait';
  value = $('context_select').value
  new Ajax.Request('/application/change_context', {
    parameters: { context: value },
    onComplete: function(r) {
      if(value=='reporting') location = '/projects';
      if(value=='workloads') location = '/workloads';
      if(value=='tools')     location = '/tools/sdp_index';
      if(value=='ci_projects')  location = '/ci_projects';
      if(value=='logout')    location = '/sessions/logout';
      }
    });
  }

function open_checklist(milestone_id) {
  content = $('checklist_popup_content');
  content.innerHTML = "
";
  popup = $('checklist_popup')
  popup.style.width = "600px";
  popup.show();
  new Ajax.Request('/checklists/show/'+milestone_id, {
    //parameters: { context: value },
    onComplete: function(r) {
      content.innerHTML = r.responseText
      }
    });
  }

function checklist_item_set_next_status(id) {
  $('cl_image_'+id).src = '/images/loading2.gif';
  new Ajax.Request('/checklists/set_next_status', {
    parameters: { id: id}
    });
  }

function refresh_projects(sort) {
  $('loading').show();
  new Ajax.Request('/projects/refresh_projects', {
    parameters: { sort: sort },
    onComplete: function(r) {
      $('timeline').update(r.responseText);
      $('loading').hide();
      index_projects_timeline = 0;
      total_results           = 0;
      is_loading_projects = false;
      }
    });

  }

function deploy_question(id,value) {
  value = (value==true? 1 : 0)
  new Ajax.Updater('q_'+id, '/generic_risk_questions/deploy', {
    parameters: { id: id, value: value }
    });
  }

function check_requirement(form) {
  if($('req_req_category_id').value=="") {
    alert('Category can not be blank');
    return false;
    }
  if($('req_req_wave_id').value=="") {
    alert('Wave can not be blank');
    return false;
    }
  return true;
  }

function check_list_per_wp(){
  $$('.milestone_title').each(function(item,index){
    if (item.next("ul") && (item.next("ul").childElements().length==0))
    {
      item.hide();
    }
  });
		// $$('.checklist_item_template_title').each(function(item,index){
		// 		console.log(item.select("ul")[0]);
		// 	if (item.select("ul").length > 1 && (item.select("ul")[0].childElements().length==0))
		// 	{
		// 		//item.hide();
		// 		console.log(item.innerHTML + "--->" + item.next("ul").childElements());
		// 	}
		// });
}

function check_submit_form_list_per_wp()
{
  $("list_per_wp_filter_submit").observe('click', function() {
    if(($('workpackages').selectedIndex!=-1)&&($('milestones').selectedIndex!=-1)&&($('checklists').selectedIndex!=-1))
    {
      $("list_per_wp_form").submit();
    }
    else
    {
	  alert("Select one or more elements in each list.");
    }
  });
}
<|endoftext|>


<commit_before>/*******************************
Some global helper functions:
*******************************/
debug = function (message) {
  if(console.log) {
    console.log(message);
  }
}

css_attr = function(selector,attr) {
  $$(selector).each(
    function(elem) {
      debug(elem.getStyle(attr));
    }
  );
}

zindex = function(selector) {
  css_attr(selector,'z-index');
}

auth_token = function () {
  if (typeof(AUTH_TOKEN) == "undefined") {
    return false;
  }
  return AUTH_TOKEN;
}

flatten_sortables = function() {
  $$('.sortable').each(
    function(i) {
      i.setStyle({zIndex: 'auto'});
    }
  );
}

// take a extended dom_element and return a model name and id
decode_model = function(elem) {
  var dom_id = elem.identify()
  var match = dom_id.gsub(/(.*)_([0-9]+)/, function(match){
    return match;
  });
  var matches = match.split(",");
  return {type:matches[1], id: matches[2]};
 }

focus_first_field = function() {
  // This will only work if there is one and only one
  // form in the document... there is probably a better way..
  if (document.forms.size ==1) {
    var first_form = document.forms[0];
    var inputs = first_form.getInputs('text');
    if (inputs && inputs[0]) {
      inputs[0].activate();
    }
  }
}

// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults
dropdown_for = function(menu_dom_id,drop_down_dom_id) {
  var menu = $(menu_dom_id);
  var drop_down = $(drop_down_dom_id);
  var menu_width = menu.getDimensions().width
  var drop_down_width = drop_down.getDimensions().width
  var padding = 0;
  drop_down.hide();
  drop_down.show();
  drop_down.setStyle({'z-index': 2000});
  drop_down.setStyle({'padding' : padding + "px"})

  if (drop_down_width < menu_width) {
    drop_down.setStyle({
      width: menu_width+"px"
    });
    drop_down_width = menu_width;
  }

  var left_offset = (drop_down_width - menu_width) / -2
  var top_offset = menu.getDimensions().height - padding
  var options = { setWidth: false, setHeight: false, offsetLeft:left_offset, offsetTop: top_offset};

  drop_down.clonePosition(menu,options);

  drop_down.observe('mouseout', function(event) {
    var mouse_over_element = event.relatedTarget;
    if(mouse_over_element) {
     if (!mouse_over_element.descendantOf(drop_down)) {
       if (event.toElement != drop_down) {
         if (event.toElement != menu) {
           hide();
         }
       }
     }
    }
  });

  drop_down.observe('click', function(event) {
    hide();
  });

  function hide() {
    drop_down.fade({ duration: 0.3});
    drop_down.stopObserving();
  };
};

show_alert = function(elem, force) {
  if (force || (!readCookie(elem.identify()))) {
    Effect.toggle(elem, 'blind', {});
    new Effect.Opacity('wrapper', { from: 1.0, to: 0.25, duration: 0.25 });
    elem.observe('click', function(event) {
      Effect.toggle(elem, 'blind', {});
      new Effect.Opacity('wrapper', { from: 0.25, to: 1.0, duration: 0.25 });
      elem.stopObserving();
    });
  };
};

show_mac_content = function(element_id) {
  var el_id = element_id || 'macintosh_content';
  if (navigator.appVersion.indexOf("Mac")!=-1) {
    if ($(el_id)) {
      $(el_id).show();
    }
  };
};

document.observe("dom:loaded", function() {
  show_mac_content();
});

<commit_msg>Only show JNLP warning for mac users (once only)<commit_after>/*******************************
Some global helper functions:
*******************************/
debug = function (message) {
  if(console.log) {
    console.log(message);
  }
}

css_attr = function(selector,attr) {
  $$(selector).each(
    function(elem) {
      debug(elem.getStyle(attr));
    }
  );
}

zindex = function(selector) {
  css_attr(selector,'z-index');
}

auth_token = function () {
  if (typeof(AUTH_TOKEN) == "undefined") {
    return false;
  }
  return AUTH_TOKEN;
}

flatten_sortables = function() {
  $$('.sortable').each(
    function(i) {
      i.setStyle({zIndex: 'auto'});
    }
  );
}

// take a extended dom_element and return a model name and id
decode_model = function(elem) {
  var dom_id = elem.identify()
  var match = dom_id.gsub(/(.*)_([0-9]+)/, function(match){
    return match;
  });
  var matches = match.split(",");
  return {type:matches[1], id: matches[2]};
 }

focus_first_field = function() {
  // This will only work if there is one and only one
  // form in the document... there is probably a better way..
  if (document.forms.size ==1) {
    var first_form = document.forms[0];
    var inputs = first_form.getInputs('text');
    if (inputs && inputs[0]) {
      inputs[0].activate();
    }
  }
}

// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults
dropdown_for = function(menu_dom_id,drop_down_dom_id) {
  var menu = $(menu_dom_id);
  var drop_down = $(drop_down_dom_id);
  var menu_width = menu.getDimensions().width
  var drop_down_width = drop_down.getDimensions().width
  var padding = 0;
  drop_down.hide();
  drop_down.show();
  drop_down.setStyle({'z-index': 2000});
  drop_down.setStyle({'padding' : padding + "px"})

  if (drop_down_width < menu_width) {
    drop_down.setStyle({
      width: menu_width+"px"
    });
    drop_down_width = menu_width;
  }

  var left_offset = (drop_down_width - menu_width) / -2
  var top_offset = menu.getDimensions().height - padding
  var options = { setWidth: false, setHeight: false, offsetLeft:left_offset, offsetTop: top_offset};

  drop_down.clonePosition(menu,options);

  drop_down.observe('mouseout', function(event) {
    var mouse_over_element = event.relatedTarget;
    if(mouse_over_element) {
     if (!mouse_over_element.descendantOf(drop_down)) {
       if (event.toElement != drop_down) {
         if (event.toElement != menu) {
           hide();
         }
       }
     }
    }
  });

  drop_down.observe('click', function(event) {
    hide();
  });

  function hide() {
    drop_down.fade({ duration: 0.3});
    drop_down.stopObserving();
  };
};

is_mac = function() {
  if (navigator) {
    if (navigator.platform) {
      return (navigator.platform.indexOf("Mac") > -1);
    }
  }
  return false;
}

show_alert = function(elem, force) {
  if (force || (!readCookie(elem.identify()))) {
    Effect.toggle(elem, 'blind', {});
    new Effect.Opacity('wrapper', { from: 1.0, to: 0.25, duration: 0.25 });
    elem.observe('click', function(event) {
      Effect.toggle(elem, 'blind', {});
      new Effect.Opacity('wrapper', { from: 0.25, to: 1.0, duration: 0.25 });
      elem.stopObserving();
    });
  };
};

show_mac_alert = function(elem, force) {
  if (is_mac()) {
    show_alart(elem,force);
  }
}
// depricated I think:
/**
show_mac_content = function(element_id) {
  var el_id = element_id || 'macintosh_content';
  if (navigator.appVersion.indexOf("Mac")!=-1) {
    if ($(el_id)) {
      $(el_id).show();
    }
  };
};
**/

document.observe("dom:loaded", function() {
  show_mac_content();
});

<|endoftext|>