mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-30 19:02:27 +00:00 
			
		
		
		
	Updated version of scriptaculous library
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@117 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
		| @@ -1,15 +1,16 @@ | ||||
| .grid { | ||||
| 	background: #fff; | ||||
| 	border: 1px solid #eee; | ||||
| 	/* width: <?php echo $this->boxWidth ?>px; */ | ||||
| 	text-align: center; | ||||
| 	height: 400px; | ||||
| 	padding: 2px 2px 2px 2px; | ||||
| 	margin: 2px 40px 2px 2px; | ||||
| 	 | ||||
|  | ||||
| } | ||||
|  | ||||
| .offLineNode { | ||||
| 	background: #aaa;	 | ||||
| 	background: #aaa; | ||||
| 	color: #444; | ||||
| 	width: 80px; | ||||
| 	height: 20px; | ||||
| @@ -22,7 +23,7 @@ | ||||
| } | ||||
|  | ||||
| .pingableNode { | ||||
| 	background: #66CC99;	 | ||||
| 	background: #66CC99; | ||||
| 	color: #444; | ||||
| 	width: 80px; | ||||
| 	height: 20px; | ||||
| @@ -91,9 +92,9 @@ | ||||
| 	position: relative; | ||||
| 	left: 0px; | ||||
| 	top: 100px; | ||||
| 	 | ||||
| 	 | ||||
| }  | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| #boxNavPrev { | ||||
| 	position: absolute; | ||||
|   | ||||
| @@ -1,85 +0,0 @@ | ||||
| .grid { | ||||
| 	background: #fff; | ||||
| 	border: 1px solid #eee; | ||||
| 	width: <?php echo $this->boxWidth ?>px; | ||||
| 	text-align: center; | ||||
| 	height: 400px; | ||||
| 	padding: 2px 2px 2px 2px; | ||||
| 	margin: 2px 40px 2px 2px; | ||||
| 	 | ||||
| } | ||||
|  | ||||
| .offLineNode { | ||||
| 	background: #aaa;	 | ||||
| 	color: #444; | ||||
| 	width: 80px; | ||||
| 	height: 20px; | ||||
| 	margin: 2px; | ||||
| 	font-family: arial; | ||||
| 	font-size: 10px; | ||||
| 	text-align: center; | ||||
| 	overflow: hidden; | ||||
| 	float: left; | ||||
| } | ||||
|  | ||||
| .pingableNode { | ||||
| 	background: #66CC99;	 | ||||
| 	color: #444; | ||||
| 	width: 80px; | ||||
| 	height: 20px; | ||||
| 	margin: 2px; | ||||
| 	font-family: arial; | ||||
| 	font-size: 10px; | ||||
| 	text-align: center; | ||||
| 	overflow: hidden; | ||||
| 	float: left; | ||||
| } | ||||
|  | ||||
| .legendBox { | ||||
| 	padding: 2px 2px 2px 2px; | ||||
| 	margin-left: 10px; | ||||
| 	margin-top: 5px; | ||||
| 	margin-bottom: 10px; | ||||
| 	border: 2px solid #eee; | ||||
| 	position: relative; | ||||
| 	width: 800px; | ||||
| 	text-align: center; | ||||
| 	float: left; | ||||
|  | ||||
| } | ||||
| .mHead { | ||||
|  | ||||
| 	font-family: arial; | ||||
|  | ||||
| } | ||||
| .subBox { | ||||
| 	border: 1px solid #eee; | ||||
| 	margin-left: 20px; | ||||
| 	margin-right: 20px; | ||||
| 	width: 100px; | ||||
| 	height: 20px; | ||||
| } | ||||
|  | ||||
| .legendDescription { | ||||
| 	font-size: 10px; | ||||
| 	font-family: arial; | ||||
| 	color: #999; | ||||
| } | ||||
| .unknown { | ||||
| 	background: #aaa; | ||||
| 	height: 20px; | ||||
| 	width: 40px; | ||||
| } | ||||
| .pingable { | ||||
| 	background: #66CC99; | ||||
| 	height: 20px; | ||||
| 	width: 40px; | ||||
| } | ||||
|  | ||||
| .online { | ||||
| 	background: #6699CC; | ||||
| 	height: 20px; | ||||
| 	width: 40px; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -1,4 +1,4 @@ | ||||
| // script.aculo.us builder.js v1.7.1_beta3, Fri May 25 17:19:41 +0200 2007 | ||||
| // script.aculo.us builder.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007 | ||||
|  | ||||
| // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) | ||||
| // | ||||
|   | ||||
							
								
								
									
										860
									
								
								xCAT-web/js/controls.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										860
									
								
								xCAT-web/js/controls.js
									
									
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| // script.aculo.us controls.js v1.7.1_beta3, Fri May 25 17:19:41 +0200 2007 | ||||
| // script.aculo.us controls.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007 | ||||
|  | ||||
| // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) | ||||
| //           (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan) | ||||
| @@ -39,9 +39,8 @@ | ||||
| if(typeof Effect == 'undefined') | ||||
|   throw("controls.js requires including script.aculo.us' effects.js library"); | ||||
|  | ||||
| var Autocompleter = {} | ||||
| Autocompleter.Base = function() {}; | ||||
| Autocompleter.Base.prototype = { | ||||
| var Autocompleter = { } | ||||
| Autocompleter.Base = Class.create({ | ||||
|   baseInitialize: function(element, update, options) { | ||||
|     element          = $(element) | ||||
|     this.element     = element;  | ||||
| @@ -51,11 +50,12 @@ Autocompleter.Base.prototype = { | ||||
|     this.active      = false;  | ||||
|     this.index       = 0;      | ||||
|     this.entryCount  = 0; | ||||
|     this.oldElementValue = this.element.value; | ||||
|  | ||||
|     if(this.setOptions) | ||||
|       this.setOptions(options); | ||||
|     else | ||||
|       this.options = options || {}; | ||||
|       this.options = options || { }; | ||||
|  | ||||
|     this.options.paramName    = this.options.paramName || this.element.name; | ||||
|     this.options.tokens       = this.options.tokens || []; | ||||
| @@ -77,6 +77,9 @@ Autocompleter.Base.prototype = { | ||||
|  | ||||
|     if(typeof(this.options.tokens) == 'string')  | ||||
|       this.options.tokens = new Array(this.options.tokens); | ||||
|     // Force carriage returns as token delimiters anyway | ||||
|     if (!this.options.tokens.include('\n')) | ||||
|       this.options.tokens.push('\n'); | ||||
|  | ||||
|     this.observer = null; | ||||
|      | ||||
| @@ -86,12 +89,6 @@ Autocompleter.Base.prototype = { | ||||
|  | ||||
|     Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this)); | ||||
|     Event.observe(this.element, 'keypress', this.onKeyPress.bindAsEventListener(this)); | ||||
|  | ||||
|     // Turn autocomplete back on when the user leaves the page, so that the | ||||
|     // field's value will be remembered on Mozilla-based browsers. | ||||
|     Event.observe(window, 'beforeunload', function(){  | ||||
|       element.setAttribute('autocomplete', 'on');  | ||||
|     }); | ||||
|   }, | ||||
|  | ||||
|   show: function() { | ||||
| @@ -245,21 +242,22 @@ Autocompleter.Base.prototype = { | ||||
|     } | ||||
|     var value = ''; | ||||
|     if (this.options.select) { | ||||
|       var nodes = document.getElementsByClassName(this.options.select, selectedElement) || []; | ||||
|       var nodes = $(selectedElement).select('.' + this.options.select) || []; | ||||
|       if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select); | ||||
|     } else | ||||
|       value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); | ||||
|      | ||||
|     var lastTokenPos = this.findLastToken(); | ||||
|     if (lastTokenPos != -1) { | ||||
|       var newValue = this.element.value.substr(0, lastTokenPos + 1); | ||||
|       var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/); | ||||
|     var bounds = this.getTokenBounds(); | ||||
|     if (bounds[0] != -1) { | ||||
|       var newValue = this.element.value.substr(0, bounds[0]); | ||||
|       var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/); | ||||
|       if (whitespace) | ||||
|         newValue += whitespace[0]; | ||||
|       this.element.value = newValue + value; | ||||
|       this.element.value = newValue + value + this.element.value.substr(bounds[1]); | ||||
|     } else { | ||||
|       this.element.value = value; | ||||
|     } | ||||
|     this.oldElementValue = this.element.value; | ||||
|     this.element.focus(); | ||||
|      | ||||
|     if (this.options.afterUpdateElement) | ||||
| @@ -303,38 +301,48 @@ Autocompleter.Base.prototype = { | ||||
|  | ||||
|   onObserverEvent: function() { | ||||
|     this.changed = false;    | ||||
|     this.tokenBounds = null; | ||||
|     if(this.getToken().length>=this.options.minChars) { | ||||
|       this.getUpdatedChoices(); | ||||
|     } else { | ||||
|       this.active = false; | ||||
|       this.hide(); | ||||
|     } | ||||
|     this.oldElementValue = this.element.value; | ||||
|   }, | ||||
|  | ||||
|   getToken: function() { | ||||
|     var tokenPos = this.findLastToken(); | ||||
|     if (tokenPos != -1) | ||||
|       var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,''); | ||||
|     else | ||||
|       var ret = this.element.value; | ||||
|  | ||||
|     return /\n/.test(ret) ? '' : ret; | ||||
|     var bounds = this.getTokenBounds(); | ||||
|     return this.element.value.substring(bounds[0], bounds[1]).strip(); | ||||
|   }, | ||||
|  | ||||
|   findLastToken: function() { | ||||
|     var lastTokenPos = -1; | ||||
|  | ||||
|     for (var i=0; i<this.options.tokens.length; i++) { | ||||
|       var thisTokenPos = this.element.value.lastIndexOf(this.options.tokens[i]); | ||||
|       if (thisTokenPos > lastTokenPos) | ||||
|         lastTokenPos = thisTokenPos; | ||||
|   getTokenBounds: function() { | ||||
|     if (null != this.tokenBounds) return this.tokenBounds; | ||||
|     var value = this.element.value; | ||||
|     if (value.strip().empty()) return [-1, 0]; | ||||
|     var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue); | ||||
|     var offset = (diff == this.oldElementValue.length ? 1 : 0); | ||||
|     var prevTokenPos = -1, nextTokenPos = value.length; | ||||
|     var tp; | ||||
|     for (var index = 0, l = this.options.tokens.length; index < l; ++index) { | ||||
|       tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1); | ||||
|       if (tp > prevTokenPos) prevTokenPos = tp; | ||||
|       tp = value.indexOf(this.options.tokens[index], diff + offset); | ||||
|       if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp; | ||||
|     } | ||||
|     return lastTokenPos; | ||||
|     return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]); | ||||
|   } | ||||
| } | ||||
| }); | ||||
|  | ||||
| Ajax.Autocompleter = Class.create(); | ||||
| Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), { | ||||
| Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) { | ||||
|   var boundary = Math.min(newS.length, oldS.length); | ||||
|   for (var index = 0; index < boundary; ++index) | ||||
|     if (newS[index] != oldS[index]) | ||||
|       return index; | ||||
|   return boundary; | ||||
| }; | ||||
|  | ||||
| Ajax.Autocompleter = Class.create(Autocompleter.Base, { | ||||
|   initialize: function(element, update, url, options) { | ||||
|     this.baseInitialize(element, update, options); | ||||
|     this.options.asynchronous  = true; | ||||
| @@ -361,7 +369,6 @@ Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.pro | ||||
|   onComplete: function(request) { | ||||
|     this.updateChoices(request.responseText); | ||||
|   } | ||||
|  | ||||
| }); | ||||
|  | ||||
| // The local array autocompleter. Used when you'd prefer to | ||||
| @@ -399,8 +406,7 @@ Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.pro | ||||
| // In that case, the other options above will not apply unless | ||||
| // you support them. | ||||
|  | ||||
| Autocompleter.Local = Class.create(); | ||||
| Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), { | ||||
| Autocompleter.Local = Class.create(Autocompleter.Base, { | ||||
|   initialize: function(element, update, array, options) { | ||||
|     this.baseInitialize(element, update, options); | ||||
|     this.options.array = array; | ||||
| @@ -456,13 +462,12 @@ Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), { | ||||
|           ret = ret.concat(partial.slice(0, instance.options.choices - ret.length)) | ||||
|         return "<ul>" + ret.join('') + "</ul>"; | ||||
|       } | ||||
|     }, options || {}); | ||||
|     }, options || { }); | ||||
|   } | ||||
| }); | ||||
|  | ||||
| // AJAX in-place editor | ||||
| // | ||||
| // see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor | ||||
| // AJAX in-place editor and collection editor | ||||
| // Full rewrite by Christophe Porteneuve <tdd@tddsworld.com> (April 2007). | ||||
|  | ||||
| // Use this if you notice weird scrolling problems on some browsers, | ||||
| // the DOM might be a bit confused when this gets called so do this | ||||
| @@ -473,387 +478,472 @@ Field.scrollFreeActivate = function(field) { | ||||
|   }, 1); | ||||
| } | ||||
|  | ||||
| Ajax.InPlaceEditor = Class.create(); | ||||
| Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99"; | ||||
| Ajax.InPlaceEditor.prototype = { | ||||
| Ajax.InPlaceEditor = Class.create({ | ||||
|   initialize: function(element, url, options) { | ||||
|     this.url = url; | ||||
|     this.element = $(element); | ||||
|  | ||||
|     this.options = Object.extend({ | ||||
|       paramName: "value", | ||||
|       okButton: true, | ||||
|       okLink: false, | ||||
|       okText: "ok", | ||||
|       cancelButton: false, | ||||
|       cancelLink: true, | ||||
|       cancelText: "cancel", | ||||
|       textBeforeControls: '', | ||||
|       textBetweenControls: '', | ||||
|       textAfterControls: '', | ||||
|       savingText: "Saving...", | ||||
|       clickToEditText: "Click to edit", | ||||
|       okText: "ok", | ||||
|       rows: 1, | ||||
|       onComplete: function(transport, element) { | ||||
|         new Effect.Highlight(element, {startcolor: this.options.highlightcolor}); | ||||
|       }, | ||||
|       onFailure: function(transport) { | ||||
|         alert("Error communicating with the server: " + transport.responseText.stripTags()); | ||||
|       }, | ||||
|       callback: function(form) { | ||||
|         return Form.serialize(form); | ||||
|       }, | ||||
|       handleLineBreaks: true, | ||||
|       loadingText: 'Loading...', | ||||
|       savingClassName: 'inplaceeditor-saving', | ||||
|       loadingClassName: 'inplaceeditor-loading', | ||||
|       formClassName: 'inplaceeditor-form', | ||||
|       highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor, | ||||
|       highlightendcolor: "#FFFFFF", | ||||
|       externalControl: null, | ||||
|       submitOnBlur: false, | ||||
|       ajaxOptions: {}, | ||||
|       evalScripts: false | ||||
|     }, options || {}); | ||||
|  | ||||
|     if(!this.options.formId && this.element.id) { | ||||
|       this.options.formId = this.element.id + "-inplaceeditor"; | ||||
|       if ($(this.options.formId)) { | ||||
|         // there's already a form with that name, don't specify an id | ||||
|         this.options.formId = null; | ||||
|       } | ||||
|     this.element = element = $(element); | ||||
|     this.prepareOptions(); | ||||
|     this._controls = { }; | ||||
|     arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!! | ||||
|     Object.extend(this.options, options || { }); | ||||
|     if (!this.options.formId && this.element.id) { | ||||
|       this.options.formId = this.element.id + '-inplaceeditor'; | ||||
|       if ($(this.options.formId)) | ||||
|         this.options.formId = ''; | ||||
|     } | ||||
|      | ||||
|     if (this.options.externalControl) { | ||||
|     if (this.options.externalControl) | ||||
|       this.options.externalControl = $(this.options.externalControl); | ||||
|     } | ||||
|      | ||||
|     this.originalBackground = Element.getStyle(this.element, 'background-color'); | ||||
|     if (!this.originalBackground) { | ||||
|       this.originalBackground = "transparent"; | ||||
|     } | ||||
|      | ||||
|     if (!this.options.externalControl) | ||||
|       this.options.externalControlOnly = false; | ||||
|     this._originalBackground = this.element.getStyle('background-color') || 'transparent'; | ||||
|     this.element.title = this.options.clickToEditText; | ||||
|      | ||||
|     this.onclickListener = this.enterEditMode.bindAsEventListener(this); | ||||
|     this.mouseoverListener = this.enterHover.bindAsEventListener(this); | ||||
|     this.mouseoutListener = this.leaveHover.bindAsEventListener(this); | ||||
|     Event.observe(this.element, 'click', this.onclickListener); | ||||
|     Event.observe(this.element, 'mouseover', this.mouseoverListener); | ||||
|     Event.observe(this.element, 'mouseout', this.mouseoutListener); | ||||
|     if (this.options.externalControl) { | ||||
|       Event.observe(this.options.externalControl, 'click', this.onclickListener); | ||||
|       Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener); | ||||
|       Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener); | ||||
|     } | ||||
|     this._boundCancelHandler = this.handleFormCancellation.bind(this); | ||||
|     this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this); | ||||
|     this._boundFailureHandler = this.handleAJAXFailure.bind(this); | ||||
|     this._boundSubmitHandler = this.handleFormSubmission.bind(this); | ||||
|     this._boundWrapperHandler = this.wrapUp.bind(this); | ||||
|     this.registerListeners(); | ||||
|   }, | ||||
|   enterEditMode: function(evt) { | ||||
|     if (this.saving) return; | ||||
|     if (this.editing) return; | ||||
|     this.editing = true; | ||||
|     this.onEnterEditMode(); | ||||
|     if (this.options.externalControl) { | ||||
|       Element.hide(this.options.externalControl); | ||||
|     } | ||||
|     Element.hide(this.element); | ||||
|     this.createForm(); | ||||
|     this.element.parentNode.insertBefore(this.form, this.element); | ||||
|     if (!this.options.loadTextURL) Field.scrollFreeActivate(this.editField); | ||||
|     // stop the event to avoid a page refresh in Safari | ||||
|     if (evt) { | ||||
|       Event.stop(evt); | ||||
|     } | ||||
|     return false; | ||||
|   checkForEscapeOrReturn: function(e) { | ||||
|     if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return; | ||||
|     if (Event.KEY_ESC == e.keyCode) | ||||
|       this.handleFormCancellation(e); | ||||
|     else if (Event.KEY_RETURN == e.keyCode) | ||||
|       this.handleFormSubmission(e); | ||||
|   }, | ||||
|   createForm: function() { | ||||
|     this.form = document.createElement("form"); | ||||
|     this.form.id = this.options.formId; | ||||
|     Element.addClassName(this.form, this.options.formClassName) | ||||
|     this.form.onsubmit = this.onSubmit.bind(this); | ||||
|  | ||||
|     this.createEditField(); | ||||
|  | ||||
|     if (this.options.textarea) { | ||||
|       var br = document.createElement("br"); | ||||
|       this.form.appendChild(br); | ||||
|   createControl: function(mode, handler, extraClasses) { | ||||
|     var control = this.options[mode + 'Control']; | ||||
|     var text = this.options[mode + 'Text']; | ||||
|     if ('button' == control) { | ||||
|       var btn = document.createElement('input'); | ||||
|       btn.type = 'submit'; | ||||
|       btn.value = text; | ||||
|       btn.className = 'editor_' + mode + '_button'; | ||||
|       if ('cancel' == mode) | ||||
|         btn.onclick = this._boundCancelHandler; | ||||
|       this._form.appendChild(btn); | ||||
|       this._controls[mode] = btn; | ||||
|     } else if ('link' == control) { | ||||
|       var link = document.createElement('a'); | ||||
|       link.href = '#'; | ||||
|       link.appendChild(document.createTextNode(text)); | ||||
|       link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler; | ||||
|       link.className = 'editor_' + mode + '_link'; | ||||
|       if (extraClasses) | ||||
|         link.className += ' ' + extraClasses; | ||||
|       this._form.appendChild(link); | ||||
|       this._controls[mode] = link; | ||||
|     } | ||||
|      | ||||
|     if (this.options.textBeforeControls) | ||||
|       this.form.appendChild(document.createTextNode(this.options.textBeforeControls)); | ||||
|  | ||||
|     if (this.options.okButton) { | ||||
|       var okButton = document.createElement("input"); | ||||
|       okButton.type = "submit"; | ||||
|       okButton.value = this.options.okText; | ||||
|       okButton.className = 'editor_ok_button'; | ||||
|       this.form.appendChild(okButton); | ||||
|     } | ||||
|      | ||||
|     if (this.options.okLink) { | ||||
|       var okLink = document.createElement("a"); | ||||
|       okLink.href = "#"; | ||||
|       okLink.appendChild(document.createTextNode(this.options.okText)); | ||||
|       okLink.onclick = this.onSubmit.bind(this); | ||||
|       okLink.className = 'editor_ok_link'; | ||||
|       this.form.appendChild(okLink); | ||||
|     } | ||||
|      | ||||
|     if (this.options.textBetweenControls &&  | ||||
|       (this.options.okLink || this.options.okButton) &&  | ||||
|       (this.options.cancelLink || this.options.cancelButton)) | ||||
|       this.form.appendChild(document.createTextNode(this.options.textBetweenControls)); | ||||
|        | ||||
|     if (this.options.cancelButton) { | ||||
|       var cancelButton = document.createElement("input"); | ||||
|       cancelButton.type = "submit"; | ||||
|       cancelButton.value = this.options.cancelText; | ||||
|       cancelButton.onclick = this.onclickCancel.bind(this); | ||||
|       cancelButton.className = 'editor_cancel_button'; | ||||
|       this.form.appendChild(cancelButton); | ||||
|     } | ||||
|  | ||||
|     if (this.options.cancelLink) { | ||||
|       var cancelLink = document.createElement("a"); | ||||
|       cancelLink.href = "#"; | ||||
|       cancelLink.appendChild(document.createTextNode(this.options.cancelText)); | ||||
|       cancelLink.onclick = this.onclickCancel.bind(this); | ||||
|       cancelLink.className = 'editor_cancel editor_cancel_link';       | ||||
|       this.form.appendChild(cancelLink); | ||||
|     } | ||||
|      | ||||
|     if (this.options.textAfterControls) | ||||
|       this.form.appendChild(document.createTextNode(this.options.textAfterControls)); | ||||
|   }, | ||||
|   hasHTMLLineBreaks: function(string) { | ||||
|     if (!this.options.handleLineBreaks) return false; | ||||
|     return string.match(/<br/i) || string.match(/<p>/i); | ||||
|   }, | ||||
|   convertHTMLLineBreaks: function(string) { | ||||
|     return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<p>/gi, ""); | ||||
|   }, | ||||
|   createEditField: function() { | ||||
|     var text; | ||||
|     if(this.options.loadTextURL) { | ||||
|       text = this.options.loadingText; | ||||
|     } else { | ||||
|       text = this.getText(); | ||||
|     } | ||||
|  | ||||
|     var obj = this; | ||||
|      | ||||
|     if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) { | ||||
|       this.options.textarea = false; | ||||
|       var textField = document.createElement("input"); | ||||
|       textField.obj = this; | ||||
|       textField.type = "text"; | ||||
|       textField.name = this.options.paramName; | ||||
|       textField.value = text; | ||||
|       textField.style.backgroundColor = this.options.highlightcolor; | ||||
|       textField.className = 'editor_field'; | ||||
|     var text = (this.options.loadTextURL ? this.options.loadingText : this.getText()); | ||||
|     var fld; | ||||
|     if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) { | ||||
|       fld = document.createElement('input'); | ||||
|       fld.type = 'text'; | ||||
|       var size = this.options.size || this.options.cols || 0; | ||||
|       if (size != 0) textField.size = size; | ||||
|       if (this.options.submitOnBlur) | ||||
|         textField.onblur = this.onSubmit.bind(this); | ||||
|       this.editField = textField; | ||||
|       if (0 < size) fld.size = size; | ||||
|     } else { | ||||
|       this.options.textarea = true; | ||||
|       var textArea = document.createElement("textarea"); | ||||
|       textArea.obj = this; | ||||
|       textArea.name = this.options.paramName; | ||||
|       textArea.value = this.convertHTMLLineBreaks(text); | ||||
|       textArea.rows = this.options.rows; | ||||
|       textArea.cols = this.options.cols || 40; | ||||
|       textArea.className = 'editor_field';       | ||||
|       if (this.options.submitOnBlur) | ||||
|         textArea.onblur = this.onSubmit.bind(this); | ||||
|       this.editField = textArea; | ||||
|       fld = document.createElement('textarea'); | ||||
|       fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows); | ||||
|       fld.cols = this.options.cols || 40; | ||||
|     } | ||||
|      | ||||
|     if(this.options.loadTextURL) { | ||||
|     fld.name = this.options.paramName; | ||||
|     fld.value = text; // No HTML breaks conversion anymore | ||||
|     fld.className = 'editor_field'; | ||||
|     if (this.options.submitOnBlur) | ||||
|       fld.onblur = this._boundSubmitHandler; | ||||
|     this._controls.editor = fld; | ||||
|     if (this.options.loadTextURL) | ||||
|       this.loadExternalText(); | ||||
|     } | ||||
|     this.form.appendChild(this.editField); | ||||
|     this._form.appendChild(this._controls.editor); | ||||
|   }, | ||||
|   createForm: function() { | ||||
|     var ipe = this; | ||||
|     function addText(mode, condition) { | ||||
|       var text = ipe.options['text' + mode + 'Controls']; | ||||
|       if (!text || condition === false) return; | ||||
|       ipe._form.appendChild(document.createTextNode(text)); | ||||
|     }; | ||||
|     this._form = $(document.createElement('form')); | ||||
|     this._form.id = this.options.formId; | ||||
|     this._form.addClassName(this.options.formClassName); | ||||
|     this._form.onsubmit = this._boundSubmitHandler; | ||||
|     this.createEditField(); | ||||
|     if ('textarea' == this._controls.editor.tagName.toLowerCase()) | ||||
|       this._form.appendChild(document.createElement('br')); | ||||
|     if (this.options.onFormCustomization) | ||||
|       this.options.onFormCustomization(this, this._form); | ||||
|     addText('Before', this.options.okControl || this.options.cancelControl); | ||||
|     this.createControl('ok', this._boundSubmitHandler); | ||||
|     addText('Between', this.options.okControl && this.options.cancelControl); | ||||
|     this.createControl('cancel', this._boundCancelHandler, 'editor_cancel'); | ||||
|     addText('After', this.options.okControl || this.options.cancelControl); | ||||
|   }, | ||||
|   destroy: function() { | ||||
|     if (this._oldInnerHTML) | ||||
|       this.element.innerHTML = this._oldInnerHTML; | ||||
|     this.leaveEditMode(); | ||||
|     this.unregisterListeners(); | ||||
|   }, | ||||
|   enterEditMode: function(e) { | ||||
|     if (this._saving || this._editing) return; | ||||
|     this._editing = true; | ||||
|     this.triggerCallback('onEnterEditMode'); | ||||
|     if (this.options.externalControl) | ||||
|       this.options.externalControl.hide(); | ||||
|     this.element.hide(); | ||||
|     this.createForm(); | ||||
|     this.element.parentNode.insertBefore(this._form, this.element); | ||||
|     if (!this.options.loadTextURL) | ||||
|       this.postProcessEditField(); | ||||
|     if (e) Event.stop(e); | ||||
|   }, | ||||
|   enterHover: function(e) { | ||||
|     if (this.options.hoverClassName) | ||||
|       this.element.addClassName(this.options.hoverClassName); | ||||
|     if (this._saving) return; | ||||
|     this.triggerCallback('onEnterHover'); | ||||
|   }, | ||||
|   getText: function() { | ||||
|     return this.element.innerHTML; | ||||
|   }, | ||||
|   handleAJAXFailure: function(transport) { | ||||
|     this.triggerCallback('onFailure', transport); | ||||
|     if (this._oldInnerHTML) { | ||||
|       this.element.innerHTML = this._oldInnerHTML; | ||||
|       this._oldInnerHTML = null; | ||||
|     } | ||||
|   }, | ||||
|   handleFormCancellation: function(e) { | ||||
|     this.wrapUp(); | ||||
|     if (e) Event.stop(e); | ||||
|   }, | ||||
|   handleFormSubmission: function(e) { | ||||
|     var form = this._form; | ||||
|     var value = $F(this._controls.editor); | ||||
|     this.prepareSubmission(); | ||||
|     var params = this.options.callback(form, value) || ''; | ||||
|     if (Object.isString(params)) | ||||
|       params = params.toQueryParams(); | ||||
|     params.editorId = this.element.id; | ||||
|     if (this.options.htmlResponse) { | ||||
|       var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions); | ||||
|       Object.extend(options, { | ||||
|         parameters: params, | ||||
|         onComplete: this._boundWrapperHandler, | ||||
|         onFailure: this._boundFailureHandler | ||||
|       }); | ||||
|       new Ajax.Updater({ success: this.element }, this.url, options); | ||||
|     } else { | ||||
|       var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); | ||||
|       Object.extend(options, { | ||||
|         parameters: params, | ||||
|         onComplete: this._boundWrapperHandler, | ||||
|         onFailure: this._boundFailureHandler | ||||
|       }); | ||||
|       new Ajax.Request(this.url, options); | ||||
|     } | ||||
|     if (e) Event.stop(e); | ||||
|   }, | ||||
|   leaveEditMode: function() { | ||||
|     this.element.removeClassName(this.options.savingClassName); | ||||
|     this.removeForm(); | ||||
|     this.leaveHover(); | ||||
|     this.element.style.backgroundColor = this._originalBackground; | ||||
|     this.element.show(); | ||||
|     if (this.options.externalControl) | ||||
|       this.options.externalControl.show(); | ||||
|     this._saving = false; | ||||
|     this._editing = false; | ||||
|     this._oldInnerHTML = null; | ||||
|     this.triggerCallback('onLeaveEditMode'); | ||||
|   }, | ||||
|   leaveHover: function(e) { | ||||
|     if (this.options.hoverClassName) | ||||
|       this.element.removeClassName(this.options.hoverClassName); | ||||
|     if (this._saving) return; | ||||
|     this.triggerCallback('onLeaveHover'); | ||||
|   }, | ||||
|   loadExternalText: function() { | ||||
|     Element.addClassName(this.form, this.options.loadingClassName); | ||||
|     this.editField.disabled = true; | ||||
|     new Ajax.Request( | ||||
|       this.options.loadTextURL, | ||||
|       Object.extend({ | ||||
|         asynchronous: true, | ||||
|         onComplete: this.onLoadedExternalText.bind(this) | ||||
|       }, this.options.ajaxOptions) | ||||
|     ); | ||||
|     this._form.addClassName(this.options.loadingClassName); | ||||
|     this._controls.editor.disabled = true; | ||||
|     var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); | ||||
|     Object.extend(options, { | ||||
|       parameters: 'editorId=' + encodeURIComponent(this.element.id), | ||||
|       onComplete: Prototype.emptyFunction, | ||||
|       onSuccess: function(transport) { | ||||
|         this._form.removeClassName(this.options.loadingClassName); | ||||
|         var text = transport.responseText; | ||||
|         if (this.options.stripLoadedTextTags) | ||||
|           text = text.stripTags(); | ||||
|         this._controls.editor.value = text; | ||||
|         this._controls.editor.disabled = false; | ||||
|         this.postProcessEditField(); | ||||
|       }.bind(this), | ||||
|       onFailure: this._boundFailureHandler | ||||
|     }); | ||||
|     new Ajax.Request(this.options.loadTextURL, options); | ||||
|   }, | ||||
|   onLoadedExternalText: function(transport) { | ||||
|     Element.removeClassName(this.form, this.options.loadingClassName); | ||||
|     this.editField.disabled = false; | ||||
|     this.editField.value = transport.responseText.stripTags(); | ||||
|     Field.scrollFreeActivate(this.editField); | ||||
|   postProcessEditField: function() { | ||||
|     var fpc = this.options.fieldPostCreation; | ||||
|     if (fpc) | ||||
|       $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate'](); | ||||
|   }, | ||||
|   onclickCancel: function() { | ||||
|     this.onComplete(); | ||||
|     this.leaveEditMode(); | ||||
|     return false; | ||||
|   prepareOptions: function() { | ||||
|     this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions); | ||||
|     Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks); | ||||
|     [this._extraDefaultOptions].flatten().compact().each(function(defs) { | ||||
|       Object.extend(this.options, defs); | ||||
|     }.bind(this)); | ||||
|   }, | ||||
|   onFailure: function(transport) { | ||||
|     this.options.onFailure(transport); | ||||
|     if (this.oldInnerHTML) { | ||||
|       this.element.innerHTML = this.oldInnerHTML; | ||||
|       this.oldInnerHTML = null; | ||||
|     } | ||||
|     return false; | ||||
|   }, | ||||
|   onSubmit: function() { | ||||
|     // onLoading resets these so we need to save them away for the Ajax call | ||||
|     var form = this.form; | ||||
|     var value = this.editField.value; | ||||
|      | ||||
|     // do this first, sometimes the ajax call returns before we get a chance to switch on Saving... | ||||
|     // which means this will actually switch on Saving... *after* we've left edit mode causing Saving... | ||||
|     // to be displayed indefinitely | ||||
|     this.onLoading(); | ||||
|      | ||||
|     if (this.options.evalScripts) { | ||||
|       new Ajax.Request( | ||||
|         this.url, Object.extend({ | ||||
|           parameters: this.options.callback(form, value), | ||||
|           onComplete: this.onComplete.bind(this), | ||||
|           onFailure: this.onFailure.bind(this), | ||||
|           asynchronous:true,  | ||||
|           evalScripts:true | ||||
|         }, this.options.ajaxOptions)); | ||||
|     } else  { | ||||
|       new Ajax.Updater( | ||||
|         { success: this.element, | ||||
|           // don't update on failure (this could be an option) | ||||
|           failure: null },  | ||||
|         this.url, Object.extend({ | ||||
|           parameters: this.options.callback(form, value), | ||||
|           onComplete: this.onComplete.bind(this), | ||||
|           onFailure: this.onFailure.bind(this) | ||||
|         }, this.options.ajaxOptions)); | ||||
|     } | ||||
|     // stop the event to avoid a page refresh in Safari | ||||
|     if (arguments.length > 1) { | ||||
|       Event.stop(arguments[0]); | ||||
|     } | ||||
|     return false; | ||||
|   }, | ||||
|   onLoading: function() { | ||||
|     this.saving = true; | ||||
|   prepareSubmission: function() { | ||||
|     this._saving = true; | ||||
|     this.removeForm(); | ||||
|     this.leaveHover(); | ||||
|     this.showSaving(); | ||||
|   }, | ||||
|   showSaving: function() { | ||||
|     this.oldInnerHTML = this.element.innerHTML; | ||||
|     this.element.innerHTML = this.options.savingText; | ||||
|     Element.addClassName(this.element, this.options.savingClassName); | ||||
|     this.element.style.backgroundColor = this.originalBackground; | ||||
|     Element.show(this.element); | ||||
|   registerListeners: function() { | ||||
|     this._listeners = { }; | ||||
|     var listener; | ||||
|     $H(Ajax.InPlaceEditor.Listeners).each(function(pair) { | ||||
|       listener = this[pair.value].bind(this); | ||||
|       this._listeners[pair.key] = listener; | ||||
|       if (!this.options.externalControlOnly) | ||||
|         this.element.observe(pair.key, listener); | ||||
|       if (this.options.externalControl) | ||||
|         this.options.externalControl.observe(pair.key, listener); | ||||
|     }.bind(this)); | ||||
|   }, | ||||
|   removeForm: function() { | ||||
|     if(this.form) { | ||||
|       if (this.form.parentNode) Element.remove(this.form); | ||||
|       this.form = null; | ||||
|     if (!this._form) return; | ||||
|     this._form.remove(); | ||||
|     this._form = null; | ||||
|     this._controls = { }; | ||||
|   }, | ||||
|   showSaving: function() { | ||||
|     this._oldInnerHTML = this.element.innerHTML; | ||||
|     this.element.innerHTML = this.options.savingText; | ||||
|     this.element.addClassName(this.options.savingClassName); | ||||
|     this.element.style.backgroundColor = this._originalBackground; | ||||
|     this.element.show(); | ||||
|   }, | ||||
|   triggerCallback: function(cbName, arg) { | ||||
|     if ('function' == typeof this.options[cbName]) { | ||||
|       this.options[cbName](this, arg); | ||||
|     } | ||||
|   }, | ||||
|   enterHover: function() { | ||||
|     if (this.saving) return; | ||||
|     this.element.style.backgroundColor = this.options.highlightcolor; | ||||
|     if (this.effect) { | ||||
|       this.effect.cancel(); | ||||
|     } | ||||
|     Element.addClassName(this.element, this.options.hoverClassName) | ||||
|   unregisterListeners: function() { | ||||
|     $H(this._listeners).each(function(pair) { | ||||
|       if (!this.options.externalControlOnly) | ||||
|         this.element.stopObserving(pair.key, pair.value); | ||||
|       if (this.options.externalControl) | ||||
|         this.options.externalControl.stopObserving(pair.key, pair.value); | ||||
|     }.bind(this)); | ||||
|   }, | ||||
|   leaveHover: function() { | ||||
|     if (this.options.backgroundColor) { | ||||
|       this.element.style.backgroundColor = this.oldBackground; | ||||
|     } | ||||
|     Element.removeClassName(this.element, this.options.hoverClassName) | ||||
|     if (this.saving) return; | ||||
|     this.effect = new Effect.Highlight(this.element, { | ||||
|       startcolor: this.options.highlightcolor, | ||||
|       endcolor: this.options.highlightendcolor, | ||||
|       restorecolor: this.originalBackground | ||||
|     }); | ||||
|   }, | ||||
|   leaveEditMode: function() { | ||||
|     Element.removeClassName(this.element, this.options.savingClassName); | ||||
|     this.removeForm(); | ||||
|     this.leaveHover(); | ||||
|     this.element.style.backgroundColor = this.originalBackground; | ||||
|     Element.show(this.element); | ||||
|     if (this.options.externalControl) { | ||||
|       Element.show(this.options.externalControl); | ||||
|     } | ||||
|     this.editing = false; | ||||
|     this.saving = false; | ||||
|     this.oldInnerHTML = null; | ||||
|     this.onLeaveEditMode(); | ||||
|   }, | ||||
|   onComplete: function(transport) { | ||||
|   wrapUp: function(transport) { | ||||
|     this.leaveEditMode(); | ||||
|     this.options.onComplete.bind(this)(transport, this.element); | ||||
|   }, | ||||
|   onEnterEditMode: function() {}, | ||||
|   onLeaveEditMode: function() {}, | ||||
|   dispose: function() { | ||||
|     if (this.oldInnerHTML) { | ||||
|       this.element.innerHTML = this.oldInnerHTML; | ||||
|     } | ||||
|     this.leaveEditMode(); | ||||
|     Event.stopObserving(this.element, 'click', this.onclickListener); | ||||
|     Event.stopObserving(this.element, 'mouseover', this.mouseoverListener); | ||||
|     Event.stopObserving(this.element, 'mouseout', this.mouseoutListener); | ||||
|     if (this.options.externalControl) { | ||||
|       Event.stopObserving(this.options.externalControl, 'click', this.onclickListener); | ||||
|       Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener); | ||||
|       Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| Ajax.InPlaceCollectionEditor = Class.create(); | ||||
| Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype); | ||||
| Object.extend(Ajax.InPlaceCollectionEditor.prototype, { | ||||
|   createEditField: function() { | ||||
|     if (!this.cached_selectTag) { | ||||
|       var selectTag = document.createElement("select"); | ||||
|       var collection = this.options.collection || []; | ||||
|       var optionTag; | ||||
|       collection.each(function(e,i) { | ||||
|         optionTag = document.createElement("option"); | ||||
|         optionTag.value = (e instanceof Array) ? e[0] : e; | ||||
|         if((typeof this.options.value == 'undefined') &&  | ||||
|           ((e instanceof Array) ? this.element.innerHTML == e[1] : e == optionTag.value)) optionTag.selected = true; | ||||
|         if(this.options.value==optionTag.value) optionTag.selected = true; | ||||
|         optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e)); | ||||
|         selectTag.appendChild(optionTag); | ||||
|       }.bind(this)); | ||||
|       this.cached_selectTag = selectTag; | ||||
|     } | ||||
|  | ||||
|     this.editField = this.cached_selectTag; | ||||
|     if(this.options.loadTextURL) this.loadExternalText(); | ||||
|     this.form.appendChild(this.editField); | ||||
|     this.options.callback = function(form, value) { | ||||
|       return "value=" + encodeURIComponent(value); | ||||
|     } | ||||
|     // Can't use triggerCallback due to backward compatibility: requires | ||||
|     // binding + direct element | ||||
|     this._boundComplete(transport, this.element); | ||||
|   } | ||||
| }); | ||||
|  | ||||
| Object.extend(Ajax.InPlaceEditor.prototype, { | ||||
|   dispose: Ajax.InPlaceEditor.prototype.destroy | ||||
| }); | ||||
|  | ||||
| Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, { | ||||
|   initialize: function($super, element, url, options) { | ||||
|     this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions; | ||||
|     $super(element, url, options); | ||||
|   }, | ||||
|  | ||||
|   createEditField: function() { | ||||
|     var list = document.createElement('select'); | ||||
|     list.name = this.options.paramName; | ||||
|     list.size = 1; | ||||
|     this._controls.editor = list; | ||||
|     this._collection = this.options.collection || []; | ||||
|     if (this.options.loadCollectionURL) | ||||
|       this.loadCollection(); | ||||
|     else | ||||
|       this.checkForExternalText(); | ||||
|     this._form.appendChild(this._controls.editor); | ||||
|   }, | ||||
|  | ||||
|   loadCollection: function() { | ||||
|     this._form.addClassName(this.options.loadingClassName); | ||||
|     this.showLoadingText(this.options.loadingCollectionText); | ||||
|     var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); | ||||
|     Object.extend(options, { | ||||
|       parameters: 'editorId=' + encodeURIComponent(this.element.id), | ||||
|       onComplete: Prototype.emptyFunction, | ||||
|       onSuccess: function(transport) { | ||||
|         var js = transport.responseText.strip(); | ||||
|         if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check | ||||
|           throw 'Server returned an invalid collection representation.'; | ||||
|         this._collection = eval(js); | ||||
|         this.checkForExternalText(); | ||||
|       }.bind(this), | ||||
|       onFailure: this.onFailure | ||||
|     }); | ||||
|     new Ajax.Request(this.options.loadCollectionURL, options); | ||||
|   }, | ||||
|  | ||||
|   showLoadingText: function(text) { | ||||
|     this._controls.editor.disabled = true; | ||||
|     var tempOption = this._controls.editor.firstChild; | ||||
|     if (!tempOption) { | ||||
|       tempOption = document.createElement('option'); | ||||
|       tempOption.value = ''; | ||||
|       this._controls.editor.appendChild(tempOption); | ||||
|       tempOption.selected = true; | ||||
|     } | ||||
|     tempOption.update((text || '').stripScripts().stripTags()); | ||||
|   }, | ||||
|  | ||||
|   checkForExternalText: function() { | ||||
|     this._text = this.getText(); | ||||
|     if (this.options.loadTextURL) | ||||
|       this.loadExternalText(); | ||||
|     else | ||||
|       this.buildOptionList(); | ||||
|   }, | ||||
|  | ||||
|   loadExternalText: function() { | ||||
|     this.showLoadingText(this.options.loadingText); | ||||
|     var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); | ||||
|     Object.extend(options, { | ||||
|       parameters: 'editorId=' + encodeURIComponent(this.element.id), | ||||
|       onComplete: Prototype.emptyFunction, | ||||
|       onSuccess: function(transport) { | ||||
|         this._text = transport.responseText.strip(); | ||||
|         this.buildOptionList(); | ||||
|       }.bind(this), | ||||
|       onFailure: this.onFailure | ||||
|     }); | ||||
|     new Ajax.Request(this.options.loadTextURL, options); | ||||
|   }, | ||||
|  | ||||
|   buildOptionList: function() { | ||||
|     this._form.removeClassName(this.options.loadingClassName); | ||||
|     this._collection = this._collection.map(function(entry) { | ||||
|       return 2 === entry.length ? entry : [entry, entry].flatten(); | ||||
|     }); | ||||
|     var marker = ('value' in this.options) ? this.options.value : this._text; | ||||
|     var textFound = this._collection.any(function(entry) { | ||||
|       return entry[0] == marker; | ||||
|     }.bind(this)); | ||||
|     this._controls.editor.update(''); | ||||
|     var option; | ||||
|     this._collection.each(function(entry, index) { | ||||
|       option = document.createElement('option'); | ||||
|       option.value = entry[0]; | ||||
|       option.selected = textFound ? entry[0] == marker : 0 == index; | ||||
|       option.appendChild(document.createTextNode(entry[1])); | ||||
|       this._controls.editor.appendChild(option); | ||||
|     }.bind(this)); | ||||
|     this._controls.editor.disabled = false; | ||||
|     Field.scrollFreeActivate(this._controls.editor); | ||||
|   } | ||||
| }); | ||||
|  | ||||
| //**** DEPRECATION LAYER FOR InPlace[Collection]Editor! **** | ||||
| //**** This only  exists for a while,  in order to  let **** | ||||
| //**** users adapt to  the new API.  Read up on the new **** | ||||
| //**** API and convert your code to it ASAP!            **** | ||||
|  | ||||
| Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) { | ||||
|   if (!options) return; | ||||
|   function fallback(name, expr) { | ||||
|     if (name in options || expr === undefined) return; | ||||
|     options[name] = expr; | ||||
|   }; | ||||
|   fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' : | ||||
|     options.cancelLink == options.cancelButton == false ? false : undefined))); | ||||
|   fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' : | ||||
|     options.okLink == options.okButton == false ? false : undefined))); | ||||
|   fallback('highlightColor', options.highlightcolor); | ||||
|   fallback('highlightEndColor', options.highlightendcolor); | ||||
| }; | ||||
|  | ||||
| Object.extend(Ajax.InPlaceEditor, { | ||||
|   DefaultOptions: { | ||||
|     ajaxOptions: { }, | ||||
|     autoRows: 3,                                // Use when multi-line w/ rows == 1 | ||||
|     cancelControl: 'link',                      // 'link'|'button'|false | ||||
|     cancelText: 'cancel', | ||||
|     clickToEditText: 'Click to edit', | ||||
|     externalControl: null,                      // id|elt | ||||
|     externalControlOnly: false, | ||||
|     fieldPostCreation: 'activate',              // 'activate'|'focus'|false | ||||
|     formClassName: 'inplaceeditor-form', | ||||
|     formId: null,                               // id|elt | ||||
|     highlightColor: '#ffff99', | ||||
|     highlightEndColor: '#ffffff', | ||||
|     hoverClassName: '', | ||||
|     htmlResponse: true, | ||||
|     loadingClassName: 'inplaceeditor-loading', | ||||
|     loadingText: 'Loading...', | ||||
|     okControl: 'button',                        // 'link'|'button'|false | ||||
|     okText: 'ok', | ||||
|     paramName: 'value', | ||||
|     rows: 1,                                    // If 1 and multi-line, uses autoRows | ||||
|     savingClassName: 'inplaceeditor-saving', | ||||
|     savingText: 'Saving...', | ||||
|     size: 0, | ||||
|     stripLoadedTextTags: false, | ||||
|     submitOnBlur: false, | ||||
|     textAfterControls: '', | ||||
|     textBeforeControls: '', | ||||
|     textBetweenControls: '' | ||||
|   }, | ||||
|   DefaultCallbacks: { | ||||
|     callback: function(form) { | ||||
|       return Form.serialize(form); | ||||
|     }, | ||||
|     onComplete: function(transport, element) { | ||||
|       // For backward compatibility, this one is bound to the IPE, and passes | ||||
|       // the element directly.  It was too often customized, so we don't break it. | ||||
|       new Effect.Highlight(element, { | ||||
|         startcolor: this.options.highlightColor, keepBackgroundImage: true }); | ||||
|     }, | ||||
|     onEnterEditMode: null, | ||||
|     onEnterHover: function(ipe) { | ||||
|       ipe.element.style.backgroundColor = ipe.options.highlightColor; | ||||
|       if (ipe._effect) | ||||
|         ipe._effect.cancel(); | ||||
|     }, | ||||
|     onFailure: function(transport, ipe) { | ||||
|       alert('Error communication with the server: ' + transport.responseText.stripTags()); | ||||
|     }, | ||||
|     onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls. | ||||
|     onLeaveEditMode: null, | ||||
|     onLeaveHover: function(ipe) { | ||||
|       ipe._effect = new Effect.Highlight(ipe.element, { | ||||
|         startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor, | ||||
|         restorecolor: ipe._originalBackground, keepBackgroundImage: true | ||||
|       }); | ||||
|     } | ||||
|   }, | ||||
|   Listeners: { | ||||
|     click: 'enterEditMode', | ||||
|     keydown: 'checkForEscapeOrReturn', | ||||
|     mouseover: 'enterHover', | ||||
|     mouseout: 'leaveHover' | ||||
|   } | ||||
| }); | ||||
|  | ||||
| Ajax.InPlaceCollectionEditor.DefaultOptions = { | ||||
|   loadingCollectionText: 'Loading options...' | ||||
| }; | ||||
|  | ||||
| // Delayed observer, like Form.Element.Observer,  | ||||
| // but waits for delay after last key input | ||||
| // Ideal for live-search fields | ||||
|  | ||||
| Form.Element.DelayedObserver = Class.create(); | ||||
| Form.Element.DelayedObserver.prototype = { | ||||
| Form.Element.DelayedObserver = Class.create({ | ||||
|   initialize: function(element, delay, callback) { | ||||
|     this.delay     = delay || 0.5; | ||||
|     this.element   = $(element); | ||||
| @@ -872,4 +962,4 @@ Form.Element.DelayedObserver.prototype = { | ||||
|     this.timer = null; | ||||
|     this.callback(this.element, $F(this.element)); | ||||
|   } | ||||
| }; | ||||
| }); | ||||
|   | ||||
							
								
								
									
										80
									
								
								xCAT-web/js/dragdrop.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										80
									
								
								xCAT-web/js/dragdrop.js
									
									
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| // script.aculo.us dragdrop.js v1.7.1_beta3, Fri May 25 17:19:41 +0200 2007 | ||||
| // script.aculo.us dragdrop.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007 | ||||
|  | ||||
| // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) | ||||
| //           (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) | ||||
| @@ -6,7 +6,7 @@ | ||||
| // script.aculo.us is freely distributable under the terms of an MIT-style license. | ||||
| // For details, see the script.aculo.us web site: http://script.aculo.us/ | ||||
|  | ||||
| if(typeof Effect == 'undefined') | ||||
| if(Object.isUndefined(Effect)) | ||||
|   throw("dragdrop.js requires including script.aculo.us' effects.js library"); | ||||
|  | ||||
| var Droppables = { | ||||
| @@ -22,14 +22,13 @@ var Droppables = { | ||||
|       greedy:     true, | ||||
|       hoverclass: null, | ||||
|       tree:       false | ||||
|     }, arguments[1] || {}); | ||||
|     }, arguments[1] || { }); | ||||
|  | ||||
|     // cache containers | ||||
|     if(options.containment) { | ||||
|       options._containers = []; | ||||
|       var containment = options.containment; | ||||
|       if((typeof containment == 'object') &&  | ||||
|         (containment.constructor == Array)) { | ||||
|       if(Object.isArray(containment)) { | ||||
|         containment.each( function(c) { options._containers.push($(c)) }); | ||||
|       } else { | ||||
|         options._containers.push($(containment)); | ||||
| @@ -89,21 +88,23 @@ var Droppables = { | ||||
|  | ||||
|   show: function(point, element) { | ||||
|     if(!this.drops.length) return; | ||||
|     var affected = []; | ||||
|     var drop, affected = []; | ||||
|      | ||||
|     if(this.last_active) this.deactivate(this.last_active); | ||||
|     this.drops.each( function(drop) { | ||||
|       if(Droppables.isAffected(point, element, drop)) | ||||
|         affected.push(drop); | ||||
|     }); | ||||
|          | ||||
|     if(affected.length>0) { | ||||
|     if(affected.length>0) | ||||
|       drop = Droppables.findDeepestChild(affected); | ||||
|  | ||||
|     if(this.last_active && this.last_active != drop) this.deactivate(this.last_active); | ||||
|     if (drop) { | ||||
|       Position.within(drop.element, point[0], point[1]); | ||||
|       if(drop.onHover) | ||||
|         drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); | ||||
|        | ||||
|       Droppables.activate(drop); | ||||
|       if (drop != this.last_active) Droppables.activate(drop); | ||||
|     } | ||||
|   }, | ||||
|  | ||||
| @@ -223,10 +224,7 @@ var Draggables = { | ||||
|  | ||||
| /*--------------------------------------------------------------------------*/ | ||||
|  | ||||
| var Draggable = Class.create(); | ||||
| Draggable._dragging    = {}; | ||||
|  | ||||
| Draggable.prototype = { | ||||
| var Draggable = Class.create({ | ||||
|   initialize: function(element) { | ||||
|     var defaults = { | ||||
|       handle: false, | ||||
| @@ -237,7 +235,7 @@ Draggable.prototype = { | ||||
|         }); | ||||
|       }, | ||||
|       endeffect: function(element) { | ||||
|         var toOpacity = typeof element._opacity == 'number' ? element._opacity : 1.0; | ||||
|         var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0; | ||||
|         new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,  | ||||
|           queue: {scope:'_draggable', position:'end'}, | ||||
|           afterFinish: function(){  | ||||
| @@ -255,7 +253,7 @@ Draggable.prototype = { | ||||
|       delay: 0 | ||||
|     }; | ||||
|      | ||||
|     if(!arguments[1] || typeof arguments[1].endeffect == 'undefined') | ||||
|     if(!arguments[1] || Object.isUndefined(arguments[1].endeffect)) | ||||
|       Object.extend(defaults, { | ||||
|         starteffect: function(element) { | ||||
|           element._opacity = Element.getOpacity(element); | ||||
| @@ -264,11 +262,11 @@ Draggable.prototype = { | ||||
|         } | ||||
|       }); | ||||
|      | ||||
|     var options = Object.extend(defaults, arguments[1] || {}); | ||||
|     var options = Object.extend(defaults, arguments[1] || { }); | ||||
|  | ||||
|     this.element = $(element); | ||||
|      | ||||
|     if(options.handle && (typeof options.handle == 'string')) | ||||
|     if(options.handle && Object.isString(options.handle)) | ||||
|       this.handle = this.element.down('.'+options.handle, 0); | ||||
|      | ||||
|     if(!this.handle) this.handle = $(options.handle); | ||||
| @@ -281,7 +279,6 @@ Draggable.prototype = { | ||||
|  | ||||
|     Element.makePositioned(this.element); // fix IE     | ||||
|  | ||||
|     this.delta    = this.currentDelta(); | ||||
|     this.options  = options; | ||||
|     this.dragging = false;    | ||||
|  | ||||
| @@ -303,7 +300,7 @@ Draggable.prototype = { | ||||
|   }, | ||||
|    | ||||
|   initDrag: function(event) { | ||||
|     if(typeof Draggable._dragging[this.element] != 'undefined' && | ||||
|     if(!Object.isUndefined(Draggable._dragging[this.element]) && | ||||
|       Draggable._dragging[this.element]) return; | ||||
|     if(Event.isLeftClick(event)) {     | ||||
|       // abort on form elements, fixes a Firefox issue | ||||
| @@ -326,6 +323,8 @@ Draggable.prototype = { | ||||
|    | ||||
|   startDrag: function(event) { | ||||
|     this.dragging = true; | ||||
|     if(!this.delta) | ||||
|       this.delta = this.currentDelta(); | ||||
|      | ||||
|     if(this.options.zindex) { | ||||
|       this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); | ||||
| @@ -334,7 +333,9 @@ Draggable.prototype = { | ||||
|      | ||||
|     if(this.options.ghosting) { | ||||
|       this._clone = this.element.cloneNode(true); | ||||
|       Position.absolutize(this.element); | ||||
|       this.element._originallyAbsolute = (this.element.getStyle('position') == 'absolute'); | ||||
|       if (!this.element._originallyAbsolute) | ||||
|         Position.absolutize(this.element); | ||||
|       this.element.parentNode.insertBefore(this._clone, this.element); | ||||
|     } | ||||
|      | ||||
| @@ -404,7 +405,9 @@ Draggable.prototype = { | ||||
|     } | ||||
|  | ||||
|     if(this.options.ghosting) { | ||||
|       Position.relativize(this.element); | ||||
|       if (!this.element._originallyAbsolute) | ||||
|         Position.relativize(this.element); | ||||
|       delete this.element._originallyAbsolute; | ||||
|       Element.remove(this._clone); | ||||
|       this._clone = null; | ||||
|     } | ||||
| @@ -418,7 +421,7 @@ Draggable.prototype = { | ||||
|     Draggables.notify('onEnd', this, event); | ||||
|  | ||||
|     var revert = this.options.revert; | ||||
|     if(revert && typeof revert == 'function') revert = revert(this.element); | ||||
|     if(revert && Object.isFunction(revert)) revert = revert(this.element); | ||||
|      | ||||
|     var d = this.currentDelta(); | ||||
|     if(revert && this.options.reverteffect) { | ||||
| @@ -472,15 +475,15 @@ Draggable.prototype = { | ||||
|     }.bind(this)); | ||||
|      | ||||
|     if(this.options.snap) { | ||||
|       if(typeof this.options.snap == 'function') { | ||||
|       if(Object.isFunction(this.options.snap)) { | ||||
|         p = this.options.snap(p[0],p[1],this); | ||||
|       } else { | ||||
|       if(this.options.snap instanceof Array) { | ||||
|       if(Object.isArray(this.options.snap)) { | ||||
|         p = p.map( function(v, i) { | ||||
|           return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this)) | ||||
|           return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this)) | ||||
|       } else { | ||||
|         p = p.map( function(v) { | ||||
|           return Math.round(v/this.options.snap)*this.options.snap }.bind(this)) | ||||
|           return (v/this.options.snap).round()*this.options.snap }.bind(this)) | ||||
|       } | ||||
|     }} | ||||
|      | ||||
| @@ -564,12 +567,13 @@ Draggable.prototype = { | ||||
|     } | ||||
|     return { top: T, left: L, width: W, height: H }; | ||||
|   } | ||||
| } | ||||
| }); | ||||
|  | ||||
| Draggable._dragging = { }; | ||||
|  | ||||
| /*--------------------------------------------------------------------------*/ | ||||
|  | ||||
| var SortableObserver = Class.create(); | ||||
| SortableObserver.prototype = { | ||||
| var SortableObserver = Class.create({ | ||||
|   initialize: function(element, observer) { | ||||
|     this.element   = $(element); | ||||
|     this.observer  = observer; | ||||
| @@ -585,12 +589,12 @@ SortableObserver.prototype = { | ||||
|     if(this.lastValue != Sortable.serialize(this.element)) | ||||
|       this.observer(this.element) | ||||
|   } | ||||
| } | ||||
| }); | ||||
|  | ||||
| var Sortable = { | ||||
|   SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/, | ||||
|    | ||||
|   sortables: {}, | ||||
|   sortables: { }, | ||||
|    | ||||
|   _findRootElement: function(element) { | ||||
|     while (element.tagName.toUpperCase() != "BODY") {   | ||||
| @@ -646,7 +650,7 @@ var Sortable = { | ||||
|        | ||||
|       onChange:    Prototype.emptyFunction, | ||||
|       onUpdate:    Prototype.emptyFunction | ||||
|     }, arguments[1] || {}); | ||||
|     }, arguments[1] || { }); | ||||
|  | ||||
|     // clear any old sortable with same element | ||||
|     this.destroy(element); | ||||
| @@ -710,7 +714,7 @@ var Sortable = { | ||||
|  | ||||
|     (options.elements || this.findElements(element, options) || []).each( function(e,i) { | ||||
|       var handle = options.handles ? $(options.handles[i]) : | ||||
|         (options.handle ? $(e).getElementsByClassName(options.handle)[0] : e);  | ||||
|         (options.handle ? $(e).select('.' + options.handle)[0] : e);  | ||||
|       options.draggables.push( | ||||
|         new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); | ||||
|       Droppables.add(e, options_for_droppable); | ||||
| @@ -870,7 +874,7 @@ var Sortable = { | ||||
|       only: sortableOptions.only, | ||||
|       name: element.id, | ||||
|       format: sortableOptions.format | ||||
|     }, arguments[1] || {}); | ||||
|     }, arguments[1] || { }); | ||||
|      | ||||
|     var root = { | ||||
|       id: null, | ||||
| @@ -894,7 +898,7 @@ var Sortable = { | ||||
|  | ||||
|   sequence: function(element) { | ||||
|     element = $(element); | ||||
|     var options = Object.extend(this.options(element), arguments[1] || {}); | ||||
|     var options = Object.extend(this.options(element), arguments[1] || { }); | ||||
|      | ||||
|     return $(this.findElements(element, options) || []).map( function(item) { | ||||
|       return item.id.match(options.format) ? item.id.match(options.format)[1] : ''; | ||||
| @@ -903,9 +907,9 @@ var Sortable = { | ||||
|  | ||||
|   setSequence: function(element, new_sequence) { | ||||
|     element = $(element); | ||||
|     var options = Object.extend(this.options(element), arguments[2] || {}); | ||||
|     var options = Object.extend(this.options(element), arguments[2] || { }); | ||||
|      | ||||
|     var nodeMap = {}; | ||||
|     var nodeMap = { }; | ||||
|     this.findElements(element, options).each( function(n) { | ||||
|         if (n.id.match(options.format)) | ||||
|             nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode]; | ||||
| @@ -923,7 +927,7 @@ var Sortable = { | ||||
|    | ||||
|   serialize: function(element) { | ||||
|     element = $(element); | ||||
|     var options = Object.extend(Sortable.options(element), arguments[1] || {}); | ||||
|     var options = Object.extend(Sortable.options(element), arguments[1] || { }); | ||||
|     var name = encodeURIComponent( | ||||
|       (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); | ||||
|      | ||||
|   | ||||
| @@ -1,64 +0,0 @@ | ||||
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||||
|  | ||||
| <html> | ||||
| <head> | ||||
| 	<title>dhtmlxTree v.1.5 Standard</title> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|  | ||||
| <h1>dhtmlxTree Standard Samples</h1> | ||||
|  | ||||
| <h3>New samples in version 1.5</h3> | ||||
| <a target="_blank" href="samples/drag_in_simple.html"><li>Simple drag-n-drop into tree from any HTML</li></a> | ||||
| <a target="_blank" href="samples/tree_iconset.html"><li>Changing iconsets</li></a> | ||||
|  | ||||
| <h3>Other samples*</h3> | ||||
| <a target="_blank" href="samples/tree_init_from_html.html"><li>Init from html</li></a> | ||||
| <a target="_blank" href="samples/treeEx11.html"><li>dhtmlXTree - Initialize object on page</li></a> | ||||
| <a target="_blank" href="samples/treeEx12.html"><li>dhtmlXTree - Add / Delete items</li></a> | ||||
| <a target="_blank" href="samples/treeEx13.html"><li>Event handlers</li></a> | ||||
| <a target="_blank" href="samples/treeEx21.html"><li>Collapse/Expand</li></a> | ||||
| <a target="_blank" href="samples/treeEx22.html"><li>Change text/image</li></a> | ||||
| <a target="_blank" href="samples/treeEx23.html"><li>Checkboxes</li></a> | ||||
| <a target="_blank" href="samples/treeEx24.html"><li>Easy skinable design</li></a> | ||||
| <a target="_blank" href="samples/treeEx31.html"><li>Autoloading from XML</li></a> | ||||
| <a target="_blank" href="samples/treeEx32.html"><li>Drag and Drop</li></a> | ||||
|  | ||||
| <h3>Professional Edition features</h3> | ||||
| <li>Context Menu</li> | ||||
| <li>Sorting (including custom type)</li> | ||||
| <li>OnDrag/OnDrop event handler</li> | ||||
| <li>Additional Drag-n-drop behavior – drop-as-sibling, complex drag-n-drop</li> | ||||
| <li>Drag-n-drop between frames</li> | ||||
| <li>Drag-n-drop to/from <a target="_blank" href="http://www.scbr.com/docs/products/dhtmlxGrid/index.shtml">dhtmlxGrid</a></li> | ||||
| <li>Ability to move items within/between trees with script API</li> | ||||
| <li>Multiselect, drag-n-drop multiple items</li> | ||||
| <li>Focus item with script method</li> | ||||
| <li>Dynamic rendering – advanced xml processing for loading big trees when dynamical loading can't be used</li> | ||||
| <li>Serialization – possibility to create XML based on updated tree structure.</li> | ||||
| <li>Search</li> | ||||
| <li>Multi-line tree items</li> | ||||
| <li>Saving/Restoring tree state in/from cookies</li> | ||||
| <li>Change icon size</li> | ||||
| <li>Editable Items</li> | ||||
| <li>Ability to automaticaly update server side on tree structure changes</li> | ||||
| <li>Keyboard navigation</li> | ||||
| <li>Locked items</li> | ||||
| <li>Right-to-left languages support</li> | ||||
| <li>Error handling</li> | ||||
| <li>Quick Search - navigate through the tree typing node name</li> | ||||
| <li>Tree lock</li> | ||||
|  | ||||
|  | ||||
|  | ||||
| <br><br> | ||||
| <small>*More than 50 samples of various features included in Professional Edition. <br> | ||||
| To obtain and use dhtmlxTree Professional contact us at <a href="mailto:dhtmlx@scand.com">dhtmlx@scand.com</a></small> | ||||
|  | ||||
| <hr> | ||||
| © Scand LLC | ||||
|  | ||||
|  | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										3269
									
								
								xCAT-web/js/prototype_rc3.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3269
									
								
								xCAT-web/js/prototype_rc3.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,23 +0,0 @@ | ||||
|  | ||||
| Current version: 1.5 from March 23, 2007 | ||||
|  | ||||
| ============================================================================================ | ||||
|  | ||||
| If you want to use dhtmlXTree in a commercial product, you have to buy a commercial license.  | ||||
| Please contact us at info@scand.com | ||||
|  | ||||
| Some comments on commercial usage: | ||||
|  | ||||
| 1.Commercial License allows you to use dhtmlXTree on unlimited number of Websites or sites  | ||||
| but only in one commercial project(application). According to this license we provide you  | ||||
| with support (consultations) and free-of-charge bug fixing during 1 month.  | ||||
| This license costs $99.  | ||||
|  | ||||
| 2.Enterprise License allows you to use dhtmlXTree in unlimited number of projects on condition  | ||||
| that all of them are projects of one company. Support period is 1 year.  | ||||
| This license costs $399. | ||||
|  | ||||
|  | ||||
| According to both licenses you are allowed to make changes to the code of Software but Scand LLC  | ||||
| still owns the code and you are not allowed to distribute changed code. | ||||
|  | ||||
| @@ -1,12 +1,11 @@ | ||||
| // script.aculo.us slider.js v1.7.1_beta3, Fri May 25 17:19:41 +0200 2007 | ||||
| // script.aculo.us slider.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007 | ||||
|  | ||||
| // Copyright (c) 2005-2007 Marty Haught, Thomas Fuchs  | ||||
| // | ||||
| // script.aculo.us is freely distributable under the terms of an MIT-style license. | ||||
| // For details, see the script.aculo.us web site: http://script.aculo.us/ | ||||
|  | ||||
| if(!Control) var Control = {}; | ||||
| Control.Slider = Class.create(); | ||||
| if (!Control) var Control = { }; | ||||
|  | ||||
| // options: | ||||
| //  axis: 'vertical', or 'horizontal' (default) | ||||
| @@ -14,18 +13,18 @@ Control.Slider = Class.create(); | ||||
| // callbacks: | ||||
| //  onChange(value) | ||||
| //  onSlide(value) | ||||
| Control.Slider.prototype = { | ||||
| Control.Slider = Class.create({ | ||||
|   initialize: function(handle, track, options) { | ||||
|     var slider = this; | ||||
|      | ||||
|     if(handle instanceof Array) { | ||||
|     if (Object.isArray(handle)) { | ||||
|       this.handles = handle.collect( function(e) { return $(e) }); | ||||
|     } else { | ||||
|       this.handles = [$(handle)]; | ||||
|     } | ||||
|      | ||||
|     this.track   = $(track); | ||||
|     this.options = options || {}; | ||||
|     this.options = options || { }; | ||||
|  | ||||
|     this.axis      = this.options.axis || 'horizontal'; | ||||
|     this.increment = this.options.increment || 1; | ||||
| @@ -59,11 +58,11 @@ Control.Slider.prototype = { | ||||
|     this.dragging = false; | ||||
|     this.disabled = false; | ||||
|  | ||||
|     if(this.options.disabled) this.setDisabled(); | ||||
|     if (this.options.disabled) this.setDisabled(); | ||||
|  | ||||
|     // Allowed values array | ||||
|     this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false; | ||||
|     if(this.allowedValues) { | ||||
|     if (this.allowedValues) { | ||||
|       this.minimum = this.allowedValues.min(); | ||||
|       this.maximum = this.allowedValues.max(); | ||||
|     } | ||||
| @@ -76,16 +75,15 @@ Control.Slider.prototype = { | ||||
|     this.handles.each( function(h,i) { | ||||
|       i = slider.handles.length-1-i; | ||||
|       slider.setValue(parseFloat( | ||||
|         (slider.options.sliderValue instanceof Array ?  | ||||
|         (Object.isArray(slider.options.sliderValue) ?  | ||||
|           slider.options.sliderValue[i] : slider.options.sliderValue) ||  | ||||
|          slider.range.start), i); | ||||
|       Element.makePositioned(h); // fix IE | ||||
|       Event.observe(h, "mousedown", slider.eventMouseDown); | ||||
|       h.makePositioned().observe("mousedown", slider.eventMouseDown); | ||||
|     }); | ||||
|      | ||||
|     Event.observe(this.track, "mousedown", this.eventMouseDown); | ||||
|     Event.observe(document, "mouseup", this.eventMouseUp); | ||||
|     Event.observe(document, "mousemove", this.eventMouseMove); | ||||
|     this.track.observe("mousedown", this.eventMouseDown); | ||||
|     document.observe("mouseup", this.eventMouseUp); | ||||
|     document.observe("mousemove", this.eventMouseMove); | ||||
|      | ||||
|     this.initialized = true; | ||||
|   }, | ||||
| @@ -105,36 +103,36 @@ Control.Slider.prototype = { | ||||
|     this.disabled = false; | ||||
|   },   | ||||
|   getNearestValue: function(value){ | ||||
|     if(this.allowedValues){ | ||||
|       if(value >= this.allowedValues.max()) return(this.allowedValues.max()); | ||||
|       if(value <= this.allowedValues.min()) return(this.allowedValues.min()); | ||||
|     if (this.allowedValues){ | ||||
|       if (value >= this.allowedValues.max()) return(this.allowedValues.max()); | ||||
|       if (value <= this.allowedValues.min()) return(this.allowedValues.min()); | ||||
|        | ||||
|       var offset = Math.abs(this.allowedValues[0] - value); | ||||
|       var newValue = this.allowedValues[0]; | ||||
|       this.allowedValues.each( function(v) { | ||||
|         var currentOffset = Math.abs(v - value); | ||||
|         if(currentOffset <= offset){ | ||||
|         if (currentOffset <= offset){ | ||||
|           newValue = v; | ||||
|           offset = currentOffset; | ||||
|         }  | ||||
|       }); | ||||
|       return newValue; | ||||
|     } | ||||
|     if(value > this.range.end) return this.range.end; | ||||
|     if(value < this.range.start) return this.range.start; | ||||
|     if (value > this.range.end) return this.range.end; | ||||
|     if (value < this.range.start) return this.range.start; | ||||
|     return value; | ||||
|   }, | ||||
|   setValue: function(sliderValue, handleIdx){ | ||||
|     if(!this.active) { | ||||
|     if (!this.active) { | ||||
|       this.activeHandleIdx = handleIdx || 0; | ||||
|       this.activeHandle    = this.handles[this.activeHandleIdx]; | ||||
|       this.updateStyles(); | ||||
|     } | ||||
|     handleIdx = handleIdx || this.activeHandleIdx || 0; | ||||
|     if(this.initialized && this.restricted) { | ||||
|       if((handleIdx>0) && (sliderValue<this.values[handleIdx-1])) | ||||
|     if (this.initialized && this.restricted) { | ||||
|       if ((handleIdx>0) && (sliderValue<this.values[handleIdx-1])) | ||||
|         sliderValue = this.values[handleIdx-1]; | ||||
|       if((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1])) | ||||
|       if ((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1])) | ||||
|         sliderValue = this.values[handleIdx+1]; | ||||
|     } | ||||
|     sliderValue = this.getNearestValue(sliderValue); | ||||
| @@ -145,7 +143,7 @@ Control.Slider.prototype = { | ||||
|       this.translateToPx(sliderValue); | ||||
|      | ||||
|     this.drawSpans(); | ||||
|     if(!this.dragging || !this.event) this.updateFinished(); | ||||
|     if (!this.dragging || !this.event) this.updateFinished(); | ||||
|   }, | ||||
|   setValueBy: function(delta, handleIdx) { | ||||
|     this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta,  | ||||
| @@ -173,24 +171,24 @@ Control.Slider.prototype = { | ||||
|       (this.track.offsetHeight != 0 ? this.track.offsetHeight : | ||||
|         this.track.style.height.replace(/px$/,"")) - this.alignY :  | ||||
|       (this.track.offsetWidth != 0 ? this.track.offsetWidth :  | ||||
|         this.track.style.width.replace(/px$/,"")) - this.alignY); | ||||
|         this.track.style.width.replace(/px$/,"")) - this.alignX); | ||||
|   },   | ||||
|   isVertical:  function(){ | ||||
|     return (this.axis == 'vertical'); | ||||
|   }, | ||||
|   drawSpans: function() { | ||||
|     var slider = this; | ||||
|     if(this.spans) | ||||
|     if (this.spans) | ||||
|       $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) }); | ||||
|     if(this.options.startSpan) | ||||
|     if (this.options.startSpan) | ||||
|       this.setSpan(this.options.startSpan, | ||||
|         $R(0, this.values.length>1 ? this.getRange(0).min() : this.value )); | ||||
|     if(this.options.endSpan) | ||||
|     if (this.options.endSpan) | ||||
|       this.setSpan(this.options.endSpan,  | ||||
|         $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum)); | ||||
|   }, | ||||
|   setSpan: function(span, range) { | ||||
|     if(this.isVertical()) { | ||||
|     if (this.isVertical()) { | ||||
|       span.style.top = this.translateToPx(range.start); | ||||
|       span.style.height = this.translateToPx(range.end - range.start + this.range.start); | ||||
|     } else { | ||||
| @@ -203,14 +201,14 @@ Control.Slider.prototype = { | ||||
|     Element.addClassName(this.activeHandle, 'selected'); | ||||
|   }, | ||||
|   startDrag: function(event) { | ||||
|     if(Event.isLeftClick(event)) { | ||||
|       if(!this.disabled){ | ||||
|     if (Event.isLeftClick(event)) { | ||||
|       if (!this.disabled){ | ||||
|         this.active = true; | ||||
|          | ||||
|         var handle = Event.element(event); | ||||
|         var pointer  = [Event.pointerX(event), Event.pointerY(event)]; | ||||
|         var track = handle; | ||||
|         if(track==this.track) { | ||||
|         if (track==this.track) { | ||||
|           var offsets  = Position.cumulativeOffset(this.track);  | ||||
|           this.event = event; | ||||
|           this.setValue(this.translateToValue(  | ||||
| @@ -224,7 +222,7 @@ Control.Slider.prototype = { | ||||
|           while((this.handles.indexOf(handle) == -1) && handle.parentNode)  | ||||
|             handle = handle.parentNode; | ||||
|              | ||||
|           if(this.handles.indexOf(handle)!=-1) { | ||||
|           if (this.handles.indexOf(handle)!=-1) { | ||||
|             this.activeHandle    = handle; | ||||
|             this.activeHandleIdx = this.handles.indexOf(this.activeHandle); | ||||
|             this.updateStyles(); | ||||
| @@ -239,10 +237,10 @@ Control.Slider.prototype = { | ||||
|     } | ||||
|   }, | ||||
|   update: function(event) { | ||||
|    if(this.active) { | ||||
|       if(!this.dragging) this.dragging = true; | ||||
|    if (this.active) { | ||||
|       if (!this.dragging) this.dragging = true; | ||||
|       this.draw(event); | ||||
|       if(Prototype.Browser.WebKit) window.scrollBy(0,0); | ||||
|       if (Prototype.Browser.WebKit) window.scrollBy(0,0); | ||||
|       Event.stop(event); | ||||
|    } | ||||
|   }, | ||||
| @@ -253,11 +251,11 @@ Control.Slider.prototype = { | ||||
|     pointer[1] -= this.offsetY + offsets[1]; | ||||
|     this.event = event; | ||||
|     this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] )); | ||||
|     if(this.initialized && this.options.onSlide) | ||||
|     if (this.initialized && this.options.onSlide) | ||||
|       this.options.onSlide(this.values.length>1 ? this.values : this.value, this); | ||||
|   }, | ||||
|   endDrag: function(event) { | ||||
|     if(this.active && this.dragging) { | ||||
|     if (this.active && this.dragging) { | ||||
|       this.finishDrag(event, true); | ||||
|       Event.stop(event); | ||||
|     } | ||||
| @@ -270,8 +268,8 @@ Control.Slider.prototype = { | ||||
|     this.updateFinished(); | ||||
|   }, | ||||
|   updateFinished: function() { | ||||
|     if(this.initialized && this.options.onChange)  | ||||
|     if (this.initialized && this.options.onChange)  | ||||
|       this.options.onChange(this.values.length>1 ? this.values : this.value, this); | ||||
|     this.event = null; | ||||
|   } | ||||
| } | ||||
| }); | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| // script.aculo.us sound.js v1.7.1_beta3, Fri May 25 17:19:41 +0200 2007 | ||||
| // script.aculo.us sound.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007 | ||||
|  | ||||
| // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) | ||||
| // | ||||
| @@ -39,16 +39,11 @@ Sound = { | ||||
|       this.tracks[options.track].id++; | ||||
|        | ||||
|     options.id = this.tracks[options.track].id; | ||||
|     if (Prototype.Browser.IE) { | ||||
|       var sound = document.createElement('bgsound'); | ||||
|       sound.setAttribute('id','sound_'+options.track+'_'+options.id); | ||||
|       sound.setAttribute('src',options.url); | ||||
|       sound.setAttribute('loop','1'); | ||||
|       sound.setAttribute('autostart','true'); | ||||
|       $$('body')[0].appendChild(sound); | ||||
|     }   | ||||
|     else | ||||
|       new Insertion.Bottom($$('body')[0], Sound.template.evaluate(options)); | ||||
|     $$('body')[0].insert(  | ||||
|       Prototype.Browser.IE ? new Element('bgsound',{ | ||||
|         id: 'sound_'+options.track+'_'+options.id, | ||||
|         src: options.url, loop: 1, autostart: true | ||||
|       }) : Sound.template.evaluate(options)); | ||||
|   } | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -1,564 +0,0 @@ | ||||
| // script.aculo.us unittest.js v1.7.1_beta3, Fri May 25 17:19:41 +0200 2007 | ||||
|  | ||||
| // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) | ||||
| //           (c) 2005-2007 Jon Tirsen (http://www.tirsen.com) | ||||
| //           (c) 2005-2007 Michael Schuerig (http://www.schuerig.de/michael/) | ||||
| // | ||||
| // script.aculo.us is freely distributable under the terms of an MIT-style license. | ||||
| // For details, see the script.aculo.us web site: http://script.aculo.us/ | ||||
|  | ||||
| // experimental, Firefox-only | ||||
| Event.simulateMouse = function(element, eventName) { | ||||
|   var options = Object.extend({ | ||||
|     pointerX: 0, | ||||
|     pointerY: 0, | ||||
|     buttons:  0, | ||||
|     ctrlKey:  false, | ||||
|     altKey:   false, | ||||
|     shiftKey: false, | ||||
|     metaKey:  false | ||||
|   }, arguments[2] || {}); | ||||
|   var oEvent = document.createEvent("MouseEvents"); | ||||
|   oEvent.initMouseEvent(eventName, true, true, document.defaultView,  | ||||
|     options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY,  | ||||
|     options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, 0, $(element)); | ||||
|    | ||||
|   if(this.mark) Element.remove(this.mark); | ||||
|   this.mark = document.createElement('div'); | ||||
|   this.mark.appendChild(document.createTextNode(" ")); | ||||
|   document.body.appendChild(this.mark); | ||||
|   this.mark.style.position = 'absolute'; | ||||
|   this.mark.style.top = options.pointerY + "px"; | ||||
|   this.mark.style.left = options.pointerX + "px"; | ||||
|   this.mark.style.width = "5px"; | ||||
|   this.mark.style.height = "5px;"; | ||||
|   this.mark.style.borderTop = "1px solid red;" | ||||
|   this.mark.style.borderLeft = "1px solid red;" | ||||
|    | ||||
|   if(this.step) | ||||
|     alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options)); | ||||
|    | ||||
|   $(element).dispatchEvent(oEvent); | ||||
| }; | ||||
|  | ||||
| // Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2. | ||||
| // You need to downgrade to 1.0.4 for now to get this working | ||||
| // See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much | ||||
| Event.simulateKey = function(element, eventName) { | ||||
|   var options = Object.extend({ | ||||
|     ctrlKey: false, | ||||
|     altKey: false, | ||||
|     shiftKey: false, | ||||
|     metaKey: false, | ||||
|     keyCode: 0, | ||||
|     charCode: 0 | ||||
|   }, arguments[2] || {}); | ||||
|  | ||||
|   var oEvent = document.createEvent("KeyEvents"); | ||||
|   oEvent.initKeyEvent(eventName, true, true, window,  | ||||
|     options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, | ||||
|     options.keyCode, options.charCode ); | ||||
|   $(element).dispatchEvent(oEvent); | ||||
| }; | ||||
|  | ||||
| Event.simulateKeys = function(element, command) { | ||||
|   for(var i=0; i<command.length; i++) { | ||||
|     Event.simulateKey(element,'keypress',{charCode:command.charCodeAt(i)}); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| var Test = {} | ||||
| Test.Unit = {}; | ||||
|  | ||||
| // security exception workaround | ||||
| Test.Unit.inspect = Object.inspect; | ||||
|  | ||||
| Test.Unit.Logger = Class.create(); | ||||
| Test.Unit.Logger.prototype = { | ||||
|   initialize: function(log) { | ||||
|     this.log = $(log); | ||||
|     if (this.log) { | ||||
|       this._createLogTable(); | ||||
|     } | ||||
|   }, | ||||
|   start: function(testName) { | ||||
|     if (!this.log) return; | ||||
|     this.testName = testName; | ||||
|     this.lastLogLine = document.createElement('tr'); | ||||
|     this.statusCell = document.createElement('td'); | ||||
|     this.nameCell = document.createElement('td'); | ||||
|     this.nameCell.className = "nameCell"; | ||||
|     this.nameCell.appendChild(document.createTextNode(testName)); | ||||
|     this.messageCell = document.createElement('td'); | ||||
|     this.lastLogLine.appendChild(this.statusCell); | ||||
|     this.lastLogLine.appendChild(this.nameCell); | ||||
|     this.lastLogLine.appendChild(this.messageCell); | ||||
|     this.loglines.appendChild(this.lastLogLine); | ||||
|   }, | ||||
|   finish: function(status, summary) { | ||||
|     if (!this.log) return; | ||||
|     this.lastLogLine.className = status; | ||||
|     this.statusCell.innerHTML = status; | ||||
|     this.messageCell.innerHTML = this._toHTML(summary); | ||||
|     this.addLinksToResults(); | ||||
|   }, | ||||
|   message: function(message) { | ||||
|     if (!this.log) return; | ||||
|     this.messageCell.innerHTML = this._toHTML(message); | ||||
|   }, | ||||
|   summary: function(summary) { | ||||
|     if (!this.log) return; | ||||
|     this.logsummary.innerHTML = this._toHTML(summary); | ||||
|   }, | ||||
|   _createLogTable: function() { | ||||
|     this.log.innerHTML = | ||||
|     '<div id="logsummary"></div>' + | ||||
|     '<table id="logtable">' + | ||||
|     '<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' + | ||||
|     '<tbody id="loglines"></tbody>' + | ||||
|     '</table>'; | ||||
|     this.logsummary = $('logsummary') | ||||
|     this.loglines = $('loglines'); | ||||
|   }, | ||||
|   _toHTML: function(txt) { | ||||
|     return txt.escapeHTML().replace(/\n/g,"<br/>"); | ||||
|   }, | ||||
|   addLinksToResults: function(){  | ||||
|     $$("tr.failed .nameCell").each( function(td){ // todo: limit to children of this.log | ||||
|       td.title = "Run only this test" | ||||
|       Event.observe(td, 'click', function(){ window.location.search = "?tests=" + td.innerHTML;}); | ||||
|     }); | ||||
|     $$("tr.passed .nameCell").each( function(td){ // todo: limit to children of this.log | ||||
|       td.title = "Run all tests" | ||||
|       Event.observe(td, 'click', function(){ window.location.search = "";}); | ||||
|     }); | ||||
|   } | ||||
| } | ||||
|  | ||||
| Test.Unit.Runner = Class.create(); | ||||
| Test.Unit.Runner.prototype = { | ||||
|   initialize: function(testcases) { | ||||
|     this.options = Object.extend({ | ||||
|       testLog: 'testlog' | ||||
|     }, arguments[1] || {}); | ||||
|     this.options.resultsURL = this.parseResultsURLQueryParameter(); | ||||
|     this.options.tests      = this.parseTestsQueryParameter(); | ||||
|     if (this.options.testLog) { | ||||
|       this.options.testLog = $(this.options.testLog) || null; | ||||
|     } | ||||
|     if(this.options.tests) { | ||||
|       this.tests = []; | ||||
|       for(var i = 0; i < this.options.tests.length; i++) { | ||||
|         if(/^test/.test(this.options.tests[i])) { | ||||
|           this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"])); | ||||
|         } | ||||
|       } | ||||
|     } else { | ||||
|       if (this.options.test) { | ||||
|         this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])]; | ||||
|       } else { | ||||
|         this.tests = []; | ||||
|         for(var testcase in testcases) { | ||||
|           if(/^test/.test(testcase)) { | ||||
|             this.tests.push( | ||||
|                new Test.Unit.Testcase( | ||||
|                  this.options.context ? ' -> ' + this.options.titles[testcase] : testcase,  | ||||
|                  testcases[testcase], testcases["setup"], testcases["teardown"] | ||||
|                )); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     this.currentTest = 0; | ||||
|     this.logger = new Test.Unit.Logger(this.options.testLog); | ||||
|     setTimeout(this.runTests.bind(this), 1000); | ||||
|   }, | ||||
|   parseResultsURLQueryParameter: function() { | ||||
|     return window.location.search.parseQuery()["resultsURL"]; | ||||
|   }, | ||||
|   parseTestsQueryParameter: function(){ | ||||
|     if (window.location.search.parseQuery()["tests"]){ | ||||
|         return window.location.search.parseQuery()["tests"].split(','); | ||||
|     }; | ||||
|   }, | ||||
|   // Returns: | ||||
|   //  "ERROR" if there was an error, | ||||
|   //  "FAILURE" if there was a failure, or | ||||
|   //  "SUCCESS" if there was neither | ||||
|   getResult: function() { | ||||
|     var hasFailure = false; | ||||
|     for(var i=0;i<this.tests.length;i++) { | ||||
|       if (this.tests[i].errors > 0) { | ||||
|         return "ERROR"; | ||||
|       } | ||||
|       if (this.tests[i].failures > 0) { | ||||
|         hasFailure = true; | ||||
|       } | ||||
|     } | ||||
|     if (hasFailure) { | ||||
|       return "FAILURE"; | ||||
|     } else { | ||||
|       return "SUCCESS"; | ||||
|     } | ||||
|   }, | ||||
|   postResults: function() { | ||||
|     if (this.options.resultsURL) { | ||||
|       new Ajax.Request(this.options.resultsURL,  | ||||
|         { method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false }); | ||||
|     } | ||||
|   }, | ||||
|   runTests: function() { | ||||
|     var test = this.tests[this.currentTest]; | ||||
|     if (!test) { | ||||
|       // finished! | ||||
|       this.postResults(); | ||||
|       this.logger.summary(this.summary()); | ||||
|       return; | ||||
|     } | ||||
|     if(!test.isWaiting) { | ||||
|       this.logger.start(test.name); | ||||
|     } | ||||
|     test.run(); | ||||
|     if(test.isWaiting) { | ||||
|       this.logger.message("Waiting for " + test.timeToWait + "ms"); | ||||
|       setTimeout(this.runTests.bind(this), test.timeToWait || 1000); | ||||
|     } else { | ||||
|       this.logger.finish(test.status(), test.summary()); | ||||
|       this.currentTest++; | ||||
|       // tail recursive, hopefully the browser will skip the stackframe | ||||
|       this.runTests(); | ||||
|     } | ||||
|   }, | ||||
|   summary: function() { | ||||
|     var assertions = 0; | ||||
|     var failures = 0; | ||||
|     var errors = 0; | ||||
|     var messages = []; | ||||
|     for(var i=0;i<this.tests.length;i++) { | ||||
|       assertions +=   this.tests[i].assertions; | ||||
|       failures   +=   this.tests[i].failures; | ||||
|       errors     +=   this.tests[i].errors; | ||||
|     } | ||||
|     return ( | ||||
|       (this.options.context ? this.options.context + ': ': '') +  | ||||
|       this.tests.length + " tests, " +  | ||||
|       assertions + " assertions, " +  | ||||
|       failures   + " failures, " + | ||||
|       errors     + " errors"); | ||||
|   } | ||||
| } | ||||
|  | ||||
| Test.Unit.Assertions = Class.create(); | ||||
| Test.Unit.Assertions.prototype = { | ||||
|   initialize: function() { | ||||
|     this.assertions = 0; | ||||
|     this.failures   = 0; | ||||
|     this.errors     = 0; | ||||
|     this.messages   = []; | ||||
|   }, | ||||
|   summary: function() { | ||||
|     return ( | ||||
|       this.assertions + " assertions, " +  | ||||
|       this.failures   + " failures, " + | ||||
|       this.errors     + " errors" + "\n" + | ||||
|       this.messages.join("\n")); | ||||
|   }, | ||||
|   pass: function() { | ||||
|     this.assertions++; | ||||
|   }, | ||||
|   fail: function(message) { | ||||
|     this.failures++; | ||||
|     this.messages.push("Failure: " + message); | ||||
|   }, | ||||
|   info: function(message) { | ||||
|     this.messages.push("Info: " + message); | ||||
|   }, | ||||
|   error: function(error) { | ||||
|     this.errors++; | ||||
|     this.messages.push(error.name + ": "+ error.message + "(" + Test.Unit.inspect(error) +")"); | ||||
|   }, | ||||
|   status: function() { | ||||
|     if (this.failures > 0) return 'failed'; | ||||
|     if (this.errors > 0) return 'error'; | ||||
|     return 'passed'; | ||||
|   }, | ||||
|   assert: function(expression) { | ||||
|     var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"'; | ||||
|     try { expression ? this.pass() :  | ||||
|       this.fail(message); } | ||||
|     catch(e) { this.error(e); } | ||||
|   }, | ||||
|   assertEqual: function(expected, actual) { | ||||
|     var message = arguments[2] || "assertEqual"; | ||||
|     try { (expected == actual) ? this.pass() : | ||||
|       this.fail(message + ': expected "' + Test.Unit.inspect(expected) +  | ||||
|         '", actual "' + Test.Unit.inspect(actual) + '"'); } | ||||
|     catch(e) { this.error(e); } | ||||
|   }, | ||||
|   assertInspect: function(expected, actual) { | ||||
|     var message = arguments[2] || "assertInspect"; | ||||
|     try { (expected == actual.inspect()) ? this.pass() : | ||||
|       this.fail(message + ': expected "' + Test.Unit.inspect(expected) +  | ||||
|         '", actual "' + Test.Unit.inspect(actual) + '"'); } | ||||
|     catch(e) { this.error(e); } | ||||
|   }, | ||||
|   assertEnumEqual: function(expected, actual) { | ||||
|     var message = arguments[2] || "assertEnumEqual"; | ||||
|     try { $A(expected).length == $A(actual).length &&  | ||||
|       expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }) ? | ||||
|         this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) +  | ||||
|           ', actual ' + Test.Unit.inspect(actual)); } | ||||
|     catch(e) { this.error(e); } | ||||
|   }, | ||||
|   assertNotEqual: function(expected, actual) { | ||||
|     var message = arguments[2] || "assertNotEqual"; | ||||
|     try { (expected != actual) ? this.pass() :  | ||||
|       this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); } | ||||
|     catch(e) { this.error(e); } | ||||
|   }, | ||||
|   assertIdentical: function(expected, actual) {  | ||||
|     var message = arguments[2] || "assertIdentical";  | ||||
|     try { (expected === actual) ? this.pass() :  | ||||
|       this.fail(message + ': expected "' + Test.Unit.inspect(expected) +   | ||||
|         '", actual "' + Test.Unit.inspect(actual) + '"'); }  | ||||
|     catch(e) { this.error(e); }  | ||||
|   }, | ||||
|   assertNotIdentical: function(expected, actual) {  | ||||
|     var message = arguments[2] || "assertNotIdentical";  | ||||
|     try { !(expected === actual) ? this.pass() :  | ||||
|       this.fail(message + ': expected "' + Test.Unit.inspect(expected) +   | ||||
|         '", actual "' + Test.Unit.inspect(actual) + '"'); }  | ||||
|     catch(e) { this.error(e); }  | ||||
|   }, | ||||
|   assertNull: function(obj) { | ||||
|     var message = arguments[1] || 'assertNull' | ||||
|     try { (obj==null) ? this.pass() :  | ||||
|       this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); } | ||||
|     catch(e) { this.error(e); } | ||||
|   }, | ||||
|   assertMatch: function(expected, actual) { | ||||
|     var message = arguments[2] || 'assertMatch'; | ||||
|     var regex = new RegExp(expected); | ||||
|     try { (regex.exec(actual)) ? this.pass() : | ||||
|       this.fail(message + ' : regex: "' +  Test.Unit.inspect(expected) + ' did not match: ' + Test.Unit.inspect(actual) + '"'); } | ||||
|     catch(e) { this.error(e); } | ||||
|   }, | ||||
|   assertHidden: function(element) { | ||||
|     var message = arguments[1] || 'assertHidden'; | ||||
|     this.assertEqual("none", element.style.display, message); | ||||
|   }, | ||||
|   assertNotNull: function(object) { | ||||
|     var message = arguments[1] || 'assertNotNull'; | ||||
|     this.assert(object != null, message); | ||||
|   }, | ||||
|   assertType: function(expected, actual) { | ||||
|     var message = arguments[2] || 'assertType'; | ||||
|     try {  | ||||
|       (actual.constructor == expected) ? this.pass() :  | ||||
|       this.fail(message + ': expected "' + Test.Unit.inspect(expected) +   | ||||
|         '", actual "' + (actual.constructor) + '"'); } | ||||
|     catch(e) { this.error(e); } | ||||
|   }, | ||||
|   assertNotOfType: function(expected, actual) { | ||||
|     var message = arguments[2] || 'assertNotOfType'; | ||||
|     try {  | ||||
|       (actual.constructor != expected) ? this.pass() :  | ||||
|       this.fail(message + ': expected "' + Test.Unit.inspect(expected) +   | ||||
|         '", actual "' + (actual.constructor) + '"'); } | ||||
|     catch(e) { this.error(e); } | ||||
|   }, | ||||
|   assertInstanceOf: function(expected, actual) { | ||||
|     var message = arguments[2] || 'assertInstanceOf'; | ||||
|     try {  | ||||
|       (actual instanceof expected) ? this.pass() :  | ||||
|       this.fail(message + ": object was not an instance of the expected type"); } | ||||
|     catch(e) { this.error(e); }  | ||||
|   }, | ||||
|   assertNotInstanceOf: function(expected, actual) { | ||||
|     var message = arguments[2] || 'assertNotInstanceOf'; | ||||
|     try {  | ||||
|       !(actual instanceof expected) ? this.pass() :  | ||||
|       this.fail(message + ": object was an instance of the not expected type"); } | ||||
|     catch(e) { this.error(e); }  | ||||
|   }, | ||||
|   assertRespondsTo: function(method, obj) { | ||||
|     var message = arguments[2] || 'assertRespondsTo'; | ||||
|     try { | ||||
|       (obj[method] && typeof obj[method] == 'function') ? this.pass() :  | ||||
|       this.fail(message + ": object doesn't respond to [" + method + "]"); } | ||||
|     catch(e) { this.error(e); } | ||||
|   }, | ||||
|   assertReturnsTrue: function(method, obj) { | ||||
|     var message = arguments[2] || 'assertReturnsTrue'; | ||||
|     try { | ||||
|       var m = obj[method]; | ||||
|       if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)]; | ||||
|       m() ? this.pass() :  | ||||
|       this.fail(message + ": method returned false"); } | ||||
|     catch(e) { this.error(e); } | ||||
|   }, | ||||
|   assertReturnsFalse: function(method, obj) { | ||||
|     var message = arguments[2] || 'assertReturnsFalse'; | ||||
|     try { | ||||
|       var m = obj[method]; | ||||
|       if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)]; | ||||
|       !m() ? this.pass() :  | ||||
|       this.fail(message + ": method returned true"); } | ||||
|     catch(e) { this.error(e); } | ||||
|   }, | ||||
|   assertRaise: function(exceptionName, method) { | ||||
|     var message = arguments[2] || 'assertRaise'; | ||||
|     try {  | ||||
|       method(); | ||||
|       this.fail(message + ": exception expected but none was raised"); } | ||||
|     catch(e) { | ||||
|       ((exceptionName == null) || (e.name==exceptionName)) ? this.pass() : this.error(e);  | ||||
|     } | ||||
|   }, | ||||
|   assertElementsMatch: function() { | ||||
|     var expressions = $A(arguments), elements = $A(expressions.shift()); | ||||
|     if (elements.length != expressions.length) { | ||||
|       this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions'); | ||||
|       return false; | ||||
|     } | ||||
|     elements.zip(expressions).all(function(pair, index) { | ||||
|       var element = $(pair.first()), expression = pair.last(); | ||||
|       if (element.match(expression)) return true; | ||||
|       this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect()); | ||||
|     }.bind(this)) && this.pass(); | ||||
|   }, | ||||
|   assertElementMatches: function(element, expression) { | ||||
|     this.assertElementsMatch([element], expression); | ||||
|   }, | ||||
|   benchmark: function(operation, iterations) { | ||||
|     var startAt = new Date(); | ||||
|     (iterations || 1).times(operation); | ||||
|     var timeTaken = ((new Date())-startAt); | ||||
|     this.info((arguments[2] || 'Operation') + ' finished ' +  | ||||
|        iterations + ' iterations in ' + (timeTaken/1000)+'s' ); | ||||
|     return timeTaken; | ||||
|   }, | ||||
|   _isVisible: function(element) { | ||||
|     element = $(element); | ||||
|     if(!element.parentNode) return true; | ||||
|     this.assertNotNull(element); | ||||
|     if(element.style && Element.getStyle(element, 'display') == 'none') | ||||
|       return false; | ||||
|      | ||||
|     return this._isVisible(element.parentNode); | ||||
|   }, | ||||
|   assertNotVisible: function(element) { | ||||
|     this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1])); | ||||
|   }, | ||||
|   assertVisible: function(element) { | ||||
|     this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1])); | ||||
|   }, | ||||
|   benchmark: function(operation, iterations) { | ||||
|     var startAt = new Date(); | ||||
|     (iterations || 1).times(operation); | ||||
|     var timeTaken = ((new Date())-startAt); | ||||
|     this.info((arguments[2] || 'Operation') + ' finished ' +  | ||||
|        iterations + ' iterations in ' + (timeTaken/1000)+'s' ); | ||||
|     return timeTaken; | ||||
|   } | ||||
| } | ||||
|  | ||||
| Test.Unit.Testcase = Class.create(); | ||||
| Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), { | ||||
|   initialize: function(name, test, setup, teardown) { | ||||
|     Test.Unit.Assertions.prototype.initialize.bind(this)(); | ||||
|     this.name           = name; | ||||
|      | ||||
|     if(typeof test == 'string') { | ||||
|       test = test.gsub(/(\.should[^\(]+\()/,'#{0}this,'); | ||||
|       test = test.gsub(/(\.should[^\(]+)\(this,\)/,'#{1}(this)'); | ||||
|       this.test = function() { | ||||
|         eval('with(this){'+test+'}'); | ||||
|       } | ||||
|     } else { | ||||
|       this.test = test || function() {}; | ||||
|     } | ||||
|      | ||||
|     this.setup          = setup || function() {}; | ||||
|     this.teardown       = teardown || function() {}; | ||||
|     this.isWaiting      = false; | ||||
|     this.timeToWait     = 1000; | ||||
|   }, | ||||
|   wait: function(time, nextPart) { | ||||
|     this.isWaiting = true; | ||||
|     this.test = nextPart; | ||||
|     this.timeToWait = time; | ||||
|   }, | ||||
|   run: function() { | ||||
|     try { | ||||
|       try { | ||||
|         if (!this.isWaiting) this.setup.bind(this)(); | ||||
|         this.isWaiting = false; | ||||
|         this.test.bind(this)(); | ||||
|       } finally { | ||||
|         if(!this.isWaiting) { | ||||
|           this.teardown.bind(this)(); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     catch(e) { this.error(e); } | ||||
|   } | ||||
| }); | ||||
|  | ||||
| // *EXPERIMENTAL* BDD-style testing to please non-technical folk | ||||
| // This draws many ideas from RSpec http://rspec.rubyforge.org/ | ||||
|  | ||||
| Test.setupBDDExtensionMethods = function(){ | ||||
|   var METHODMAP = { | ||||
|     shouldEqual:     'assertEqual', | ||||
|     shouldNotEqual:  'assertNotEqual', | ||||
|     shouldEqualEnum: 'assertEnumEqual', | ||||
|     shouldBeA:       'assertType', | ||||
|     shouldNotBeA:    'assertNotOfType', | ||||
|     shouldBeAn:      'assertType', | ||||
|     shouldNotBeAn:   'assertNotOfType', | ||||
|     shouldBeNull:    'assertNull', | ||||
|     shouldNotBeNull: 'assertNotNull', | ||||
|      | ||||
|     shouldBe:        'assertReturnsTrue', | ||||
|     shouldNotBe:     'assertReturnsFalse', | ||||
|     shouldRespondTo: 'assertRespondsTo' | ||||
|   }; | ||||
|   Test.BDDMethods = {}; | ||||
|   for(m in METHODMAP) { | ||||
|     Test.BDDMethods[m] = eval( | ||||
|       'function(){'+ | ||||
|       'var args = $A(arguments);'+ | ||||
|       'var scope = args.shift();'+ | ||||
|       'scope.'+METHODMAP[m]+'.apply(scope,(args || []).concat([this])); }'); | ||||
|   } | ||||
|   [Array.prototype, String.prototype, Number.prototype].each( | ||||
|     function(p){ Object.extend(p, Test.BDDMethods) } | ||||
|   ); | ||||
| } | ||||
|  | ||||
| Test.context = function(name, spec, log){ | ||||
|   Test.setupBDDExtensionMethods(); | ||||
|    | ||||
|   var compiledSpec = {}; | ||||
|   var titles = {}; | ||||
|   for(specName in spec) { | ||||
|     switch(specName){ | ||||
|       case "setup": | ||||
|       case "teardown": | ||||
|         compiledSpec[specName] = spec[specName]; | ||||
|         break; | ||||
|       default: | ||||
|         var testName = 'test'+specName.gsub(/\s+/,'-').camelize(); | ||||
|         var body = spec[specName].toString().split('\n').slice(1); | ||||
|         if(/^\{/.test(body[0])) body = body.slice(1); | ||||
|         body.pop(); | ||||
|         body = body.map(function(statement){  | ||||
|           return statement.strip() | ||||
|         }); | ||||
|         compiledSpec[testName] = body.join('\n'); | ||||
|         titles[testName] = specName; | ||||
|     } | ||||
|   } | ||||
|   new Test.Unit.Runner(compiledSpec, { titles: titles, testLog: log || 'testlog', context: name }); | ||||
| }; | ||||
| @@ -1,192 +0,0 @@ | ||||
| var zIndex = 1; | ||||
| function addLoadEvent(func) { | ||||
| 	var oldonload = window.onload; | ||||
| 	if (typeof window.onload != 'function') { | ||||
| 		window.onload = func; | ||||
| 	} else { | ||||
| 		window.onload = function() { | ||||
| 			if (oldonload) { | ||||
| 				oldonload(); | ||||
| 			} | ||||
| 			func; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 	 | ||||
| 	 | ||||
| var activeNode; | ||||
|  | ||||
| function startList() { | ||||
| 	if (document.getElementById('menubeans')) { | ||||
| 		navRoot = document.getElementById('menubeans'); | ||||
| 		for (i = 0; i < navRoot.childNodes.length; i++) { | ||||
| 			node = navRoot.childNodes[i]; | ||||
| 			if (node.nodeName == 'LI') { | ||||
| 				if (node.className == 'active') { | ||||
| 					activeNode = i; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		for (i = 0; i < navRoot.childNodes.length; i++) { | ||||
| 			node = navRoot.childNodes[i]; | ||||
| 			if (node.nodeName == 'LI') { | ||||
| 				node.onmouseover = function() { | ||||
| 					navRoot.childNodes[activeNode].className = ''; | ||||
| 					this.className = 'active'; | ||||
| 				} | ||||
|   				node.onmouseout = function() { | ||||
| 					this.className = ''; | ||||
| 					navRoot.childNodes[activeNode].className = 'active'; | ||||
| 				} | ||||
| 				node.onmousedown = function() { | ||||
| 					navRoot.childNodes[activeNode].className = ''; | ||||
| 					this.className = 'active'; | ||||
| 					activeNode = this.id - 1; | ||||
| 				} | ||||
| 	 | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| var activeNN = '2-li-0'; | ||||
| function chActiveMenu(newk){ | ||||
| 	// find active node | ||||
| 	//alert("value for AN" + activeNN); | ||||
| 	//alert("value for newk" + newk); | ||||
| 	/* set old one to nothing */ | ||||
| 	document.getElementById(activeNN).className = ''; | ||||
| 	/* set new one to active */ | ||||
| 	document.getElementById(newk).className = 'active'; | ||||
| 	activeNN = newk; | ||||
| } | ||||
| function resetForm(fobj){ | ||||
| 	fobj.reset(); | ||||
| 	closeTree(); | ||||
| } | ||||
|  | ||||
| function getFormVals(fobj) {  | ||||
| 	var str = '';  | ||||
| 	var ft = '';  | ||||
| 	var fv = '';  | ||||
| 	var fn = '';  | ||||
| 	var els = '';  | ||||
| 	for(var i = 0;i < fobj.elements.length;i++) {  | ||||
| 		els = fobj.elements[i];  | ||||
| 		ft = els.title;  | ||||
| 		fv = els.value;  | ||||
| 		fn = els.name;  | ||||
| 		switch(els.type) {  | ||||
| 			case "text":  | ||||
| 			case "hidden":  | ||||
| 			case "password":  | ||||
| 			case "textarea":  | ||||
| 			// is it a required field?  | ||||
| 			if(encodeURI(ft) == "required" && encodeURI(fv).length < 1) {  | ||||
| 			alert(fn + ' is a required field, please complete.');   | ||||
| 			els.focus();   | ||||
| 				return false;   | ||||
| 			}   | ||||
| 			str += fn + "=" + encodeURI(fv) + "&";   | ||||
| 			break;    | ||||
|     | ||||
| 			case "checkbox":   | ||||
| 			case "radio":   | ||||
| 				if(els.checked) str += fn + "=" + encodeURI(fv) + "&";   | ||||
| 				break;       | ||||
|     | ||||
| 			case "select-one":   | ||||
| 				str += fn + "=" +   | ||||
| 				els.options[els.selectedIndex].value + "&";   | ||||
| 				break;   | ||||
| 		} // switch   | ||||
| 	} // for   | ||||
| 	str = str.substr(0,(str.length - 1));   | ||||
| 	return str;   | ||||
| } | ||||
|  | ||||
|  | ||||
| function killChildren(domE){ | ||||
| 	for(var i = 0; i<domE.childNodes.length; i++){ | ||||
| 		domE.removeChild(domE.childNodes[i]); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| function getCmdWindow(){ | ||||
| 	var d = ''; | ||||
| 	var dob = ''; | ||||
| 	d = document.getElementById('cmd'); | ||||
| 	if(!d){ | ||||
| 		d = winNewWin('Command Output'); | ||||
| 		var foo = document.createElement('div'); | ||||
| 		foo.id = 'cmd'; | ||||
| 		foo.innerHTML = ' '; | ||||
| 		d.appendChild(foo); | ||||
| 		d = foo; | ||||
| 	}else{ | ||||
| 		killChildren(d); | ||||
| 	} | ||||
| 	return d; | ||||
| } | ||||
|  | ||||
| function doForm(fobj){ | ||||
| 	/* make a new place for our form to appear */ | ||||
| 	var d = getCmdWindow(); | ||||
| 	/* get all form data */ | ||||
| 	var data = getFormVals(fobj); | ||||
| 	/* noew request it all */ | ||||
| 	/* alert(data); */ | ||||
| 	new Ajax.Updater(d, 'parse.php',  | ||||
| 		{method:'post', | ||||
| 		postBody: data, | ||||
| 		evalScripts: true | ||||
| 		}); | ||||
| 	resetForm(fobj); | ||||
| } | ||||
|  | ||||
| function newPane(turl, tobj, title, newk){ | ||||
| 	var el = winNewWin(title); | ||||
| 	new Ajax.Updater(el, turl,  | ||||
| 		{evalScripts:true});  | ||||
| 	chActiveMenu(newk); | ||||
| } | ||||
|  | ||||
| function newBack(turl, tobj, title, newk){ | ||||
| 	new Ajax.Updater(tobj, turl,  | ||||
| 		{evalScripts:true});  | ||||
| 	chActiveMenu(newk); | ||||
| } | ||||
|  | ||||
| function firstLoad(){ | ||||
| 	var turl = 'xcattop.php'; | ||||
| 	new Ajax.Updater('content', turl,  | ||||
| 		{evalScripts:true});  | ||||
| } | ||||
|  | ||||
| function newPane2(turl, tobj, title){ | ||||
| 	var el = winNewWin(title); | ||||
| 	new Ajax.Updater(el, turl,  | ||||
| 		{evalScripts:true});  | ||||
| 	 | ||||
| } | ||||
|  | ||||
|  | ||||
| function getNodeStatus(divID){ | ||||
| 	var id = 'grid' + divID; | ||||
| 	var el = document.getElementById(id);	 | ||||
| 	new Ajax.Updater(el, 'pingNode.php?n=' + divID, {evalScripts: true}); | ||||
| } | ||||
|  | ||||
| function chNodeStatus(node, status){ | ||||
| 	var id = 'grid' + node; | ||||
| 	var el = document.getElementById(id); | ||||
| 	el.className = status; | ||||
| 	el.innerHTML = node; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @@ -20,6 +20,7 @@ echo <<<EOS | ||||
| 	<td width="88" align=left><input type="checkbox" name="chk_node_all" id="chk_node_all">Groups</td> | ||||
| 	<td>HW Type</td><td>OS</td><td>Mode</td><td>Status</td><td>HW Ctrl Pt</td><td>Comment</td> | ||||
| </tr> | ||||
|  | ||||
| EOS; | ||||
| 	return; | ||||
| } | ||||
| @@ -44,7 +45,7 @@ $plusgif = "$TOPDIR/images/plus-sign.gif"; | ||||
| <span | ||||
| 	title="$exTxt" | ||||
| 	id="img_gr_$nodeGroupName" | ||||
| 	onclick="XCATui.updateNodeList('$nodeGroupName')" | ||||
| 	onclick="GroupNodeTableUpdater.updateNodeList('$nodeGroupName')" | ||||
| 	ondblclick="toggleSection(this,'div_$nodeGroupName')"> | ||||
| 	<img src="$plusgif" id="div_$nodeGroupName-im" name="div_$nodeGroupName-im"> | ||||
| EOS; | ||||
| @@ -71,66 +72,52 @@ echo <<<EOE | ||||
| 	<td> </td> | ||||
| 	<td> </td> | ||||
| 	</tr> | ||||
| 	<tr style="display:none"><td colspan=7><div id=div_$nodeGroupName style="display:none"></div></td></tr> | ||||
| 	<tr><td colspan=7><div id=div_$nodeGroupName style="display:none"></div></td></tr> | ||||
| EOE; | ||||
| return; | ||||
| } | ||||
|  | ||||
| // This is used by nodes_by_group.php | ||||
| 	/** | ||||
| 	 * @param XCATNodeGroup	nodeGroup	The node group for which we want to generate the html. | ||||
| 	 * @param An array of node groups, each of which contains an array of attr/value pairs | ||||
| 	 * returns the table that contains all the nodes information of that group | ||||
| 	 */ | ||||
| function getNodeGroupSection($nodeGroup) { | ||||
| 		$imagedir = 'images'; | ||||
| 		$right_arrow_gif = $imagedir . "/grey_arrow_r.gif"; | ||||
| 		$left_arrow_gif = $imagedir . "/grey_arrow_l.gif"; | ||||
| function getNodeGroupSection($group, $nodes) { | ||||
| 	global $TOPDIR; | ||||
| 	$imagedir = "$TOPDIR/images"; | ||||
| 	$right_arrow_gif = $imagedir . "/grey_arrow_r.gif"; | ||||
| 	$left_arrow_gif = $imagedir . "/grey_arrow_l.gif"; | ||||
|  | ||||
| 		$html .= <<<EOS | ||||
| 		<table id=" | ||||
| EOS; | ||||
| 		$html .= $nodeGroup->getName(); | ||||
| 		$html .= <<<EOS | ||||
| 				" width='100%' cellpadding=0 cellspacing=1 border=0> | ||||
| EOS; | ||||
| 	$html .= "<table id='$group' width='100%' cellpadding=0 cellspacing=1 border=0>\n"; | ||||
|  | ||||
| 		$nodes = $nodeGroup->getNodes(); | ||||
| 	foreach($nodes as $nodeName => $attrs) { | ||||
| 		$html .= GroupNodeTable::getNodeTableRow($nodeName, $attrs); | ||||
| 	} | ||||
|  | ||||
| 		foreach($nodes as $nodeName => $node) { | ||||
| 			$html .= GroupNodeTable::getNodeTableRow($node); | ||||
| 		} | ||||
|  | ||||
| 		$html .= "<TR bgcolor=\"#FFFF66\"><TD colspan=9 align=\"right\"><image src=\"$left_arrow_gif\" alt=\"Previous page\">    <image src=\"$right_arrow_gif\" alt=\"Next page\">  </TD></TR>"; | ||||
| 		$html .= <<<EOS | ||||
| 		</table> | ||||
| EOS; | ||||
| 	$html .= "<TR bgcolor='#FFFF66'><TD colspan=9 align=right><image src='$left_arrow_gif' alt='Previous page'>    <image src='$right_arrow_gif' alt='Next page'>  </TD></TR>\n"; | ||||
| 	$html .= "</table>\n"; | ||||
|  | ||||
| 	return $html; | ||||
| } | ||||
|  | ||||
| 	/** | ||||
| 	 * @param XCATNode	node	The node for which we want to generate the html. | ||||
| 	 * @param The node for which we want to generate the html. | ||||
| 	 */ | ||||
| function getNodeTableRow($node) { | ||||
| function getNodeTableRow($nodeName, $attrs) { | ||||
| 	$html = "<tr bgcolor='#FFFF66' class=indent>\n" . | ||||
| 			"<td width=89><input type=checkbox name='node_$nodeName' >$nodeName</td>\n" . | ||||
| 			"<td width=38><div align=center>" . $attrs['arch'] . "</div></td>\n" . | ||||
| 			"<td width=22><div align=center>" . $attrs['osversion'] . "</div></td>\n" . | ||||
| 			"<td width=43><div align=center>" . $attrs['mode'] . "</div></td>\n"; | ||||
|  | ||||
| 		$imagedir = 'images'; | ||||
| 	$stat = 'unknown';   //todo: implement | ||||
| 	$img_string = '<img src="' . getStatusImage($stat) . '">'; | ||||
|  | ||||
| 		//echo $node->getName(); | ||||
| 		$html = "<tr bgcolor=\"#FFFF66\" class=\"indent\"> | ||||
| 				<td width=89><input type=\"checkbox\" name=\"node_" .$node->getName(). "\" />" .$node->getName(). "</td>" . | ||||
| 				"<td width=38><div align=center>" . $node->getHwType(). "</div></td>". | ||||
| 				"<td width=22><div align=center>" . $node->getOs(). "</div></td>". | ||||
| 				"<td width=43><div align=center>" . $node->getMode(). "</div></td>"; | ||||
| 	$html .= "<td width=43><div align=center>" . $img_string . "</div></td>". | ||||
| 			"<td width=85><div align=center>" . $attrs['power'] . "</div></td>". | ||||
| 			"<td width=71><div align=center>" . $attrs['comment'] . "</div></td></tr>"; | ||||
|  | ||||
| 		$stat = $node->getStatus(); | ||||
| 		$img_string = '<img src="' . getStatusImage($stat) . '">'; | ||||
|  | ||||
| 		$html .= "<td width=43><div align=center>" . $img_string . "</div></td>". | ||||
| 				"<td width=85><div align=center>" . $node->getHwCtrlPt(). "</div></td>". | ||||
| 				"<td width=71><div align=center>" . $node->getComment(). "</div></td></tr>"; | ||||
|  | ||||
| EOS; | ||||
| 		return $html; | ||||
| 	return $html; | ||||
| 	} | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| var XCATui = {}; | ||||
| var GroupNodeTableUpdater = {}; | ||||
| 
 | ||||
| XCATui.updateCommandResult = function() { | ||||
| GroupNodeTableUpdater.updateCommandResult = function() { | ||||
| 	var commandQueryId = "commandQuery"; | ||||
| 	var copyChkBoxId = "copyChkBox"; | ||||
| 	var nodenameHiddenTxtId = "nodename"; | ||||
| @@ -71,7 +71,7 @@ XCATui.updateCommandResult = function() { | ||||
| /** | ||||
|  * Hides/shows the nodes in a node group table. | ||||
|  */ | ||||
| XCATui.toggleSection = function(nodeGroupName) { | ||||
| GroupNodeTableUpdater.toggleSection = function(nodeGroupName) { | ||||
| 	var tableId = "div_" + nodeGroupName; | ||||
| 	var imageId = tableId + '-im'; | ||||
| 	var expandSpanId = "img_gr_" + nodeGroupName; | ||||
| @@ -101,40 +101,40 @@ XCATui.toggleSection = function(nodeGroupName) { | ||||
| 	return true; | ||||
| }; | ||||
| 
 | ||||
| XCATui.getFailureSpanHTML = function(nodeGroupName) { | ||||
| GroupNodeTableUpdater.getFailureSpanHTML = function(nodeGroupName) { | ||||
| 	var spanId = "nodegroup_" + nodeGroupName + "_failure"; | ||||
| 	var html = '<span id="' + spanId + '">There was a problem loading the node for the group ' + nodeGroupName + '</span>'; | ||||
| 	return html; | ||||
| } | ||||
| 
 | ||||
| XCATui.getLoadingSpanHTML = function(nodeGroupName) { | ||||
| GroupNodeTableUpdater.getLoadingSpanHTML = function(nodeGroupName) { | ||||
| 	var spanId = "nodegroup_" + nodeGroupName + "_loading"; | ||||
| 	var html = '<span id="' + spanId + '" style="padding-left: 0.5em; display: none;"><img alt="Loading ..." src="../images/ajax-loader.gif" />Loading ...</span>'; | ||||
| 	return html; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * This is the onCreate callback for the AJAX request made in XCATui.updateNodeList. | ||||
|  * This is the onCreate callback for the AJAX request made in GroupNodeTableUpdater.updateNodeList. | ||||
|  * It updates the interface to show that the request is loading. | ||||
|  * See http://www.prototypejs.org/api/ajax/options
 | ||||
|  */ | ||||
| XCATui.updateNodeListLoading = function(nodeGroupName) { | ||||
| GroupNodeTableUpdater.updateNodeListLoading = function(nodeGroupName) { | ||||
| 
 | ||||
| 	var spanId = 'img_gr_' + nodeGroupName; | ||||
| 	new Insertion.Bottom(spanId, XCATui.getLoadingSpanHTML(nodeGroupName)); | ||||
| 	new Insertion.Bottom(spanId, GroupNodeTableUpdater.getLoadingSpanHTML(nodeGroupName)); | ||||
| 
 | ||||
| 	var loadingSpanId = "nodegroup_" + nodeGroupName + "_loading"; | ||||
| 	new Effect.Appear(loadingSpanId); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * This is the onFailure callback for the AJAX request made in XCATui.updateNodeList. | ||||
|  * This is the onFailure callback for the AJAX request made in GroupNodeTableUpdater.updateNodeList. | ||||
|  * It updates the interface to show that the request failed. | ||||
|  * See http://www.prototypejs.org/api/ajax/options
 | ||||
|  */ | ||||
| XCATui.updateNodeListFailure = function(nodeGroupName) { | ||||
| GroupNodeTableUpdater.updateNodeListFailure = function(nodeGroupName) { | ||||
| 	var spanId = 'img_gr_' + nodeGroupName; | ||||
| 	new Insertion.Bottom(spanId, XCATui.getFailureSpanHTML(nodeGroupName)); | ||||
| 	new Insertion.Bottom(spanId, GroupNodeTableUpdater.getFailureSpanHTML(nodeGroupName)); | ||||
| 
 | ||||
| 	var failureSpanId = "nodegroup_" + nodeGroupName + "_failure"; | ||||
| 	new Effect.Shake(failureSpanId); | ||||
| @@ -144,21 +144,21 @@ XCATui.updateNodeListFailure = function(nodeGroupName) { | ||||
|  * Add table rows representing nodes to the table that represents the node group | ||||
|  * identified by the given name. | ||||
|  */ | ||||
| XCATui.updateNodeList = function(nodeGroupName) { | ||||
| GroupNodeTableUpdater.updateNodeList = function(nodeGroupName) { | ||||
| 
 | ||||
| 	var tableId = "div_" + nodeGroupName; | ||||
| 	var imageId = tableId + '-im'; | ||||
| 	var expandSpanId = "img_gr_" + nodeGroupName; | ||||
| 
 | ||||
| 	var tableObj = document.getElementById(tableId);   //$(tableId);
 | ||||
| 	var tableObj = $(tableId); | ||||
| 
 | ||||
| 	if(null == tableObj) { | ||||
| 		alert('Error: section ' + tableId + ' not found.'); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	var imageTag = document.getElementById(imageId);   //$(imageId);
 | ||||
| 	var expandSpanObj = document.getElementById(expandSpanId);   //$(expandSpanId);
 | ||||
| 	var imageTag = $(imageId); | ||||
| 	var expandSpanObj = $(expandSpanId); | ||||
| 
 | ||||
| 	if(!tableObj.style.display || tableObj.style.display == 'inline') {// currently visible
 | ||||
| 
 | ||||
| @@ -178,17 +178,17 @@ XCATui.updateNodeList = function(nodeGroupName) { | ||||
| 
 | ||||
| 		//var URL = "webservice.php?method=getXCATNodeRows&nodeGroupName=" + encodeURIComponent(nodeGroupName);
 | ||||
| 
 | ||||
| 		alert('About to call Ajax.Updater'); | ||||
| 		//alert('About to call Ajax.Updater');
 | ||||
| 		new Ajax.Updater(target, URL, { | ||||
| 			method: 'post', parameters: pars, | ||||
| 			onCreate: function() { XCATui.updateNodeListLoading(nodeGroupName) }, // Needs Prototype 1.5.1
 | ||||
| 			onFailure: function() {XCATui.updateNodeListFailure(nodeGroupName) }, | ||||
| 			onCreate: function() { GroupNodeTableUpdater.updateNodeListLoading(nodeGroupName) }, // Needs Prototype 1.5.1
 | ||||
| 			onFailure: function() {GroupNodeTableUpdater.updateNodeListFailure(nodeGroupName) }, | ||||
| 			onComplete: function() {new Effect.Fade("nodegroup_" + nodeGroupName + "_loading")} | ||||
| 		}); | ||||
| 
 | ||||
| 		// the inner table is currently invisible
 | ||||
| 		tableObj.style.display = 'inline'; | ||||
| 		alert('Back from Ajax.Updater'); | ||||
| 		//alert('Back from Ajax.Updater');
 | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| @@ -196,5 +196,5 @@ XCATui.updateNodeList = function(nodeGroupName) { | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 	//XCATui.toggleSection(nodeGroupName);
 | ||||
| 	//GroupNodeTableUpdater.toggleSection(nodeGroupName);
 | ||||
| } | ||||
| @@ -32,20 +32,24 @@ echo <<<EOS | ||||
|  | ||||
| EOS; | ||||
|  | ||||
| /* These are only needed for popup windows, so only need it for specific pages like dsh | ||||
| <script src="js_xcat/event.js" type="text/javascript"> </script> | ||||
| <script src="js_xcat/ui.js" type="text/javascript"> </script> | ||||
| <link href="css/xcattop.css" rel="stylesheet"> | ||||
| <link href="css/xcat.css" rel="stylesheet"> | ||||
| <link href="css/clickTree.css" rel="stylesheet"> | ||||
| <script src="js/windows.js" type="text/javascript"></script> | ||||
| <script src="js/clickTree.js" type="text/javascript"></script> | ||||
| <script src="js/prototype.js" type="text/javascript"></script> | ||||
| <script src="js/scriptaculous.js" type="text/javascript"></script> | ||||
| <script src="js/xcat.js" type="text/javascript"></script> | ||||
| <script src="js/effect.js" type="text/javascript"> </script> | ||||
| <link href="themes/default.css" rel="stylesheet" type="text/css"/> | ||||
| */ | ||||
| // These are only needed for popup windows, so only need it for specific pages like groups & dsh | ||||
| //echo "<script src='$TOPDIR/js_xcat/event.js' type='text/javascript'> </script>\n"; | ||||
| //echo "<script src='$TOPDIR/lib/GroupNodeTableUpdater.js' type='text/javascript'> </script>\n"; | ||||
|  | ||||
| //echo "<script src='$TOPDIR/js/prototype.js' type='text/javascript'></script>\n"; | ||||
| //echo "<script src='$TOPDIR/js/scriptaculous.js?load=effects' type='text/javascript'></script>\n"; | ||||
| //echo "<script src='$TOPDIR/js/effects.js' type='text/javascript'> </script>\n"; | ||||
|  | ||||
| //echo "<script src='$TOPDIR/js/window.js' type='text/javascript'></script>\n"; | ||||
| //echo "<link href='$TOPDIR/themes/default.css' rel='stylesheet' type='text/css'/>\n"; | ||||
|  | ||||
| //echo "<link href='$TOPDIR/css/xcattop.css' rel='stylesheet'>\n"; | ||||
| //echo "<link href='$TOPDIR/css/xcat.css' rel='stylesheet'>\n"; | ||||
|  | ||||
| //echo "<script src='$TOPDIR/js/windows.js' type='text/javascript'></script>\n"; | ||||
| //echo "<script src='$TOPDIR/js/clickTree.js' type='text/javascript'></script>\n"; | ||||
| //echo "<link href='$TOPDIR/css/clickTree.css' rel='stylesheet'>\n"; | ||||
|  | ||||
|  | ||||
| if ($stylesheets) { | ||||
| 	foreach ($stylesheets as $s) { | ||||
| @@ -419,13 +423,28 @@ function getPref($key) { //------------------------------------ | ||||
| } | ||||
|  | ||||
|  | ||||
| // Returns a list of some or all of the nodes in the cluster.  Pass in either a group name or node range, | ||||
| // or NULL for each to get all nodes.  Not finished. | ||||
| function getNodes($group, $noderange) { //------------------------------------ | ||||
| // Returns a list of some or all of the nodes in the cluster and some of their attributes. | ||||
| // Pass in a node range (or NULL to get all nodes) and an array of attribute names (or NULL for none). | ||||
| // Returns an array where each key is the node name and each value is an array of attr/value pairs. | ||||
| function getNodes($noderange, $attrs) { | ||||
| 	//my ($hostname, $type, $osname, $distro, $version, $mode, $status, $conport, $hcp, $nodeid, $pmethod, $location, $comment) = split(/:\|:/, $na); | ||||
| 	for ($i = 1; $i <= 10; $i++) { | ||||
| 		$nodes[] = array('hostname'=>"node$i.cluster.com", 'type'=>'x3655', 'osname'=>'Linux', 'distro'=>'RedHat', 'version'=>'4.5', 'status'=>1, | ||||
| 						'conport'=>$i, 'hcp'=>"node$i-bmc.cluster.com", 'nodeid'=>'', 'pmethod'=>'bmc', 'location'=>"frame=1 u=$", 'comment'=>''); | ||||
| 	//$nodes[] = array('hostname'=>"node$i.cluster.com", 'type'=>'x3655', 'osname'=>'Linux', 'distro'=>'RedHat', 'version'=>'4.5', 'status'=>1, 'conport'=>$i, 'hcp'=>"node$i-bmc.cluster.com", 'nodeid'=>'', 'pmethod'=>'bmc', 'location'=>"frame=1 u=$", 'comment'=>''); | ||||
| 	$nodes = array(); | ||||
| 	foreach ($attrs as $a) { | ||||
| 		$output = array(); | ||||
| 		//echo "<p>/bin/sudo nodels $noderange $a</p>\n"; | ||||
| 		runcmd("/bin/sudo nodels $noderange $a", 2, $output); | ||||
| 		foreach ($output as $line) { | ||||
| 			$vals = preg_split('/: */', $line);   // vals[0] will be the node name | ||||
| 			if (!$nodes[$vals[0]]) { $nodes[$vals[0]] = array(); } | ||||
| 			$attributes = & $nodes[$vals[0]]; | ||||
| 			if ($a == 'type') { | ||||
| 				$types = preg_split('/-/', $vals[1]); | ||||
| 				$attributes['osversion'] = $types[0]; | ||||
| 				$attributes['arch'] = $types[1]; | ||||
| 				$attributes['type'] = $types[2]; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return $nodes; | ||||
| } | ||||
|   | ||||
| @@ -7,9 +7,10 @@ require_once "$TOPDIR/lib/functions.php"; | ||||
| if (isAIX()) { $aixDisabled = 'disabled'; } | ||||
|  | ||||
| require_once("$TOPDIR/lib/GroupNodeTable.class.php"); | ||||
| require_once("$TOPDIR/lib/XCAT/XCATCommand/XCATCommandRunner.class.php"); | ||||
|  | ||||
| insertHeader('Groups', array('groups.css'), array("$TOPDIR/js_xcat/ui.js","$TOPDIR/js/prototype.js"), array('machines','groups')); | ||||
| insertHeader('Groups', array('groups.css'), | ||||
| 	array("$TOPDIR/lib/GroupNodeTableUpdater.js","$TOPDIR/js/prototype.js","$TOPDIR/js/scriptaculous.js?load=effects"), | ||||
| 	array('machines','groups')); | ||||
|  | ||||
| echo "<div id=content align=center>\n"; | ||||
|  | ||||
|   | ||||
| @@ -1,14 +1,11 @@ | ||||
| <?php | ||||
| $TOPDIR = '..'; | ||||
| require_once("$TOPDIR/lib/GroupNodeTable.class.php"); | ||||
| require_once("$TOPDIR/lib/XCAT/XCATCommand/XCATCommandRunner.class.php"); | ||||
|  | ||||
| $nodeGroupName = @$_REQUEST["nodeGroupName"]; | ||||
|  | ||||
| // Get all the nodes with node information of the group | ||||
| $xcmdr = new XCATCommandRunner(); | ||||
| $nodeGroup = $xcmdr->getXCATNodeByGroupName($nodeGroupName); | ||||
| echo GroupNodeTable::getNodeGroupSection($nodeGroup); | ||||
|  | ||||
| $nodes = getNodes($nodeGroupName, array('type')); | ||||
| echo GroupNodeTable::getNodeGroupSection($nodeGroupName, $nodes); | ||||
|  | ||||
| ?> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user