<commit_before>(function($) {

	/**
	 * @class Base edit form, provides ajaxified saving
	 * and reloading itself through the ajax return values.
	 * Takes care of resizing tabsets within the layout container.
	 * @name ss.Form_EditForm
	 * @require jquery.changetracker
	 *
	 *
Events

	 * - ajaxsubmit: Form is about to be submitted through ajax
	 * - validate: Contains validation result
	 * - removeform: A form is about to be removed from the DOM
	 * - load: Form is about to be loaded through ajax
	 */
	$('#Form_EditForm').concrete('ss',function($){
		return/** @lends ss.Form_EditForm */{

			/**
			 * @type String HTML text to show when no form content is chosen.
			 *  Will show inside the <form> tag.
			 */
			PlaceholderHtml: '',

			/**
			 * @type Object
			 */
			ChangeTrackerOptions: {},

			onmatch: function() {
				var self = this;

				this._setupChangeTracker();

				// Can't bind this through jQuery
				window.onbeforeunload = function(e) {return self._checkChangeTracker(false);};

				$._super();
			},

			_setupChangeTracker: function() {
				// Don't bind any events here, as we dont replace the
				// full <form> tag by any ajax updates they won't automatically reapply
				this.changetracker(this.ChangeTrackerOptions());
			},

			/**
			 * Checks the jquery.changetracker plugin status for this form.
			 * Usually bound to window.onbeforeunload.
			 *
			 * @param {boolean} isUnloadEvent
			 * @return Either a string with a confirmation message, or the result of a confirm() dialog,
			 *  based on the isUnloadEvent parameter.
			 */
			_checkChangeTracker: function(isUnloadEvent) {
			  var self = this;

				// @todo TinyMCE coupling
				if(typeof tinyMCE != 'undefined') tinyMCE.triggerSave();

				// check for form changes
				if(self.is('.changed')) {
					// returned string will trigger a confirm() dialog,
					// but only if the method is triggered by an event
					if(isUnloadEvent) {
						return confirm(ss.i18n._t('LeftAndMain.CONFIRMUNSAVED'));
					} else {
						return ss.i18n._t('LeftAndMain.CONFIRMUNSAVEDSHORT');
					}
				}
			},

			/**
			 * Suppress submission unless it is handled through ajaxSubmit().
			 *
			 * @param {Event} e
			 */
			onsubmit: function(e) {
				return false;
			},

			/**
			 * @param {DOMElement} button The pressed button (optional)
			 * @param {Function} callback Called in complete() handler of jQuery.ajax()
			 * @param {Object} ajaxOptions Object literal to merge into $.ajax() call
			 * @param {boolean} loadResponse Render response through _loadResponse() (Default: true)
			 */
			ajaxSubmit: function(button, callback, ajaxOptions, loadResponse) {
			  var self = this;

				// look for save button
				if(!button) button = this.find('.Actions :submit[name=action_save]');
				// default to first button if none given - simulates browser behaviour
				if(!button) button = this.find('.Actions :submit:first');

				this.trigger('ajaxsubmit', {button: button});

				// set button to "submitting" state
				$(button).addClass('loading');

				// @todo TinyMCE coupling
				if(typeof tinyMCE != 'undefined') tinyMCE.triggerSave();

				// validate if required
				if(!this.validate()) {
					// TODO Automatically switch to the tab/position of the first error
					statusMessage("Validation failed.", "bad");

					$(button).removeClass('loading');

					return false;
				}

				// get all data from the form
				var formData = this.serializeArray();
				// add button action
				formData.push({name: $(button).attr('name'), value:'1'});
				jQuery.ajax(jQuery.extend({
					url: this.attr('action'),
					data: formData,
					type: 'POST',
					complete: function(xmlhttp, status) {
						$(button).removeClass('loading');

						// TODO This should be using the plugin API
						self.removeClass('changed');

						if(callback) callback(xmlhttp, status);

						// pass along original form data to enable old/new comparisons
						if(loadResponse !== false) {
						  self._loadResponse(xmlhttp.responseText, status, xmlhttp, formData);
						}
					},
					dataType: 'html'
				}, ajaxOptions));

				return false;
			},

			/**
			 * Hook in (optional) validation routines.
			 * Currently clientside validation is not supported out of the box in the CMS.
			 *
			 * @todo Placeholder implementation
			 *
			 * @return {boolean}
			 */
			validate: function() {
				var isValid = true;
				this.trigger('validate', {isValid: isValid});

				return isValid;
			},

			/**
			 * @param {String} url
			 * @param {Function} callback (Optional) Called after the form content as been loaded
			 * @param {ajaxOptions} Object literal merged into the jQuery.ajax() call (Optional)
			 */
			load: function(url, callback, ajaxOptions) {
				var self = this;

				// Alert when unsaved changes are present
				if(this._checkChangeTracker(true) == false) return false;

				this.trigger('load');

				return jQuery.ajax(jQuery.extend({
					url: url,
					complete: function(xmlhttp, status) {
					  // TODO This should be using the plugin API
						self.removeClass('changed');

						self._loadResponse(xmlhttp.responseText, status, xmlhttp);

						if(callback) callback.apply(self, arguments);
					},
					dataType: 'html'
				}, ajaxOptions));
			},

			/**
			 * Remove everying inside the <form> tag
			 * with a custom HTML fragment. Useful e.g. for deleting a page in the CMS.
			 * Checks for unsaved changes before removing the form
			 *
			 * @param {String} placeholderHtml Short note why the form has been removed, displayed in
 tags.
			 *  Falls back to the default RemoveText() option (Optional)
			 */
			removeForm: function(placeholderHtml) {
				if(!placeholderHtml) placeholderHtml = this.PlaceholderHtml();

				// Alert when unsaved changes are present
				if(this._checkChangeTracker(true) == false) return false;

				this.trigger('removeform');

				this.html(placeholderHtml);

				// TODO This should be using the plugin API
				this.removeClass('changed');
			},

			/**
			 * Remove all the currently active TinyMCE editors.
			 * Note: Everything that calls this externally has an inappropriate coupling to TinyMCE.
			 */
			cleanup: function() {
				if((typeof tinymce != 'undefined') && tinymce.EditorManager) {
					var id;
					for(id in tinymce.EditorManager.editors) {
						tinymce.EditorManager.editors[id].remove();
					}
					tinymce.EditorManager.editors = {};
				}
			},

			/**
			 * @param {String} data Either HTML for straight insertion, or eval'ed JavaScript.
			 *  If passed as HTML, it is assumed that everying inside the <form> tag is replaced,
			 *  but the old <form> tag itself stays intact.
			 * @param {String} status
			 * @param {XMLHTTPRequest} xmlhttp
			 * @param {Array} origData The original submitted data, useful to do comparisons of changed
			 *  values in new form output, e.g. to detect a URLSegment being changed on the serverside.
			 *  Array in jQuery serializeArray() notation.
			 */
			_loadResponse: function(data, status, xmlhttp, origData) {
				if(status == 'success') {
					this.cleanup();

					var html = data;

					// Rewrite # links
					html = html.replace(/(]+href *= *")#/g, '$1' + window.location.href.replace(/#.*$/,'') + '#');

					// Rewrite iframe links (for IE)
					html = html.replace(/(]*src=")([^"]+)("[^>]*>)/g, '$1' + $('base').attr('href') + '$2$3');

					// Prepare iframes for removal, otherwise we get loading bugs
					this.find('iframe').each(function() {
						this.contentWindow.location.href = 'about:blank';
						this.remove();
					});

					// update form content
					if(html) {
						this.html(html);
					} else {
						this.removeForm();
					}

					this._setupChangeTracker();

					// Optionally get the form attributes from embedded fields, see Form->formHtmlContent()
					for(var overrideAttr in {'action':true,'method':true,'enctype':true,'name':true}) {
						var el = this.find(':input[name='+ '_form_' + overrideAttr + ']');
						if(el) {
							this.attr(overrideAttr, el.val());
							el.remove();
						}
					}

					Behaviour.apply(); // refreshes ComplexTableField

					// focus input on first form element
					this.find(':input:visible:first').focus();

					this.trigger('loadnewpage', {data: data, origData: origData});
				}

				// set status message based on response
				var _statusMessage = (xmlhttp.getResponseHeader('X-Status')) ? xmlhttp.getResponseHeader('X-Status') : xmlhttp.statusText;
				if(this.hasClass('validationerror')) {
					// TODO validation shouldnt need a special case
					statusMessage(ss.i18n._t('ModelAdmin.VALIDATIONERROR', 'Validation Error'), 'bad');
				} else {
					statusMessage(_statusMessage, (xmlhttp.status >= 400) ? 'bad' : 'good');
				}
			}
		};
	});

	/**
	 * @class All buttons in the right CMS form go through here by default.
	 * We need this onclick overloading because we can't get to the
	 * clicked button from a form.onsubmit event.
	 * @name ss.Form_EditForm.Actions.submit
	 */
	$('#Form_EditForm .Actions :submit').concrete('ss', function($){
		return/** @lends ss.Form_EditForm.Actions.submit */{
			onmatch: function() {
			  var self = this;

				// TODO Fix once concrete library is updated
				this.bind('click', function(e) {return self.clickFake(e);});
			},
			clickFake: function(e) {
				$(this[0].form).concrete('ss').ajaxSubmit(this);
				return false;
			}
		};
	});

	/**
	 * @class Add tinymce to HtmlEditorFields within the CMS.
	 * @name ss.Form_EditForm.textarea.htmleditor
	 */
	$('#Form_EditForm textarea.htmleditor').concrete('ss', function($){
		return/** @lends ss.Form_EditForm.Actions.submit */{
			onmatch : function() {
				tinyMCE.execCommand("mceAddControl", true, this.attr('id'));
				this.isChanged = function() {
					return tinyMCE.getInstanceById(this.attr('id')).isDirty();
				}
				this.resetChanged = function() {
					var inst = tinyMCE.getInstanceById(this.attr('id'));
					if (inst) inst.startContent = tinymce.trim(inst.getContent({format : 'raw', no_events : 1}));
				}
			}
		};
	});
}(jQuery));<commit_msg>BUGFIX Fixed onsubmit() concrete handlers in LeftAndMain.EditForm.js<commit_after>(function($) {

	/**
	 * @class Base edit form, provides ajaxified saving
	 * and reloading itself through the ajax return values.
	 * Takes care of resizing tabsets within the layout container.
	 * @name ss.Form_EditForm
	 * @require jquery.changetracker
	 *
	 *
Events

	 * - ajaxsubmit: Form is about to be submitted through ajax
	 * - validate: Contains validation result
	 * - removeform: A form is about to be removed from the DOM
	 * - load: Form is about to be loaded through ajax
	 */
	$('#Form_EditForm').concrete('ss',function($){
		return/** @lends ss.Form_EditForm */{

			/**
			 * @type String HTML text to show when no form content is chosen.
			 *  Will show inside the <form> tag.
			 */
			PlaceholderHtml: '',

			/**
			 * @type Object
			 */
			ChangeTrackerOptions: {},

			onmatch: function() {
				var self = this;

				this._setupChangeTracker();

				this.bind('submit', function(e) {
				  return self._submit(e);
				});

				// Can't bind this through jQuery
				window.onbeforeunload = function(e) {return self._checkChangeTracker(false);};

				this._super();
			},

			_setupChangeTracker: function() {
				// Don't bind any events here, as we dont replace the
				// full <form> tag by any ajax updates they won't automatically reapply
				this.changetracker(this.ChangeTrackerOptions());
			},

			/**
			 * Checks the jquery.changetracker plugin status for this form.
			 * Usually bound to window.onbeforeunload.
			 *
			 * @param {boolean} isUnloadEvent
			 * @return Either a string with a confirmation message, or the result of a confirm() dialog,
			 *  based on the isUnloadEvent parameter.
			 */
			_checkChangeTracker: function(isUnloadEvent) {
			  var self = this;

				// @todo TinyMCE coupling
				if(typeof tinyMCE != 'undefined') tinyMCE.triggerSave();

				// check for form changes
				if(self.is('.changed')) {
					// returned string will trigger a confirm() dialog,
					// but only if the method is triggered by an event
					if(isUnloadEvent) {
						return confirm(ss.i18n._t('LeftAndMain.CONFIRMUNSAVED'));
					} else {
						return ss.i18n._t('LeftAndMain.CONFIRMUNSAVEDSHORT');
					}
				}
			},

			/**
			 * Suppress submission unless it is handled through ajaxSubmit().
			 *
			 * @param {Event} e
			 */
			_submit: function(e) {
			  this.ajaxSubmit();
				return false;
			},

			/**
			 * @param {DOMElement} button The pressed button (optional)
			 * @param {Function} callback Called in complete() handler of jQuery.ajax()
			 * @param {Object} ajaxOptions Object literal to merge into $.ajax() call
			 * @param {boolean} loadResponse Render response through _loadResponse() (Default: true)
			 */
			ajaxSubmit: function(button, callback, ajaxOptions, loadResponse) {
			  var self = this;

				// look for save button
				if(!button) button = this.find('.Actions :submit[name=action_save]');
				// default to first button if none given - simulates browser behaviour
				if(!button) button = this.find('.Actions :submit:first');

				this.trigger('ajaxsubmit', {button: button});

				// set button to "submitting" state
				$(button).addClass('loading');

				// @todo TinyMCE coupling
				if(typeof tinyMCE != 'undefined') tinyMCE.triggerSave();

				// validate if required
				if(!this.validate()) {
					// TODO Automatically switch to the tab/position of the first error
					statusMessage("Validation failed.", "bad");

					$(button).removeClass('loading');

					return false;
				}

				// get all data from the form
				var formData = this.serializeArray();
				// add button action
				formData.push({name: $(button).attr('name'), value:'1'});
				jQuery.ajax(jQuery.extend({
					url: this.attr('action'),
					data: formData,
					type: 'POST',
					complete: function(xmlhttp, status) {
						$(button).removeClass('loading');

						// TODO This should be using the plugin API
						self.removeClass('changed');

						if(callback) callback(xmlhttp, status);

						// pass along original form data to enable old/new comparisons
						if(loadResponse !== false) {
						  self._loadResponse(xmlhttp.responseText, status, xmlhttp, formData);
						}
					},
					dataType: 'html'
				}, ajaxOptions));

				return false;
			},

			/**
			 * Hook in (optional) validation routines.
			 * Currently clientside validation is not supported out of the box in the CMS.
			 *
			 * @todo Placeholder implementation
			 *
			 * @return {boolean}
			 */
			validate: function() {
				var isValid = true;
				this.trigger('validate', {isValid: isValid});

				return isValid;
			},

			/**
			 * @param {String} url
			 * @param {Function} callback (Optional) Called after the form content as been loaded
			 * @param {ajaxOptions} Object literal merged into the jQuery.ajax() call (Optional)
			 */
			loadForm: function(url, callback, ajaxOptions) {
				var self = this;

				// Alert when unsaved changes are present
				if(this._checkChangeTracker(true) == false) return false;

				this.trigger('load');

				return jQuery.ajax(jQuery.extend({
					url: url,
					complete: function(xmlhttp, status) {
					  // TODO This should be using the plugin API
						self.removeClass('changed');

						self._loadResponse(xmlhttp.responseText, status, xmlhttp);

						if(callback) callback.apply(self, arguments);
					},
					dataType: 'html'
				}, ajaxOptions));
			},

			/**
			 * Remove everying inside the <form> tag
			 * with a custom HTML fragment. Useful e.g. for deleting a page in the CMS.
			 * Checks for unsaved changes before removing the form
			 *
			 * @param {String} placeholderHtml Short note why the form has been removed, displayed in
 tags.
			 *  Falls back to the default RemoveText() option (Optional)
			 */
			removeForm: function(placeholderHtml) {
				if(!placeholderHtml) placeholderHtml = this.PlaceholderHtml();

				// Alert when unsaved changes are present
				if(this._checkChangeTracker(true) == false) return false;

				this.trigger('removeform');

				this.html(placeholderHtml);

				// TODO This should be using the plugin API
				this.removeClass('changed');
			},

			/**
			 * Remove all the currently active TinyMCE editors.
			 * Note: Everything that calls this externally has an inappropriate coupling to TinyMCE.
			 */
			cleanup: function() {
				if((typeof tinymce != 'undefined') && tinymce.EditorManager) {
					var id;
					for(id in tinymce.EditorManager.editors) {
						tinymce.EditorManager.editors[id].remove();
					}
					tinymce.EditorManager.editors = {};
				}
			},

			/**
			 * @param {String} data Either HTML for straight insertion, or eval'ed JavaScript.
			 *  If passed as HTML, it is assumed that everying inside the <form> tag is replaced,
			 *  but the old <form> tag itself stays intact.
			 * @param {String} status
			 * @param {XMLHTTPRequest} xmlhttp
			 * @param {Array} origData The original submitted data, useful to do comparisons of changed
			 *  values in new form output, e.g. to detect a URLSegment being changed on the serverside.
			 *  Array in jQuery serializeArray() notation.
			 */
			_loadResponse: function(data, status, xmlhttp, origData) {
				if(status == 'success') {
					this.cleanup();

					var html = data;

					// Rewrite # links
					html = html.replace(/(]+href *= *")#/g, '$1' + window.location.href.replace(/#.*$/,'') + '#');

					// Rewrite iframe links (for IE)
					html = html.replace(/(]*src=")([^"]+)("[^>]*>)/g, '$1' + $('base').attr('href') + '$2$3');

					// Prepare iframes for removal, otherwise we get loading bugs
					this.find('iframe').each(function() {
						this.contentWindow.location.href = 'about:blank';
						this.remove();
					});

					// update form content
					if(html) {
						this.html(html);
					} else {
						this.removeForm();
					}

					this._setupChangeTracker();

					// Optionally get the form attributes from embedded fields, see Form->formHtmlContent()
					for(var overrideAttr in {'action':true,'method':true,'enctype':true,'name':true}) {
						var el = this.find(':input[name='+ '_form_' + overrideAttr + ']');
						if(el) {
							this.attr(overrideAttr, el.val());
							el.remove();
						}
					}

					Behaviour.apply(); // refreshes ComplexTableField

					// focus input on first form element
					this.find(':input:visible:first').focus();

					this.trigger('loadnewpage', {data: data, origData: origData});
				}

				// set status message based on response
				var _statusMessage = (xmlhttp.getResponseHeader('X-Status')) ? xmlhttp.getResponseHeader('X-Status') : xmlhttp.statusText;
				if(this.hasClass('validationerror')) {
					// TODO validation shouldnt need a special case
					statusMessage(ss.i18n._t('ModelAdmin.VALIDATIONERROR', 'Validation Error'), 'bad');
				} else {
					statusMessage(_statusMessage, (xmlhttp.status >= 400) ? 'bad' : 'good');
				}
			}
		};
	});

	/**
	 * @class All buttons in the right CMS form go through here by default.
	 * We need this onclick overloading because we can't get to the
	 * clicked button from a form.onsubmit event.
	 * @name ss.Form_EditForm.Actions.submit
	 */
	$('#Form_EditForm .Actions :submit').concrete('ss', function($){
		return/** @lends ss.Form_EditForm.Actions.submit */{
			onmatch: function() {
			  var self = this;

				// TODO Fix once concrete library is updated
				this.bind('click', function(e) {return self.clickFake(e);});
			},
			clickFake: function(e) {
				$(this[0].form).concrete('ss').ajaxSubmit(this);
				return false;
			}
		};
	});

	/**
	 * @class Add tinymce to HtmlEditorFields within the CMS.
	 * @name ss.Form_EditForm.textarea.htmleditor
	 */
	$('#Form_EditForm textarea.htmleditor').concrete('ss', function($){
		return/** @lends ss.Form_EditForm.Actions.submit */{
			onmatch : function() {
				tinyMCE.execCommand("mceAddControl", true, this.attr('id'));
				this.isChanged = function() {
					return tinyMCE.getInstanceById(this.attr('id')).isDirty();
				}
				this.resetChanged = function() {
					var inst = tinyMCE.getInstanceById(this.attr('id'));
					if (inst) inst.startContent = tinymce.trim(inst.getContent({format : 'raw', no_events : 1}));
				}
			}
		};
	});
}(jQuery));<|endoftext|>


<commit_before>
function showSubsiteMenu() {
	//select all text
	jQuery('#SubsiteActions #SubsiteSearch')[0].select();

	form = jQuery('#SubsiteActions');
	form.animate({height: '540px'},333);
	form.addClass('active');
	applySubsiteFilters();	//reset the list to show 'all'
}

function hideSubsiteMenu() {
	form = jQuery('#SubsiteActions');

	if (form.hasClass('active')) {
		form.animate({height: '20px'},333);
		form.removeClass('active');
		jQuery('#SubsiteActions #SubsiteSearch').val(jQuery('input#SubsiteID').attr('data-title'));
		return true;
	} else return false;

}

function toggleSubsiteMenu() {
	if (!hideSubsiteMenu())
		showSubsiteMenu();
}

/**
 * Change the subsite to the one specified. This involves an ajax call.
 * @param subsiteid	int	 new subsite ID
 */
function changeSubsite(subsiteid) {
	if (!subsiteid)
		return false;

	if($('Form_AddPageOptionsForm_SubsiteID')) {
		$('Form_AddPageOptionsForm_SubsiteID').value = subsiteid;
	}
	showSubsiteSpinner();

	var request = new Ajax.Request(SiteTreeHandlers.controller_url + '/changesubsite?SubsiteID=' + subsiteid + '&ajax=1', {
		onSuccess: function(response) {
			hideSubsiteSpinner();
			if ($('sitetree')) {
				$('sitetree').innerHTML = response.responseText;
				SiteTree.applyTo($('sitetree'));
				$('sitetree').getTreeNodeByIdx(0).onselect();
				$('siteTreeFilterList').reapplyIfNeeded();
			}
			//fire the change event for the #SubsiteID hidden input.
			//	if you want to run custom code (e.g to refresh) on subsite change,
			//	bind an event to $('#SubsiteActions #SubsiteID').change();
			jQuery('#SubsiteActions #SubsiteID').trigger('change');
		},

		onFailure: function(response) {
			jQuery("#SubsiteActions .icons .fa-spinner").remove();

			errorMessage('Could not change subsite', response);
		}
	});
}

jQuery(window).click(function(evt) {
	if (jQuery(evt.target).parents('#SubsiteActions').length == 0) {
		//element is not a child of the subsite menu - hide the menu.
		hideSubsiteMenu();
	}
});

/**
 * Applies subsite filters. This is how you reset the subsite list to a 'show all' state
 * @returns
 */
function applySubsiteFilters() {

	var activeOnly = jQuery("input#active-only").is(':checked');

	jQuery('ul#SubsitesSelect li a').each(function() {
		ele = jQuery(this);
		var show = true;

		if (activeOnly) {
			if (ele.attr('data-active') != "1")
				show = false;
		}

		if (show)
			ele.parent().show();
		else
			ele.parent().hide();

	});
}

//var used to store timeout for search
var searchTimeout = false;

function doSubsiteSearch() {
	var searchTerm = jQuery('#SubsiteActions #SubsiteSearch').val().toLowerCase();
	applySubsiteFilters();
	jQuery('ul#SubsitesSelect li a').each(function() {
		ele = jQuery(this);
		if (ele.text().toLowerCase().indexOf(searchTerm) != -1) {
			ele.parent().show();
		} else
			ele.parent().hide();
	});

	hideSubsiteSpinner();

}

function showSubsiteSpinner() {
	if (jQuery("#SubsiteActions .icons .fa-spinner").length) return false;	//there can be only one!

	spinner = jQuery('');
	jQuery('#SubsiteActions .icons').prepend(spinner);
}

function hideSubsiteSpinner() {
	jQuery("#SubsiteActions .icons .fa-spinner").remove();
}

Behaviour.register({

	//DM: @TODO: this function is now defunct, remove it:
	'#SubsiteActions select' : {
		onchange: function() {
			if($('Form_AddPageOptionsForm_SubsiteID')) {
				$('Form_AddPageOptionsForm_SubsiteID').value = this.value;
			}
			var request = new Ajax.Request(SiteTreeHandlers.controller_url + '/changesubsite?SubsiteID=' + this.value + '&ajax=1', {
				onSuccess: function(response) {
					if ($('sitetree')) {
						$('sitetree').innerHTML = response.responseText;
						SiteTree.applyTo($('sitetree'));
						$('sitetree').getTreeNodeByIdx(0).onselect();
						$('siteTreeFilterList').reapplyIfNeeded();
					}
				},

				onFailure: function(response) {
					errorMessage('Could not change subsite', response);
				}
			});
		}
	},

	'#SubsiteActions #SubsiteSearch': {
		onfocus: function() {
			showSubsiteMenu();
		},
		onkeyup: function() {
			showSubsiteSpinner();

			//we don't run the search immediately, we wait 333ms for another keystroke
			if (searchTimeout) window.clearTimeout(searchTimeout);
			searchTimeout = window.setTimeout(doSubsiteSearch,666);
		}
	},
	'#SubsiteActions .icons .caret': {
		onclick: function() {
			toggleSubsiteMenu();
		}
	},

	'ul#SubsitesSelect li a': {
		onclick: function() {
			itm=jQuery(this);

			textbox = jQuery('#SubsiteActions #SubsiteSearch');
			textbox.val(itm.text());

			jQuery('ul#SubsitesSelect li a').removeClass('selected');
			itm.addClass('selected');

			id = itm.attr('data-value');

			ele = jQuery('input#SubsiteID')
			ele.val(id);
			ele.attr('data-title',itm.text());

			changeSubsite(id);

			hideSubsiteMenu();
		}
	},

	"input#active-only": {
		onchange: function() {
			applySubsiteFilters();
		}
	},

	//DM: I don't think this "new subsite" item exists anywhere. was just #SubsiteActions a
	'#SubsiteActions a.new-subsite' : {
		onclick: function() {
			var subsiteName = prompt('Enter the name of the new site','');
			if(subsiteName && subsiteName != '') {
				var request = new Ajax.Request(this.href + '?Name=' + encodeURIComponent(subsiteName) + '&ajax=1', {
					onSuccess: function(response) {
						var origSelect = $('SubsitesSelect');
						var div = document.createElement('div');
						div.innerHTML = response.responseText;
						var newSelect = div.firstChild;

						while(origSelect.length > 0)
							origSelect.remove(0);

						for(var j = 0; j < newSelect.length; j++) {
							var opt = newSelect.options.item(j).cloneNode(true);
							var newOption = document.createElement('option');

							/*if(opt.text)
								newOption.text = opt.text;*/
							if(opt.firstChild)
								newOption.text = opt.firstChild.nodeValue;

							newOption.value = opt.value;
							try {
								origSelect.add(newOption, null);
							} catch(ex) {
								origSelect.add(newOption);
							}
						}

						statusMessage('Created ' + subsiteName, 'good');
					},
					onFailure: function(response) {
						errorMessage('Could not create new subsite', response);
					}
				});
			}

			return false;
		}
	},

	// Subsite tab of Group editor
	'#Form_EditForm_AccessAllSubsites' : {
		initialize: function () {
			this.showHideSubsiteList();
			var i=0,items=this.getElementsByTagName('input');
			for(i=0;i<items.length;i++) {
				items[i].onchange = this.showHideSubsiteList;
			}
		},

		showHideSubsiteList : function () {
			$('Form_EditForm_Subsites').parentNode.style.display =
				Form.Element.getValue($('Form_EditForm').AccessAllSubsites)==1 ? 'none' : '';
		}
	}
});

// Add an item to fieldsToIgnore
Behaviour.register({
	'#Form_EditForm' : {
		initialize: function () {
			this.changeDetection_fieldsToIgnore.IsSubsite = true;
		}
	}
});

fitToParent('ResultTable_holder');
<commit_msg>github #114: fix bug where filters do not apply when searching<commit_after>
function showSubsiteMenu() {
	//select all text
	jQuery('#SubsiteActions #SubsiteSearch')[0].select();

	form = jQuery('#SubsiteActions');
	form.animate({height: '540px'},333);
	form.addClass('active');
	applySubsiteFilters();	//reset the list to show 'all'
}

function hideSubsiteMenu() {
	form = jQuery('#SubsiteActions');

	if (form.hasClass('active')) {
		form.animate({height: '20px'},333);
		form.removeClass('active');
		jQuery('#SubsiteActions #SubsiteSearch').val(jQuery('input#SubsiteID').attr('data-title'));
		return true;
	} else return false;

}

function toggleSubsiteMenu() {
	if (!hideSubsiteMenu())
		showSubsiteMenu();
}

/**
 * Change the subsite to the one specified. This involves an ajax call.
 * @param subsiteid	int	 new subsite ID
 */
function changeSubsite(subsiteid) {
	if (!subsiteid)
		return false;

	if($('Form_AddPageOptionsForm_SubsiteID')) {
		$('Form_AddPageOptionsForm_SubsiteID').value = subsiteid;
	}
	showSubsiteSpinner();

	var request = new Ajax.Request(SiteTreeHandlers.controller_url + '/changesubsite?SubsiteID=' + subsiteid + '&ajax=1', {
		onSuccess: function(response) {
			hideSubsiteSpinner();
			if ($('sitetree')) {
				$('sitetree').innerHTML = response.responseText;
				SiteTree.applyTo($('sitetree'));
				$('sitetree').getTreeNodeByIdx(0).onselect();
				$('siteTreeFilterList').reapplyIfNeeded();
			}
			//fire the change event for the #SubsiteID hidden input.
			//	if you want to run custom code (e.g to refresh) on subsite change,
			//	bind an event to $('#SubsiteActions #SubsiteID').change();
			jQuery('#SubsiteActions #SubsiteID').trigger('change');
		},

		onFailure: function(response) {
			jQuery("#SubsiteActions .icons .fa-spinner").remove();

			errorMessage('Could not change subsite', response);
		}
	});
}

jQuery(window).click(function(evt) {
	if (jQuery(evt.target).parents('#SubsiteActions').length == 0) {
		//element is not a child of the subsite menu - hide the menu.
		hideSubsiteMenu();
	}
});

/**
 * Applies subsite filters. This is how you reset the subsite list to a 'show all' state
 * @returns
 */
function applySubsiteFilters() {

	var activeOnly = jQuery("input#active-only").is(':checked');

	jQuery('ul#SubsitesSelect li a').each(function() {
		ele = jQuery(this);
		var show = true;

		if (activeOnly) {
			if (ele.attr('data-active') != "1")
				show = false;
		}

		if (show)
			ele.parent().show();
		else
			ele.parent().hide();

	});
}

//var used to store timeout for search
var searchTimeout = false;

function doSubsiteSearch() {
	var searchTerm = jQuery('#SubsiteActions #SubsiteSearch').val().toLowerCase();
	applySubsiteFilters();
	jQuery('ul#SubsitesSelect li a').each(function() {
		ele = jQuery(this);
		if (ele.parent().is(':visible')) {
			if (ele.text().toLowerCase().indexOf(searchTerm) != -1) {
				ele.parent().show();
			} else
				ele.parent().hide();
		}
	});

	hideSubsiteSpinner();

}

function showSubsiteSpinner() {
	if (jQuery("#SubsiteActions .icons .fa-spinner").length) return false;	//there can be only one!

	spinner = jQuery('');
	jQuery('#SubsiteActions .icons').prepend(spinner);
}

function hideSubsiteSpinner() {
	jQuery("#SubsiteActions .icons .fa-spinner").remove();
}

Behaviour.register({

	//DM: @TODO: this function is now defunct, remove it:
	'#SubsiteActions select' : {
		onchange: function() {
			if($('Form_AddPageOptionsForm_SubsiteID')) {
				$('Form_AddPageOptionsForm_SubsiteID').value = this.value;
			}
			var request = new Ajax.Request(SiteTreeHandlers.controller_url + '/changesubsite?SubsiteID=' + this.value + '&ajax=1', {
				onSuccess: function(response) {
					if ($('sitetree')) {
						$('sitetree').innerHTML = response.responseText;
						SiteTree.applyTo($('sitetree'));
						$('sitetree').getTreeNodeByIdx(0).onselect();
						$('siteTreeFilterList').reapplyIfNeeded();
					}
				},

				onFailure: function(response) {
					errorMessage('Could not change subsite', response);
				}
			});
		}
	},

	'#SubsiteActions #SubsiteSearch': {
		onfocus: function() {
			showSubsiteMenu();
		},
		onkeyup: function() {
			showSubsiteSpinner();

			//we don't run the search immediately, we wait 333ms for another keystroke
			if (searchTimeout) window.clearTimeout(searchTimeout);
			searchTimeout = window.setTimeout(doSubsiteSearch,666);
		}
	},
	'#SubsiteActions .icons .caret': {
		onclick: function() {
			toggleSubsiteMenu();
		}
	},

	'ul#SubsitesSelect li a': {
		onclick: function() {
			itm=jQuery(this);

			textbox = jQuery('#SubsiteActions #SubsiteSearch');
			textbox.val(itm.text());

			jQuery('ul#SubsitesSelect li a').removeClass('selected');
			itm.addClass('selected');

			id = itm.attr('data-value');

			ele = jQuery('input#SubsiteID')
			ele.val(id);
			ele.attr('data-title',itm.text());

			changeSubsite(id);

			hideSubsiteMenu();
		}
	},

	"input#active-only": {
		onchange: function() {
			applySubsiteFilters();
		}
	},

	//DM: I don't think this "new subsite" item exists anywhere. was just #SubsiteActions a
	'#SubsiteActions a.new-subsite' : {
		onclick: function() {
			var subsiteName = prompt('Enter the name of the new site','');
			if(subsiteName && subsiteName != '') {
				var request = new Ajax.Request(this.href + '?Name=' + encodeURIComponent(subsiteName) + '&ajax=1', {
					onSuccess: function(response) {
						var origSelect = $('SubsitesSelect');
						var div = document.createElement('div');
						div.innerHTML = response.responseText;
						var newSelect = div.firstChild;

						while(origSelect.length > 0)
							origSelect.remove(0);

						for(var j = 0; j < newSelect.length; j++) {
							var opt = newSelect.options.item(j).cloneNode(true);
							var newOption = document.createElement('option');

							/*if(opt.text)
								newOption.text = opt.text;*/
							if(opt.firstChild)
								newOption.text = opt.firstChild.nodeValue;

							newOption.value = opt.value;
							try {
								origSelect.add(newOption, null);
							} catch(ex) {
								origSelect.add(newOption);
							}
						}

						statusMessage('Created ' + subsiteName, 'good');
					},
					onFailure: function(response) {
						errorMessage('Could not create new subsite', response);
					}
				});
			}

			return false;
		}
	},

	// Subsite tab of Group editor
	'#Form_EditForm_AccessAllSubsites' : {
		initialize: function () {
			this.showHideSubsiteList();
			var i=0,items=this.getElementsByTagName('input');
			for(i=0;i<items.length;i++) {
				items[i].onchange = this.showHideSubsiteList;
			}
		},

		showHideSubsiteList : function () {
			$('Form_EditForm_Subsites').parentNode.style.display =
				Form.Element.getValue($('Form_EditForm').AccessAllSubsites)==1 ? 'none' : '';
		}
	}
});

// Add an item to fieldsToIgnore
Behaviour.register({
	'#Form_EditForm' : {
		initialize: function () {
			this.changeDetection_fieldsToIgnore.IsSubsite = true;
		}
	}
});

fitToParent('ResultTable_holder');
<|endoftext|>


<commit_before>//x times corpse smooch combo.
function CorpseSmooch(session){
	this.session = session;
	this.canRepeat = true;
	this.playerList = [];  //what players are already in the medium when i trigger?
	this.dreamersToRevive = [];
	this.combo = 0;

	this.trigger = function(playerList){
		this.playerList = playerList;
		this.dreamersToRevive = [];
		//all dead players who aren't god tier and are destined to be god tier god tier now.
		var deadPlayers = findDeadPlayers(playerList);
		for(var i = 0; i<deadPlayers.length; i++){
			var p = deadPlayers[i];
			//only get one shot at this. if you're a jerk, no luck.
			if(p.dreamSelf){
				this.dreamersToRevive.push(p);
			}
		}
		//corspses can't smooch themselves.
		return this.dreamersToRevive.length > 0 && this.dreamersToRevive.length < playerList.length;

	}

	this.renderContent = function(div){
		this.combo = 0;
		div.append("
"+this.contentForRender(div));

		if(this.combo>1){
			var divID = (div.attr("id")) + "_" + "combo";
			var canvasHTML = "
<canvas id='canvasCombo" + divID+"' width='" +canvasWidth + "' height="+canvasHeight/3 + "'>  </canvas>";
			div.append(canvasHTML);
			var canvasDiv = document.getElementById("canvasCombo"+ divID);
			this.drawCombo(canvasDiv, this.combo);
		}
	}

	this.makeAlive = function(d){
		//foundRareSession(div, "A player was corpse smooched alive.")
		d.dead = false;
		d.dreamSelf = false;
		d.isDreamSelf = true;
		d.murderMode = false;
		d.grimDark = false;
		d.triggerLevel = 1;
		d.leftMurderMode = false; //no scars
		d.victimBlood = null; //clean face
	}

	this.makeDead = function(d){
		d.dreamSelf = false;
		d.dead = true;
	}

	//smoocher on left, corpse on right, them waking up on prospit/derse on far right
	this.drawCorpseSmooch = function(canvas, dead_player, royalty, repeatTime){
		var pSpriteBuffer = getBufferCanvas(document.getElementById("sprite_template"));
		drawSprite(pSpriteBuffer,royalty)

		dead_player.dead = true;
		dead_player.isDreamSelf = false;  //temporarily show non dream version
		var dSpriteBuffer = getBufferCanvas(document.getElementById("sprite_template"));
		drawSprite(dSpriteBuffer,dead_player)

		copyTmpCanvasToRealCanvasAtPos(canvas, pSpriteBuffer,-100,0)
		copyTmpCanvasToRealCanvasAtPos(canvas, dSpriteBuffer,100,0)

		var moonBuffer = getBufferCanvas(document.getElementById("canvas_template"));
		drawMoon(moonBuffer, dead_player);
		this.makeAlive(dead_player);
		drawSprite(moonBuffer,dead_player)
		copyTmpCanvasToRealCanvasAtPos(canvas, moonBuffer,600,0)
		//this.makeAlive(dead_player); //make SURE the player is alive after smooches.

	}

	this.drawCombo = function(canvas,comboNum){
		drawComboText(canvas, comboNum);
	}

	this.ignoreEnemies = function(player, royalty){
		if(!royalty){
			return null;
		}
		var r = royalty.getRelationshipWith(player);
		if(!r || (r && r.value < 0)){
			return null;
		}
		return royalty;
	}

	this.getRoyalty = function(d){
		var royalty = d.getWhoLikesMeBestFromList(findLivingPlayers(this.session.availablePlayers));
		royalty = this.ignoreEnemies(d, royalty);
		if(!royalty){
			//okay, princes are traditional...
			royalty = findClassPlayer(findLivingPlayers(this.session.availablePlayers), "Prince");
			if(royalty && royalty.grimDark == true){
				royalty = null; //grim dark won't corpse smooch unless they actual want to.
			}
		}
		royalty = this.ignoreEnemies(d, royalty);
		if(!royalty){
			//okay, anybody free?
			royalty = getRandomElementFromArray(findLivingPlayers(this.session.availablePlayers));
			if(royalty && royalty.grimDark == true){
				royalty = null; //grim dark won't corpse smooch unless they actual want to.
			}
		}
		royalty = this.ignoreEnemies(d, royalty);
		//shit, maybe your best friend can drop what they are doing to save your ass?
		if(!royalty){
			royalty = d.getWhoLikesMeBestFromList(findLivingPlayers(this.playerList));
		}
		royalty = this.ignoreEnemies(d, royalty);
		//is ANYBODY even alive out there????
		if(!royalty){
			royalty = getRandomElementFromArray(findLivingPlayers(this.playerList));
			if(royalty && royalty.grimDark == true){
				royalty = null; //grim dark won't corpse smooch unless they actual want to.
			}
		}
		royalty = this.ignoreEnemies(d, royalty);
		return royalty;
	}

	this.renderForPlayer = function(div, deadPlayer){
		var royalty = this.getRoyalty(deadPlayer)
		if(royalty){
			var divID = (div.attr("id")) + "_" + deadPlayer.chatHandle;
			var canvasHTML = "
<canvas id='canvas" + divID+"' width='" +canvasWidth + "' height="+canvasHeight + "'>  </canvas>";
			div.append(canvasHTML);
			var canvasDiv = document.getElementById("canvas"+ divID);
			this.drawCorpseSmooch(canvasDiv, deadPlayer, royalty, 1000)
		}else{
			this.makeDead(deadPlayer); //dream self dies, too
		}

	}

	//don't actually bring themt o life yet, cause it gets rid of grimdark/murdermode etc.
	this.contentForRender = function(div){
		var ret = "";
		this.combo = 0;
		for(var i = 0; i<this.dreamersToRevive.length; i++){
			var d = this.dreamersToRevive[i];
			//have best friend mac on you.
			var royalty = this.getRoyalty(d);

			if(royalty){
				royalty.triggerLevel ++;
				ret += " The " + royalty.htmlTitle() + ", as a member of the royalty of " + royalty.moon + ", administers the universal remedy for the unawakened ";
				ret += " to the " + d.htmlTitle() + ". Their dream self takes over on " + d.moon + ". ";
				this.renderForPlayer(div, this.dreamersToRevive[i]);
				//this.makeAlive(d);
				this.combo ++;
			}else{
				this.addImportantEvent(d);
				ret += d.htmlTitle() + "'s corpse waits patiently for the kiss of life. But nobody came. ";
				ret += " Their dream self dies as well. ";
				this.makeDead(d);
			}
		}
		if(this.combo > 1){
			ret += this.combo +"X CORPSEMOOCH COMBO!!!";
		}
		//x times corpse smooch combo
		return ret;
	}

	this.addImportantEvent = function(player){
		var current_mvp =  findStrongestPlayer(this.session.players)
		if(player.godDestiny == false){//could god tier, but fate wn't let them
			this.session.addImportantEvent(new PlayerDiedButCouldGodTier(this.session, current_mvp.power,player) );
			this.session.addImportantEvent(new PlayerDiedForever(this.session, current_mvp.power,player) );
		}else{
			this.session.addImportantEvent(new PlayerDiedForever(this.session, current_mvp.power,player) );
		}
	}

	//prefer to be smooched by prince who doesn't hate you, or person who likes you best.
	this.content = function(){
		var ret = "";
		var combo = 0;
		for(var i = 0; i<this.dreamersToRevive.length; i++){
			var d = this.dreamersToRevive[i];
			//have best friend mac on you.
			var royalty = this.getRoyalty(d);

			if(royalty){
				royalty.triggerLevel ++;
				ret += " The " + royalty.htmlTitle() + ", as a member of the royalty of " + royalty.moon + ", administers the universal remedy for the unawakened ";
				ret += " to the " + d.htmlTitle() + ". Their dream self takes over on " + d.moon + ". ";
				this.makeAlive(d);
				combo ++;
			}else{
				ret += d.htmlTitle() + "'s corpse waits patiently for the kiss of life. But nobody came. ";
				ret += " Their dream self dies as well. ";
				this.makeDead(d);
			}
		}
		if(combo > 1){
			ret += combo +"X CORPSEMOOCH COMBO!!!";
		}
		//x times corpse smooch combo
		return ret;

	}

}
<commit_msg>working on yellow yard<commit_after>//x times corpse smooch combo.
function CorpseSmooch(session){
	this.session = session;
	this.canRepeat = true;
	this.playerList = [];  //what players are already in the medium when i trigger?
	this.dreamersToRevive = [];
	this.combo = 0;

	this.trigger = function(playerList){
		this.playerList = playerList;
		this.dreamersToRevive = [];
		//all dead players who aren't god tier and are destined to be god tier god tier now.
		var deadPlayers = findDeadPlayers(playerList);
		for(var i = 0; i<deadPlayers.length; i++){
			var p = deadPlayers[i];
			//only get one shot at this. if you're a jerk, no luck.
			if(p.dreamSelf){
				this.dreamersToRevive.push(p);
			}
		}
		//corspses can't smooch themselves.
		return this.dreamersToRevive.length > 0 && this.dreamersToRevive.length < playerList.length;

	}

	this.renderContent = function(div){
		this.combo = 0;
		div.append("
"+this.contentForRender(div));

		if(this.combo>1){
			var divID = (div.attr("id")) + "_" + "combo";
			var canvasHTML = "
<canvas id='canvasCombo" + divID+"' width='" +canvasWidth + "' height="+canvasHeight/3 + "'>  </canvas>";
			div.append(canvasHTML);
			var canvasDiv = document.getElementById("canvasCombo"+ divID);
			this.drawCombo(canvasDiv, this.combo);
		}
	}

	this.makeAlive = function(d){
		//foundRareSession(div, "A player was corpse smooched alive.")
		d.dead = false;
		d.dreamSelf = false;
		d.isDreamSelf = true;
		d.murderMode = false;
		d.grimDark = false;
		d.triggerLevel = 1;
		d.leftMurderMode = false; //no scars
		d.victimBlood = null; //clean face
	}

	this.makeDead = function(d){
		d.dreamSelf = false;
		d.dead = true;
	}

	//smoocher on left, corpse on right, them waking up on prospit/derse on far right
	this.drawCorpseSmooch = function(canvas, dead_player, royalty, repeatTime){
		var pSpriteBuffer = getBufferCanvas(document.getElementById("sprite_template"));
		drawSprite(pSpriteBuffer,royalty)

		dead_player.dead = true;
		dead_player.isDreamSelf = false;  //temporarily show non dream version
		var dSpriteBuffer = getBufferCanvas(document.getElementById("sprite_template"));
		drawSprite(dSpriteBuffer,dead_player)

		copyTmpCanvasToRealCanvasAtPos(canvas, pSpriteBuffer,-100,0)
		copyTmpCanvasToRealCanvasAtPos(canvas, dSpriteBuffer,100,0)

		var moonBuffer = getBufferCanvas(document.getElementById("canvas_template"));
		drawMoon(moonBuffer, dead_player);
		this.makeAlive(dead_player);
		drawSprite(moonBuffer,dead_player)
		copyTmpCanvasToRealCanvasAtPos(canvas, moonBuffer,600,0)
		//this.makeAlive(dead_player); //make SURE the player is alive after smooches.

	}

	this.drawCombo = function(canvas,comboNum){
		drawComboText(canvas, comboNum);
	}

	this.ignoreEnemies = function(player, royalty){
		if(!royalty){
			return null;
		}
		var r = royalty.getRelationshipWith(player);
		if(!r || (r && r.value < 0)){
			return null;
		}
		return royalty;
	}

	this.getRoyalty = function(d){
		var royalty = d.getWhoLikesMeBestFromList(findLivingPlayers(this.session.availablePlayers));
		royalty = this.ignoreEnemies(d, royalty);
		if(!royalty){
			//okay, princes are traditional...
			royalty = findClassPlayer(findLivingPlayers(this.session.availablePlayers), "Prince");
			if(royalty && royalty.grimDark == true){
				royalty = null; //grim dark won't corpse smooch unless they actual want to.
			}
		}
		royalty = this.ignoreEnemies(d, royalty);
		if(!royalty){
			//okay, anybody free?
			royalty = getRandomElementFromArray(findLivingPlayers(this.session.availablePlayers));
			if(royalty && royalty.grimDark == true){
				royalty = null; //grim dark won't corpse smooch unless they actual want to.
			}
		}
		royalty = this.ignoreEnemies(d, royalty);
		//shit, maybe your best friend can drop what they are doing to save your ass?
		if(!royalty){
			royalty = d.getWhoLikesMeBestFromList(findLivingPlayers(this.playerList));
		}
		royalty = this.ignoreEnemies(d, royalty);
		//is ANYBODY even alive out there????
		if(!royalty){
			royalty = getRandomElementFromArray(findLivingPlayers(this.playerList));
			if(royalty && royalty.grimDark == true){
				royalty = null; //grim dark won't corpse smooch unless they actual want to.
			}
		}
		royalty = this.ignoreEnemies(d, royalty);
		return royalty;
	}

	this.renderForPlayer = function(div, deadPlayer){
		var royalty = this.getRoyalty(deadPlayer)
		if(royalty){
			var divID = (div.attr("id")) + "_" + deadPlayer.chatHandle;
			var canvasHTML = "
<canvas id='canvas" + divID+"' width='" +canvasWidth + "' height="+canvasHeight + "'>  </canvas>";
			div.append(canvasHTML);
			var canvasDiv = document.getElementById("canvas"+ divID);
			this.drawCorpseSmooch(canvasDiv, deadPlayer, royalty, 1000)
		}else{
			this.makeDead(deadPlayer); //dream self dies, too
		}

	}

	//don't actually bring themt o life yet, cause it gets rid of grimdark/murdermode etc.
	this.contentForRender = function(div){
		var ret = "";
		this.combo = 0;
		for(var i = 0; i<this.dreamersToRevive.length; i++){
			var d = this.dreamersToRevive[i];
			//have best friend mac on you.
			var royalty = this.getRoyalty(d);

			if(royalty){
				royalty.triggerLevel ++;
				ret += " The " + royalty.htmlTitle() + ", as a member of the royalty of " + royalty.moon + ", administers the universal remedy for the unawakened ";
				ret += " to the " + d.htmlTitle() + ". Their dream self takes over on " + d.moon + ". ";
				this.renderForPlayer(div, this.dreamersToRevive[i]);
				//this.makeAlive(d);
				this.combo ++;
			}else{
				this.addImportantEvent(d);
				ret += d.htmlTitle() + "'s corpse waits patiently for the kiss of life. But nobody came. ";
				ret += " Their dream self dies as well. ";
				this.makeDead(d);
			}
		}
		if(this.combo > 1){
			ret += this.combo +"X CORPSEMOOCH COMBO!!!";
		}
		//x times corpse smooch combo
		return ret;
	}

	this.addImportantEvent = function(player){
		var current_mvp =  findStrongestPlayer(this.session.players)
		if(player.godDestiny == false){//could god tier, but fate wn't let them
			this.session.addImportantEvent(new PlayerDiedButCouldGodTier(this.session, current_mvp.power,player) );
			this.session.addImportantEvent(new PlayerDiedForever(this.session, current_mvp.power,player) );
		}else if(this.session.reckoningStarted == true) { //if the reckoning started, they couldn't god tier.
			this.session.addImportantEvent(new PlayerDiedForever(this.session, current_mvp.power,player) );
			this.session.addImportantEvent(new PlayerDiedButCouldGodTier(this.session, current_mvp.power,player) );
		}else{
				this.session.addImportantEvent(new PlayerDiedForever(this.session, current_mvp.power,player) );
		}
	}

	//prefer to be smooched by prince who doesn't hate you, or person who likes you best.
	this.content = function(){
		var ret = "";
		var combo = 0;
		for(var i = 0; i<this.dreamersToRevive.length; i++){
			var d = this.dreamersToRevive[i];
			//have best friend mac on you.
			var royalty = this.getRoyalty(d);

			if(royalty){
				royalty.triggerLevel ++;
				ret += " The " + royalty.htmlTitle() + ", as a member of the royalty of " + royalty.moon + ", administers the universal remedy for the unawakened ";
				ret += " to the " + d.htmlTitle() + ". Their dream self takes over on " + d.moon + ". ";
				this.makeAlive(d);
				combo ++;
			}else{
				ret += d.htmlTitle() + "'s corpse waits patiently for the kiss of life. But nobody came. ";
				ret += " Their dream self dies as well. ";
				this.makeDead(d);
			}
		}
		if(combo > 1){
			ret += combo +"X CORPSEMOOCH COMBO!!!";
		}
		//x times corpse smooch combo
		return ret;

	}

}
<|endoftext|>


<commit_before>import HandleRepConstants from 'vtk.js/Sources/Interaction/Widgets/HandleRepresentation/Constants';
import macro from 'vtk.js/Sources/macro';
import vtkAbstractWidget from 'vtk.js/Sources/Interaction/Widgets/AbstractWidget';
import vtkHandleWidget from 'vtk.js/Sources/Interaction/Widgets/HandleWidget';
import vtkLineRepresentation from 'vtk.js/Sources/Interaction/Widgets/LineRepresentation';
import { State } from 'vtk.js/Sources/Interaction/Widgets/LineRepresentation/Constants';
import Constants from './Constants';

const { WidgetState } = Constants;
const { InteractionState } = HandleRepConstants;

// ----------------------------------------------------------------------------
// vtkHandleWidget methods
// ----------------------------------------------------------------------------

function vtkLineWidget(publicAPI, model) {
  // Set our className
  model.classHierarchy.push('vtkLineWidget');

  const superClass = Object.assign({}, publicAPI);

  function setCursor(state) {
    switch (state) {
      case State.OUTSIDE: {
        model.interactor.getView().setCursor('default');
        break;
      }
      default: {
        model.interactor.getView().setCursor('pointer');
      }
    }
  }

  publicAPI.setEnabled = (enabling) => {
    superClass.setEnabled(enabling);

    if (!model.widgetRep) {
      return;
    }
    // Use the representations from the line widget
    // for the point widgets to avoid creating
    // default representations when setting the
    // interactor below
    model.point1Widget.setWidgetRep(model.widgetRep.getPoint1Representation());
    model.point2Widget.setWidgetRep(model.widgetRep.getPoint2Representation());
    model.point1Widget.setInteractor(model.interactor);
    model.point2Widget.setInteractor(model.interactor);

    if (model.widgetState === WidgetState.START) {
      model.point1Widget.setEnabled(0);
      model.point2Widget.setEnabled(0);
      model.widgetRep.setLineVisibility(0);
      model.widgetRep.setPoint1Visibility(1);
      model.widgetRep.setPoint2Visibility(0);
    } else {
      model.point1Widget.setEnabled(enabling);
      model.point2Widget.setEnabled(enabling);
      model.widgetRep.setLineVisibility(1);
      model.widgetRep.setPoint1Visibility(1);
      model.widgetRep.setPoint2Visibility(1);
    }
  };

  publicAPI.setWidgetStateToStart = () => {
    model.widgetState = WidgetState.START;
    model.currentHandle = 0;
    publicAPI.setEnabled(model.enabled);
  };

  publicAPI.setWidgetStateToManipulate = () => {
    model.widgetState = WidgetState.MANIPULATE;
    model.currentHandle = -1;
    publicAPI.setEnabled(model.enabled);
  };

  publicAPI.handleMouseMove = (callData) => publicAPI.moveAction(callData);

  publicAPI.handleLeftButtonPress = (callData) =>
    publicAPI.selectAction(callData);

  publicAPI.handleLeftButtonRelease = (callData) =>
    publicAPI.endSelectAction(callData);

  publicAPI.handleMiddleButtonPress = (callData) =>
    publicAPI.translateAction(callData);

  publicAPI.handleMiddleButtonRelease = (callData) =>
    publicAPI.endSelectAction(callData);

  publicAPI.handleRightButtonPress = (callData) =>
    publicAPI.scaleAction(callData);

  publicAPI.handleRightButtonRelease = (callData) =>
    publicAPI.endSelectAction(callData);

  publicAPI.selectAction = (callData) => {
    const position = [callData.position.x, callData.position.y];

    if (model.widgetState === WidgetState.START) {
      const pos3D = model.point1Widget
        .getWidgetRep()
        .displayToWorld(position, 0);
      // The first time we click, the method is called twice
      if (model.currentHandle < 1) {
        model.widgetRep.setLineVisibility(1);
        model.widgetRep.setPoint1WorldPosition(pos3D);
        // Trick to avoid a line with a zero length
        // If the line has a zero length, it appears with bad extremities
        pos3D[0] += 0.000000001;
        model.widgetRep.setPoint2WorldPosition(pos3D);
        model.currentHandle++;
      } else {
        model.widgetRep.setPoint2Visibility(1);
        model.widgetRep.setPoint2WorldPosition(pos3D);
        // When two points are placed, we go back to the native
        model.widgetState = WidgetState.MANIPULATE;
        model.currentHandle = -1;
      }
    } else {
      const state = model.widgetRep.computeInteractionState(position);
      if (state === InteractionState.OUTSIDE) {
        return;
      }
      model.widgetState = WidgetState.ACTIVE;
      publicAPI.invokeStartInteractionEvent();
    }

    model.widgetRep.startComplexWidgetInteraction(position);

    publicAPI.render();
  };

  publicAPI.translateAction = (callData) => {
    const position = [callData.position.x, callData.position.y];
    const state = model.widgetRep.computeInteractionState(position);
    if (state === InteractionState.OUTSIDE) {
      return;
    }

    model.widgetState = WidgetState.ACTIVE;
    model.widgetRep.startComplexWidgetInteraction(position);
    publicAPI.invokeStartInteractionEvent();
  };

  publicAPI.scaleAction = (callData) => {
    const position = [callData.position.x, callData.position.y];
    const state = model.widgetRep.computeInteractionState(position);
    if (state === InteractionState.OUTSIDE) {
      return;
    }

    model.widgetState = WidgetState.ACTIVE;
    model.widgetRep.startComplexWidgetInteraction(position);
    publicAPI.invokeStartInteractionEvent();
  };

  publicAPI.moveAction = (callData) => {
    const position = [callData.position.x, callData.position.y];
    let modified = false;

    if (model.widgetState === WidgetState.MANIPULATE) {
      // In MANIPULATE, we are hovering above the widget
      // Check if above a sphere and enable/disable if needed
      const state = model.widgetRep.computeInteractionState(position);
      setCursor(state);

      const enablePoint1Widget = state === State.ONP1;
      const enablePoint2Widget = state === State.ONP2;

      if (enablePoint1Widget !== model.point1Widget.getEnabled()) {
        model.point1Widget.setEnabled(enablePoint1Widget);
        modified = true;
      }
      if (enablePoint2Widget !== model.point2Widget.getEnabled()) {
        model.point2Widget.setEnabled(enablePoint2Widget);
        modified = true;
      }
    } else if (model.widgetState === WidgetState.START) {
      // In START, we are placing the sphere widgets.
      // Move current handle along the mouse position.
      model.widgetRep.complexWidgetInteraction(position);
      const pos3D = model.point1Widget
        .getWidgetRep()
        .displayToWorld(position, 0);
      if (model.currentHandle === 0) {
        model.widgetRep.setPoint1WorldPosition(pos3D);
      } else {
        model.widgetRep.setPoint2WorldPosition(pos3D);
      }
      modified = true;
    } else if (model.widgetState === WidgetState.ACTIVE) {
      // In ACTIVE, we are moving a sphere widget.
      // Update the line extremities to follow the spheres.
      model.widgetRep.setPoint1WorldPosition(
        model.point1Widget.getWidgetRep().getWorldPosition()
      );
      model.widgetRep.setPoint2WorldPosition(
        model.point2Widget.getWidgetRep().getWorldPosition()
      );
      modified = true;
    }

    if (modified) {
      publicAPI.invokeInteractionEvent();
      publicAPI.render();
    }
  };

  publicAPI.endSelectAction = (callData) => {
    if (model.widgetState === WidgetState.START) {
      return;
    }
    const position = [callData.position.x, callData.position.y];
    model.widgetRep.complexWidgetInteraction(position);
    model.widgetRep.setPoint1WorldPosition(
      model.point1Widget.getWidgetRep().getWorldPosition()
    );
    model.widgetRep.setPoint2WorldPosition(
      model.point2Widget.getWidgetRep().getWorldPosition()
    );

    model.widgetState = WidgetState.MANIPULATE;
    publicAPI.invokeEndInteractionEvent();
    publicAPI.render();
  };

  publicAPI.createDefaultRepresentation = () => {
    if (!model.widgetRep) {
      model.widgetRep = vtkLineRepresentation.newInstance();
    }
  };
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
  widgetState: WidgetState.START,
  managesCursor: 1,
  currentHandle: -1,
  point1Widget: null,
  point2Widget: null,
};

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
  Object.assign(model, DEFAULT_VALUES, initialValues);

  // Inheritance
  vtkAbstractWidget.extend(publicAPI, model, initialValues);

  model.point1Widget = vtkHandleWidget.newInstance();
  model.point1Widget.setParent(publicAPI);
  model.point1Widget.createDefaultRepresentation();

  model.point2Widget = vtkHandleWidget.newInstance();
  model.point2Widget.setParent(publicAPI);
  model.point2Widget.createDefaultRepresentation();

  // Object methods
  vtkLineWidget(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(extend, 'vtkLineWidget');

// ----------------------------------------------------------------------------

export default { newInstance, extend };
<commit_msg>fix(LineWidget): Fix default value<commit_after>import HandleRepConstants from 'vtk.js/Sources/Interaction/Widgets/HandleRepresentation/Constants';
import macro from 'vtk.js/Sources/macro';
import vtkAbstractWidget from 'vtk.js/Sources/Interaction/Widgets/AbstractWidget';
import vtkHandleWidget from 'vtk.js/Sources/Interaction/Widgets/HandleWidget';
import vtkLineRepresentation from 'vtk.js/Sources/Interaction/Widgets/LineRepresentation';
import { State } from 'vtk.js/Sources/Interaction/Widgets/LineRepresentation/Constants';
import Constants from './Constants';

const { WidgetState } = Constants;
const { InteractionState } = HandleRepConstants;

// ----------------------------------------------------------------------------
// vtkHandleWidget methods
// ----------------------------------------------------------------------------

function vtkLineWidget(publicAPI, model) {
  // Set our className
  model.classHierarchy.push('vtkLineWidget');

  const superClass = Object.assign({}, publicAPI);

  function setCursor(state) {
    switch (state) {
      case State.OUTSIDE: {
        model.interactor.getView().setCursor('default');
        break;
      }
      default: {
        model.interactor.getView().setCursor('pointer');
      }
    }
  }

  publicAPI.setEnabled = (enabling) => {
    superClass.setEnabled(enabling);

    if (!model.widgetRep) {
      return;
    }
    // Use the representations from the line widget
    // for the point widgets to avoid creating
    // default representations when setting the
    // interactor below
    model.point1Widget.setWidgetRep(model.widgetRep.getPoint1Representation());
    model.point2Widget.setWidgetRep(model.widgetRep.getPoint2Representation());
    model.point1Widget.setInteractor(model.interactor);
    model.point2Widget.setInteractor(model.interactor);

    if (model.widgetState === WidgetState.START) {
      model.point1Widget.setEnabled(0);
      model.point2Widget.setEnabled(0);
      model.widgetRep.setLineVisibility(0);
      model.widgetRep.setPoint1Visibility(1);
      model.widgetRep.setPoint2Visibility(0);
    } else {
      model.point1Widget.setEnabled(enabling);
      model.point2Widget.setEnabled(enabling);
      model.widgetRep.setLineVisibility(1);
      model.widgetRep.setPoint1Visibility(1);
      model.widgetRep.setPoint2Visibility(1);
    }
  };

  publicAPI.setWidgetStateToStart = () => {
    model.widgetState = WidgetState.START;
    model.currentHandle = 0;
    publicAPI.setEnabled(model.enabled);
  };

  publicAPI.setWidgetStateToManipulate = () => {
    model.widgetState = WidgetState.MANIPULATE;
    model.currentHandle = -1;
    publicAPI.setEnabled(model.enabled);
  };

  publicAPI.handleMouseMove = (callData) => publicAPI.moveAction(callData);

  publicAPI.handleLeftButtonPress = (callData) =>
    publicAPI.selectAction(callData);

  publicAPI.handleLeftButtonRelease = (callData) =>
    publicAPI.endSelectAction(callData);

  publicAPI.handleMiddleButtonPress = (callData) =>
    publicAPI.translateAction(callData);

  publicAPI.handleMiddleButtonRelease = (callData) =>
    publicAPI.endSelectAction(callData);

  publicAPI.handleRightButtonPress = (callData) =>
    publicAPI.scaleAction(callData);

  publicAPI.handleRightButtonRelease = (callData) =>
    publicAPI.endSelectAction(callData);

  publicAPI.selectAction = (callData) => {
    const position = [callData.position.x, callData.position.y];

    if (model.widgetState === WidgetState.START) {
      const pos3D = model.point1Widget
        .getWidgetRep()
        .displayToWorld(position, 0);
      // The first time we click, the method is called twice
      if (model.currentHandle < 1) {
        model.widgetRep.setLineVisibility(1);
        model.widgetRep.setPoint1WorldPosition(pos3D);
        // Trick to avoid a line with a zero length
        // If the line has a zero length, it appears with bad extremities
        pos3D[0] += 0.000000001;
        model.widgetRep.setPoint2WorldPosition(pos3D);
        model.currentHandle++;
      } else {
        model.widgetRep.setPoint2Visibility(1);
        model.widgetRep.setPoint2WorldPosition(pos3D);
        // When two points are placed, we go back to the native
        model.widgetState = WidgetState.MANIPULATE;
        model.currentHandle = -1;
      }
    } else {
      const state = model.widgetRep.computeInteractionState(position);
      if (state === InteractionState.OUTSIDE) {
        return;
      }
      model.widgetState = WidgetState.ACTIVE;
      publicAPI.invokeStartInteractionEvent();
    }

    model.widgetRep.startComplexWidgetInteraction(position);

    publicAPI.render();
  };

  publicAPI.translateAction = (callData) => {
    const position = [callData.position.x, callData.position.y];
    const state = model.widgetRep.computeInteractionState(position);
    if (state === InteractionState.OUTSIDE) {
      return;
    }

    model.widgetState = WidgetState.ACTIVE;
    model.widgetRep.startComplexWidgetInteraction(position);
    publicAPI.invokeStartInteractionEvent();
  };

  publicAPI.scaleAction = (callData) => {
    const position = [callData.position.x, callData.position.y];
    const state = model.widgetRep.computeInteractionState(position);
    if (state === InteractionState.OUTSIDE) {
      return;
    }

    model.widgetState = WidgetState.ACTIVE;
    model.widgetRep.startComplexWidgetInteraction(position);
    publicAPI.invokeStartInteractionEvent();
  };

  publicAPI.moveAction = (callData) => {
    const position = [callData.position.x, callData.position.y];
    let modified = false;

    if (model.widgetState === WidgetState.MANIPULATE) {
      // In MANIPULATE, we are hovering above the widget
      // Check if above a sphere and enable/disable if needed
      const state = model.widgetRep.computeInteractionState(position);
      setCursor(state);

      const enablePoint1Widget = state === State.ONP1;
      const enablePoint2Widget = state === State.ONP2;

      if (enablePoint1Widget !== model.point1Widget.getEnabled()) {
        model.point1Widget.setEnabled(enablePoint1Widget);
        modified = true;
      }
      if (enablePoint2Widget !== model.point2Widget.getEnabled()) {
        model.point2Widget.setEnabled(enablePoint2Widget);
        modified = true;
      }
    } else if (model.widgetState === WidgetState.START) {
      // In START, we are placing the sphere widgets.
      // Move current handle along the mouse position.
      model.widgetRep.complexWidgetInteraction(position);
      const pos3D = model.point1Widget
        .getWidgetRep()
        .displayToWorld(position, 0);
      if (model.currentHandle === 0) {
        model.widgetRep.setPoint1WorldPosition(pos3D);
      } else {
        model.widgetRep.setPoint2WorldPosition(pos3D);
      }
      modified = true;
    } else if (model.widgetState === WidgetState.ACTIVE) {
      // In ACTIVE, we are moving a sphere widget.
      // Update the line extremities to follow the spheres.
      model.widgetRep.setPoint1WorldPosition(
        model.point1Widget.getWidgetRep().getWorldPosition()
      );
      model.widgetRep.setPoint2WorldPosition(
        model.point2Widget.getWidgetRep().getWorldPosition()
      );
      modified = true;
    }

    if (modified) {
      publicAPI.invokeInteractionEvent();
      publicAPI.render();
    }
  };

  publicAPI.endSelectAction = (callData) => {
    if (model.widgetState === WidgetState.START) {
      return;
    }
    const position = [callData.position.x, callData.position.y];
    model.widgetRep.complexWidgetInteraction(position);
    model.widgetRep.setPoint1WorldPosition(
      model.point1Widget.getWidgetRep().getWorldPosition()
    );
    model.widgetRep.setPoint2WorldPosition(
      model.point2Widget.getWidgetRep().getWorldPosition()
    );

    model.widgetState = WidgetState.MANIPULATE;
    publicAPI.invokeEndInteractionEvent();
    publicAPI.render();
  };

  publicAPI.createDefaultRepresentation = () => {
    if (!model.widgetRep) {
      model.widgetRep = vtkLineRepresentation.newInstance();
    }
  };
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
  widgetState: WidgetState.START,
  managesCursor: 1,
  currentHandle: 0,
  point1Widget: null,
  point2Widget: null,
};

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
  Object.assign(model, DEFAULT_VALUES, initialValues);

  // Inheritance
  vtkAbstractWidget.extend(publicAPI, model, initialValues);

  model.point1Widget = vtkHandleWidget.newInstance();
  model.point1Widget.setParent(publicAPI);
  model.point1Widget.createDefaultRepresentation();

  model.point2Widget = vtkHandleWidget.newInstance();
  model.point2Widget.setParent(publicAPI);
  model.point2Widget.createDefaultRepresentation();

  // Object methods
  vtkLineWidget(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(extend, 'vtkLineWidget');

// ----------------------------------------------------------------------------

export default { newInstance, extend };
<|endoftext|>