diff --git a/data/msfweb/public/javascripts/application.js b/data/msfweb/public/javascripts/application.js
index df528c4c68..553ff66add 100644
--- a/data/msfweb/public/javascripts/application.js
+++ b/data/msfweb/public/javascripts/application.js
@@ -168,7 +168,7 @@ function create_window_ajax(target_url, wid, wtitle, wwidth, wheight) {
* Height and width are fixed, should be working values in all cases.
*/
function openModuleWindow(mtype, refname, wtitle) {
- var mWin = create_window_ajax("/" + mtype + "/view?refname=" + refname, mtype + "-view-" + obtainWindowId(), wtitle, 500, 350);
+ var mWin = create_window_ajax("/" + mtype + "/view?refname=" + refname, mtype + "-view-" + obtainWindowId(), wtitle, 650, 350);
mWin.setDestroyOnClose();
mWin.showCenter();
}
diff --git a/data/msfweb/public/javascripts/debug.js b/data/msfweb/public/javascripts/debug.js
new file mode 100644
index 0000000000..3d8f338836
--- /dev/null
+++ b/data/msfweb/public/javascripts/debug.js
@@ -0,0 +1,137 @@
+var debugWindow = null;
+function debug(text, reverse) {
+ if (debugWindow == null)
+ return;
+
+ time = "-"; //new Date();
+ if (reverse) {
+ $('debug').innerHTML = time + " " + text + "
"+ $('debug').innerHTML;
+ debugWindow.getContent().scrollTop=0;
+ }
+ else {
+ $('debug').innerHTML += time + " " + text + "
";
+ debugWindow.getContent().scrollTop=10000; // Far away
+ }
+}
+
+function hideDebug() {
+ if (debugWindow) {
+ debugWindow.destroy();
+ debugWindow = null;
+ }
+}
+
+function showDebug(bShow) {
+ if (debugWindow == null) {
+ debugWindow = new Window('debug_window', {className: 'dialog',width:250, height:100, right:4, bottom:42, zIndex:1000, opacity:1, showEffect: Element.show, resizable: true, title: "Debug"})
+ debugWindow.getContent().innerHTML = "
";
+ date=new Date;
+ date.setMonth(date.getMonth()+3);
+
+ //debugWindow.setCookie(null, date);
+ }
+ if( typeof bShow == 'undefined' || bShow)debugWindow.show()
+}
+
+
+function clearDebug() {
+ if (debugWindow == null)
+ return;
+ $('debug').innerHTML = "";
+}
+
+/**
+ * document.createElement convenience wrapper
+ *
+ * The data parameter is an object that must have the "tag" key, containing
+ * a string with the tagname of the element to create. It can optionally have
+ * a "children" key which can be: a string, "data" object, or an array of "data"
+ * objects to append to this element as children. Any other key is taken as an
+ * attribute to be applied to this tag.
+ *
+ * Available under an MIT license:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * @param {Object} data The data representing the element to create
+ * @return {Element} The element created.
+ */
+function $E(data) {
+ var el;
+ if ('string'==typeof data) {
+ el=document.createTextNode(data);
+ } else {
+ //create the element
+ el=document.createElement(data.tag);
+ delete(data.tag);
+
+ //append the children
+ if ('undefined'!=typeof data.children) {
+ if ('string'==typeof data.children ||'undefined'==typeof data.children.length) {
+ //strings and single elements
+ el.appendChild($E(data.children));
+ } else {
+ //arrays of elements
+ for (var i=0, child=null; 'undefined'!=typeof (child=data.children[i]); i++) {
+ el.appendChild($E(child));
+ }
+ }
+ delete(data.children);
+ }
+
+ //any other data is attributes
+ for (attr in data) {
+ el[attr]=data[attr];
+ }
+ }
+
+ return el;
+}
+
+// FROM Nick Hemsley
+var Debug = {
+ inspectOutput: function (container, within) {
+ within = within || debugWindow.getContent()
+
+ if (debugWindow == null)
+ return;
+
+ within.appendChild(container)
+ },
+
+ inspect: function(object) {
+ var cont = $E({tag: "div", className: "inspector"})
+ Debug.inspectObj(object, cont)
+ debugWindow.getContent().appendChild(cont)
+ },
+
+ inspectObj: function (object, container) {
+ for (prop in object) {
+ Debug.inspectOutput(Debug.inspectable(object, prop), container)
+ }
+ },
+
+ inspectable: function(object, prop) {
+ cont = $E({tag: 'div', className: 'inspectable', children: [prop + " value: " + object[prop] ]})
+ cont.toInspect = object[prop]
+ Event.observe(cont, 'click', Debug.inspectClicked, false)
+ return cont
+ },
+
+ inspectClicked: function(e) {
+ Debug.inspectContained(Event.element(e))
+ Event.stop(e)
+ },
+
+ inspectContained: function(container) {
+ if (container.opened) {
+ container.parentNode.removeChild(container.opened)
+ delete(container.opened)
+ } else {
+ sibling = container.parentNode.insertBefore($E({tag: "div", className: "child"}), container.nextSibling)
+ if (container.toInspect)
+ Debug.inspectObj(container.toInspect, sibling)
+ container.opened = sibling
+ }
+ }
+}
+var inspect = Debug.inspect;
diff --git a/data/msfweb/public/javascripts/effects.js b/data/msfweb/public/javascripts/effects.js
index 927400502d..06f59b4769 100644
--- a/data/msfweb/public/javascripts/effects.js
+++ b/data/msfweb/public/javascripts/effects.js
@@ -1,15 +1,18 @@
-// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// script.aculo.us effects.js v1.7.0, Fri Jan 19 19:16:36 CET 2007
+
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// Contributors:
// Justin Palmer (http://encytemedia.com/)
// Mark Pilgrim (http://diveintomark.org/)
// Martin Bialasinki
//
-// See scriptaculous.js for full license.
+// 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/
// converts rgb() and #xxx to #xxxxxx format,
// returns self (or first argument) if not convertable
String.prototype.parseColor = function() {
- var color = '#';
+ var color = '#';
if(this.slice(0,4) == 'rgb(') {
var cols = this.slice(4,this.length-1).split(',');
var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
@@ -41,48 +44,21 @@ Element.collectTextNodesIgnoreClass = function(element, className) {
Element.setContentZoom = function(element, percent) {
element = $(element);
- Element.setStyle(element, {fontSize: (percent/100) + 'em'});
+ element.setStyle({fontSize: (percent/100) + 'em'});
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+ return element;
}
-Element.getOpacity = function(element){
- var opacity;
- if (opacity = Element.getStyle(element, 'opacity'))
- return parseFloat(opacity);
- if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/))
- if(opacity[1]) return parseFloat(opacity[1]) / 100;
- return 1.0;
+Element.getOpacity = function(element){
+ return $(element).getStyle('opacity');
}
-Element.setOpacity = function(element, value){
- element= $(element);
- if (value == 1){
- Element.setStyle(element, { opacity:
- (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ?
- 0.999999 : null });
- if(/MSIE/.test(navigator.userAgent))
- Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});
- } else {
- if(value < 0.00001) value = 0;
- Element.setStyle(element, {opacity: value});
- if(/MSIE/.test(navigator.userAgent))
- Element.setStyle(element,
- { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
- 'alpha(opacity='+value*100+')' });
- }
-}
-
-Element.getInlineOpacity = function(element){
+Element.setOpacity = function(element, value){
+ return $(element).setStyle({opacity:value});
+}
+
+Element.getInlineOpacity = function(element){
return $(element).style.opacity || '';
-}
-
-Element.childrenWithClassName = function(element, className, findFirst) {
- var classNameRegExp = new RegExp("(^|\\s)" + className + "(\\s|$)");
- var results = $A($(element).getElementsByTagName('*'))[findFirst ? 'detect' : 'select']( function(c) {
- return (c.className && c.className.match(classNameRegExp));
- });
- if(!results) results = [];
- return results;
}
Element.forceRerendering = function(element) {
@@ -104,9 +80,17 @@ Array.prototype.call = function() {
/*--------------------------------------------------------------------------*/
var Effect = {
+ _elementDoesNotExistError: {
+ name: 'ElementDoesNotExistError',
+ message: 'The specified DOM element does not exist, but is required for this effect to operate'
+ },
tagifyText: function(element) {
+ if(typeof Builder == 'undefined')
+ throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
+
var tagifyStyle = 'position:relative';
- if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1';
+ if(/MSIE/.test(navigator.userAgent) && !window.opera) tagifyStyle += ';zoom:1';
+
element = $(element);
$A(element.childNodes).each( function(child) {
if(child.nodeType==3) {
@@ -159,33 +143,35 @@ var Effect2 = Effect; // deprecated
/* ------------- transitions ------------- */
-Effect.Transitions = {}
-
-Effect.Transitions.linear = function(pos) {
- return pos;
-}
-Effect.Transitions.sinoidal = function(pos) {
- return (-Math.cos(pos*Math.PI)/2) + 0.5;
-}
-Effect.Transitions.reverse = function(pos) {
- return 1-pos;
-}
-Effect.Transitions.flicker = function(pos) {
- return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
-}
-Effect.Transitions.wobble = function(pos) {
- return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
-}
-Effect.Transitions.pulse = function(pos) {
- return (Math.floor(pos*10) % 2 == 0 ?
- (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10)));
-}
-Effect.Transitions.none = function(pos) {
- return 0;
-}
-Effect.Transitions.full = function(pos) {
- return 1;
-}
+Effect.Transitions = {
+ linear: Prototype.K,
+ sinoidal: function(pos) {
+ return (-Math.cos(pos*Math.PI)/2) + 0.5;
+ },
+ reverse: function(pos) {
+ return 1-pos;
+ },
+ flicker: function(pos) {
+ return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
+ },
+ wobble: function(pos) {
+ return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
+ },
+ pulse: function(pos, pulses) {
+ pulses = pulses || 5;
+ return (
+ Math.round((pos % (1/pulses)) * pulses) == 0 ?
+ ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) :
+ 1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2))
+ );
+ },
+ none: function(pos) {
+ return 0;
+ },
+ full: function(pos) {
+ return 1;
+ }
+};
/* ------------- core effects ------------- */
@@ -212,6 +198,9 @@ Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
e.finishOn += effect.finishOn;
});
break;
+ case 'with-last':
+ timestamp = this.effects.pluck('startOn').max() || timestamp;
+ break;
case 'end':
// start effect after last queued effect has finished
timestamp = this.effects.pluck('finishOn').max() || timestamp;
@@ -225,7 +214,7 @@ Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
this.effects.push(effect);
if(!this.interval)
- this.interval = setInterval(this.loop.bind(this), 40);
+ this.interval = setInterval(this.loop.bind(this), 15);
},
remove: function(effect) {
this.effects = this.effects.reject(function(e) { return e==effect });
@@ -236,7 +225,8 @@ Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
},
loop: function() {
var timePos = new Date().getTime();
- this.effects.invoke('loop', timePos);
+ for(var i=0, len=this.effects.length;i';
+ var data = $H();
+ for(property in this)
+ if(typeof this[property] != 'function') data[property] = this[property];
+ return '#';
}
}
@@ -348,12 +341,24 @@ Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
}
});
+Effect.Event = Class.create();
+Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), {
+ initialize: function() {
+ var options = Object.extend({
+ duration: 0
+ }, arguments[0] || {});
+ this.start(options);
+ },
+ update: Prototype.emptyFunction
+});
+
Effect.Opacity = Class.create();
Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
+ if(!this.element) throw(Effect._elementDoesNotExistError);
// make this work on IE on elements without 'layout'
- if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout))
+ if(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout))
this.element.setStyle({zoom: 1});
var options = Object.extend({
from: this.element.getOpacity() || 0.0,
@@ -370,6 +375,7 @@ Effect.Move = Class.create();
Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
+ if(!this.element) throw(Effect._elementDoesNotExistError);
var options = Object.extend({
x: 0,
y: 0,
@@ -393,8 +399,8 @@ Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
},
update: function(position) {
this.element.setStyle({
- left: this.options.x * position + this.originalLeft + 'px',
- top: this.options.y * position + this.originalTop + 'px'
+ left: Math.round(this.options.x * position + this.originalLeft) + 'px',
+ top: Math.round(this.options.y * position + this.originalTop) + 'px'
});
}
});
@@ -408,7 +414,8 @@ Effect.MoveBy = function(element, toTop, toLeft) {
Effect.Scale = Class.create();
Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
initialize: function(element, percent) {
- this.element = $(element)
+ this.element = $(element);
+ if(!this.element) throw(Effect._elementDoesNotExistError);
var options = Object.extend({
scaleX: true,
scaleY: true,
@@ -433,7 +440,7 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
this.originalLeft = this.element.offsetLeft;
var fontSize = this.element.getStyle('font-size') || '100%';
- ['em','px','%'].each( function(fontSizeType) {
+ ['em','px','%','pt'].each( function(fontSizeType) {
if(fontSize.indexOf(fontSizeType)>0) {
this.fontSize = parseFloat(fontSize);
this.fontSizeType = fontSizeType;
@@ -458,12 +465,12 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
},
finish: function(position) {
- if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
+ if(this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
},
setDimensions: function(height, width) {
var d = {};
- if(this.options.scaleX) d.width = width + 'px';
- if(this.options.scaleY) d.height = height + 'px';
+ if(this.options.scaleX) d.width = Math.round(width) + 'px';
+ if(this.options.scaleY) d.height = Math.round(height) + 'px';
if(this.options.scaleFromCenter) {
var topd = (height - this.dims[0])/2;
var leftd = (width - this.dims[1])/2;
@@ -483,6 +490,7 @@ Effect.Highlight = Class.create();
Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
+ if(!this.element) throw(Effect._elementDoesNotExistError);
var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
this.start(options);
},
@@ -490,9 +498,11 @@ Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype),
// Prevent executing on elements not in the layout flow
if(this.element.getStyle('display')=='none') { this.cancel(); return; }
// Disable background image during the effect
- this.oldStyle = {
- backgroundImage: this.element.getStyle('background-image') };
- this.element.setStyle({backgroundImage: 'none'});
+ this.oldStyle = {};
+ if (!this.options.keepBackgroundImage) {
+ this.oldStyle.backgroundImage = this.element.getStyle('background-image');
+ this.element.setStyle({backgroundImage: 'none'});
+ }
if(!this.options.endcolor)
this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
if(!this.options.restorecolor)
@@ -547,8 +557,7 @@ Effect.Fade = function(element) {
to: 0.0,
afterFinishInternal: function(effect) {
if(effect.options.to!=0) return;
- effect.element.hide();
- effect.element.setStyle({opacity: oldOpacity});
+ effect.element.hide().setStyle({opacity: oldOpacity});
}}, arguments[1] || {});
return new Effect.Opacity(element,options);
}
@@ -563,25 +572,31 @@ Effect.Appear = function(element) {
effect.element.forceRerendering();
},
beforeSetup: function(effect) {
- effect.element.setOpacity(effect.options.from);
- effect.element.show();
+ effect.element.setOpacity(effect.options.from).show();
}}, arguments[1] || {});
return new Effect.Opacity(element,options);
}
Effect.Puff = function(element) {
element = $(element);
- var oldStyle = { opacity: element.getInlineOpacity(), position: element.getStyle('position') };
+ var oldStyle = {
+ opacity: element.getInlineOpacity(),
+ position: element.getStyle('position'),
+ top: element.style.top,
+ left: element.style.left,
+ width: element.style.width,
+ height: element.style.height
+ };
return new Effect.Parallel(
[ new Effect.Scale(element, 200,
{ sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
Object.extend({ duration: 1.0,
beforeSetupInternal: function(effect) {
- effect.effects[0].element.setStyle({position: 'absolute'}); },
+ Position.absolutize(effect.effects[0].element)
+ },
afterFinishInternal: function(effect) {
- effect.effects[0].element.hide();
- effect.effects[0].element.setStyle(oldStyle); }
+ effect.effects[0].element.hide().setStyle(oldStyle); }
}, arguments[1] || {})
);
}
@@ -589,13 +604,12 @@ Effect.Puff = function(element) {
Effect.BlindUp = function(element) {
element = $(element);
element.makeClipping();
- return new Effect.Scale(element, 0,
+ return new Effect.Scale(element, 0,
Object.extend({ scaleContent: false,
scaleX: false,
restoreAfterFinish: true,
afterFinishInternal: function(effect) {
- effect.element.hide();
- effect.element.undoClipping();
+ effect.element.hide().undoClipping();
}
}, arguments[1] || {})
);
@@ -604,28 +618,25 @@ Effect.BlindUp = function(element) {
Effect.BlindDown = function(element) {
element = $(element);
var elementDimensions = element.getDimensions();
- return new Effect.Scale(element, 100,
- Object.extend({ scaleContent: false,
- scaleX: false,
- scaleFrom: 0,
- scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
- restoreAfterFinish: true,
- afterSetup: function(effect) {
- effect.element.makeClipping();
- effect.element.setStyle({height: '0px'});
- effect.element.show();
- },
- afterFinishInternal: function(effect) {
- effect.element.undoClipping();
- }
- }, arguments[1] || {})
- );
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ scaleFrom: 0,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function(effect) {
+ effect.element.makeClipping().setStyle({height: '0px'}).show();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.undoClipping();
+ }
+ }, arguments[1] || {}));
}
Effect.SwitchOff = function(element) {
element = $(element);
var oldOpacity = element.getInlineOpacity();
- return new Effect.Appear(element, {
+ return new Effect.Appear(element, Object.extend({
duration: 0.4,
from: 0,
transition: Effect.Transitions.flicker,
@@ -634,18 +645,14 @@ Effect.SwitchOff = function(element) {
duration: 0.3, scaleFromCenter: true,
scaleX: false, scaleContent: false, restoreAfterFinish: true,
beforeSetup: function(effect) {
- effect.element.makePositioned();
- effect.element.makeClipping();
+ effect.element.makePositioned().makeClipping();
},
afterFinishInternal: function(effect) {
- effect.element.hide();
- effect.element.undoClipping();
- effect.element.undoPositioned();
- effect.element.setStyle({opacity: oldOpacity});
+ effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
}
})
}
- });
+ }, arguments[1] || {}));
}
Effect.DropOut = function(element) {
@@ -663,9 +670,7 @@ Effect.DropOut = function(element) {
effect.effects[0].element.makePositioned();
},
afterFinishInternal: function(effect) {
- effect.effects[0].element.hide();
- effect.effects[0].element.undoPositioned();
- effect.effects[0].element.setStyle(oldStyle);
+ effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
}
}, arguments[1] || {}));
}
@@ -687,54 +692,42 @@ Effect.Shake = function(element) {
{ x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
- effect.element.undoPositioned();
- effect.element.setStyle(oldStyle);
+ effect.element.undoPositioned().setStyle(oldStyle);
}}) }}) }}) }}) }}) }});
}
Effect.SlideDown = function(element) {
- element = $(element);
- element.cleanWhitespace();
+ element = $(element).cleanWhitespace();
// SlideDown need to have the content of the element wrapped in a container element with fixed height!
- var oldInnerBottom = $(element.firstChild).getStyle('bottom');
+ var oldInnerBottom = element.down().getStyle('bottom');
var elementDimensions = element.getDimensions();
return new Effect.Scale(element, 100, Object.extend({
scaleContent: false,
scaleX: false,
- scaleFrom: 0,
+ scaleFrom: window.opera ? 0 : 1,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
afterSetup: function(effect) {
effect.element.makePositioned();
- effect.element.firstChild.makePositioned();
+ effect.element.down().makePositioned();
if(window.opera) effect.element.setStyle({top: ''});
- effect.element.makeClipping();
- effect.element.setStyle({height: '0px'});
- effect.element.show(); },
+ effect.element.makeClipping().setStyle({height: '0px'}).show();
+ },
afterUpdateInternal: function(effect) {
- effect.element.firstChild.setStyle({bottom:
+ effect.element.down().setStyle({bottom:
(effect.dims[0] - effect.element.clientHeight) + 'px' });
},
afterFinishInternal: function(effect) {
- effect.element.undoClipping();
- // IE will crash if child is undoPositioned first
- if(/MSIE/.test(navigator.userAgent)){
- effect.element.undoPositioned();
- effect.element.firstChild.undoPositioned();
- }else{
- effect.element.firstChild.undoPositioned();
- effect.element.undoPositioned();
- }
- effect.element.firstChild.setStyle({bottom: oldInnerBottom}); }
+ effect.element.undoClipping().undoPositioned();
+ effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
}, arguments[1] || {})
);
}
-
+
Effect.SlideUp = function(element) {
- element = $(element);
- element.cleanWhitespace();
- var oldInnerBottom = $(element.firstChild).getStyle('bottom');
- return new Effect.Scale(element, 0,
+ element = $(element).cleanWhitespace();
+ var oldInnerBottom = element.down().getStyle('bottom');
+ return new Effect.Scale(element, window.opera ? 0 : 1,
Object.extend({ scaleContent: false,
scaleX: false,
scaleMode: 'box',
@@ -742,32 +735,32 @@ Effect.SlideUp = function(element) {
restoreAfterFinish: true,
beforeStartInternal: function(effect) {
effect.element.makePositioned();
- effect.element.firstChild.makePositioned();
+ effect.element.down().makePositioned();
if(window.opera) effect.element.setStyle({top: ''});
- effect.element.makeClipping();
- effect.element.show(); },
+ effect.element.makeClipping().show();
+ },
afterUpdateInternal: function(effect) {
- effect.element.firstChild.setStyle({bottom:
- (effect.dims[0] - effect.element.clientHeight) + 'px' }); },
+ effect.element.down().setStyle({bottom:
+ (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ },
afterFinishInternal: function(effect) {
- effect.element.hide();
- effect.element.undoClipping();
- effect.element.firstChild.undoPositioned();
- effect.element.undoPositioned();
- effect.element.setStyle({bottom: oldInnerBottom}); }
+ effect.element.hide().undoClipping().undoPositioned().setStyle({bottom: oldInnerBottom});
+ effect.element.down().undoPositioned();
+ }
}, arguments[1] || {})
);
}
// Bug in opera makes the TD containing this element expand for a instance after finish
Effect.Squish = function(element) {
- return new Effect.Scale(element, window.opera ? 1 : 0,
- { restoreAfterFinish: true,
- beforeSetup: function(effect) {
- effect.element.makeClipping(effect.element); },
- afterFinishInternal: function(effect) {
- effect.element.hide(effect.element);
- effect.element.undoClipping(effect.element); }
+ return new Effect.Scale(element, window.opera ? 1 : 0, {
+ restoreAfterFinish: true,
+ beforeSetup: function(effect) {
+ effect.element.makeClipping();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping();
+ }
});
}
@@ -823,9 +816,7 @@ Effect.Grow = function(element) {
y: initialMoveY,
duration: 0.01,
beforeSetup: function(effect) {
- effect.element.hide();
- effect.element.makeClipping();
- effect.element.makePositioned();
+ effect.element.hide().makeClipping().makePositioned();
},
afterFinishInternal: function(effect) {
new Effect.Parallel(
@@ -836,13 +827,10 @@ Effect.Grow = function(element) {
sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
], Object.extend({
beforeSetup: function(effect) {
- effect.effects[0].element.setStyle({height: '0px'});
- effect.effects[0].element.show();
+ effect.effects[0].element.setStyle({height: '0px'}).show();
},
afterFinishInternal: function(effect) {
- effect.effects[0].element.undoClipping();
- effect.effects[0].element.undoPositioned();
- effect.effects[0].element.setStyle(oldStyle);
+ effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
}
}, options)
)
@@ -896,13 +884,10 @@ Effect.Shrink = function(element) {
new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
], Object.extend({
beforeStartInternal: function(effect) {
- effect.effects[0].element.makePositioned();
- effect.effects[0].element.makeClipping(); },
+ effect.effects[0].element.makePositioned().makeClipping();
+ },
afterFinishInternal: function(effect) {
- effect.effects[0].element.hide();
- effect.effects[0].element.undoClipping();
- effect.effects[0].element.undoPositioned();
- effect.effects[0].element.setStyle(oldStyle); }
+ effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
}, options)
);
}
@@ -912,10 +897,10 @@ Effect.Pulsate = function(element) {
var options = arguments[1] || {};
var oldOpacity = element.getInlineOpacity();
var transition = options.transition || Effect.Transitions.sinoidal;
- var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) };
+ var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
reverser.bind(transition);
return new Effect.Opacity(element,
- Object.extend(Object.extend({ duration: 3.0, from: 0,
+ Object.extend(Object.extend({ duration: 2.0, from: 0,
afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
}, options), {transition: reverser}));
}
@@ -927,7 +912,7 @@ Effect.Fold = function(element) {
left: element.style.left,
width: element.style.width,
height: element.style.height };
- Element.makeClipping(element);
+ element.makeClipping();
return new Effect.Scale(element, 5, Object.extend({
scaleContent: false,
scaleX: false,
@@ -936,15 +921,162 @@ Effect.Fold = function(element) {
scaleContent: false,
scaleY: false,
afterFinishInternal: function(effect) {
- effect.element.hide();
- effect.element.undoClipping();
- effect.element.setStyle(oldStyle);
+ effect.element.hide().undoClipping().setStyle(oldStyle);
} });
}}, arguments[1] || {}));
};
+Effect.Morph = Class.create();
+Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), {
+ initialize: function(element) {
+ this.element = $(element);
+ if(!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({
+ style: {}
+ }, arguments[1] || {});
+ if (typeof options.style == 'string') {
+ if(options.style.indexOf(':') == -1) {
+ var cssText = '', selector = '.' + options.style;
+ $A(document.styleSheets).reverse().each(function(styleSheet) {
+ if (styleSheet.cssRules) cssRules = styleSheet.cssRules;
+ else if (styleSheet.rules) cssRules = styleSheet.rules;
+ $A(cssRules).reverse().each(function(rule) {
+ if (selector == rule.selectorText) {
+ cssText = rule.style.cssText;
+ throw $break;
+ }
+ });
+ if (cssText) throw $break;
+ });
+ this.style = cssText.parseStyle();
+ options.afterFinishInternal = function(effect){
+ effect.element.addClassName(effect.options.style);
+ effect.transforms.each(function(transform) {
+ if(transform.style != 'opacity')
+ effect.element.style[transform.style.camelize()] = '';
+ });
+ }
+ } else this.style = options.style.parseStyle();
+ } else this.style = $H(options.style)
+ this.start(options);
+ },
+ setup: function(){
+ function parseColor(color){
+ if(!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
+ color = color.parseColor();
+ return $R(0,2).map(function(i){
+ return parseInt( color.slice(i*2+1,i*2+3), 16 )
+ });
+ }
+ this.transforms = this.style.map(function(pair){
+ var property = pair[0].underscore().dasherize(), value = pair[1], unit = null;
+
+ if(value.parseColor('#zzzzzz') != '#zzzzzz') {
+ value = value.parseColor();
+ unit = 'color';
+ } else if(property == 'opacity') {
+ value = parseFloat(value);
+ if(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout))
+ this.element.setStyle({zoom: 1});
+ } else if(Element.CSS_LENGTH.test(value))
+ var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/),
+ value = parseFloat(components[1]), unit = (components.length == 3) ? components[2] : null;
+
+ var originalValue = this.element.getStyle(property);
+ return $H({
+ style: property,
+ originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
+ targetValue: unit=='color' ? parseColor(value) : value,
+ unit: unit
+ });
+ }.bind(this)).reject(function(transform){
+ return (
+ (transform.originalValue == transform.targetValue) ||
+ (
+ transform.unit != 'color' &&
+ (isNaN(transform.originalValue) || isNaN(transform.targetValue))
+ )
+ )
+ });
+ },
+ update: function(position) {
+ var style = $H(), value = null;
+ this.transforms.each(function(transform){
+ value = transform.unit=='color' ?
+ $R(0,2).inject('#',function(m,v,i){
+ return m+(Math.round(transform.originalValue[i]+
+ (transform.targetValue[i] - transform.originalValue[i])*position)).toColorPart() }) :
+ transform.originalValue + Math.round(
+ ((transform.targetValue - transform.originalValue) * position) * 1000)/1000 + transform.unit;
+ style[transform.style] = value;
+ });
+ this.element.setStyle(style);
+ }
+});
+
+Effect.Transform = Class.create();
+Object.extend(Effect.Transform.prototype, {
+ initialize: function(tracks){
+ this.tracks = [];
+ this.options = arguments[1] || {};
+ this.addTracks(tracks);
+ },
+ addTracks: function(tracks){
+ tracks.each(function(track){
+ var data = $H(track).values().first();
+ this.tracks.push($H({
+ ids: $H(track).keys().first(),
+ effect: Effect.Morph,
+ options: { style: data }
+ }));
+ }.bind(this));
+ return this;
+ },
+ play: function(){
+ return new Effect.Parallel(
+ this.tracks.map(function(track){
+ var elements = [$(track.ids) || $$(track.ids)].flatten();
+ return elements.map(function(e){ return new track.effect(e, Object.extend({ sync:true }, track.options)) });
+ }).flatten(),
+ this.options
+ );
+ }
+});
+
+Element.CSS_PROPERTIES = $w(
+ 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
+ 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
+ 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
+ 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
+ 'fontSize fontWeight height left letterSpacing lineHeight ' +
+ 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
+ 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
+ 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
+ 'right textIndent top width wordSpacing zIndex');
+
+Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
+
+String.prototype.parseStyle = function(){
+ var element = Element.extend(document.createElement('div'));
+ element.innerHTML = '';
+ var style = element.down().style, styleRules = $H();
+
+ Element.CSS_PROPERTIES.each(function(property){
+ if(style[property]) styleRules[property] = style[property];
+ });
+ if(/MSIE/.test(navigator.userAgent) && !window.opera && this.indexOf('opacity') > -1) {
+ styleRules.opacity = this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1];
+ }
+ return styleRules;
+};
+
+Element.morph = function(element, style) {
+ new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || {}));
+ return element;
+};
+
['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
- 'collectTextNodes','collectTextNodesIgnoreClass','childrenWithClassName'].each(
+ 'collectTextNodes','collectTextNodesIgnoreClass','morph'].each(
function(f) { Element.Methods[f] = Element[f]; }
);
diff --git a/data/msfweb/public/javascripts/extended_debug.js b/data/msfweb/public/javascripts/extended_debug.js
new file mode 100755
index 0000000000..2b935b1b7d
--- /dev/null
+++ b/data/msfweb/public/javascripts/extended_debug.js
@@ -0,0 +1,113 @@
+var commandHistory;
+var historyIndex;
+
+function showExtendedDebug() {
+ if (debugWindow != null) {
+ hideDebug();
+ }
+
+ if (debugWindow == null) {
+ commandHistory = new Array();
+ historyIndex = 0;
+
+ debugWindow = new Window('debug_window', {className: 'dialog',width:250, height:100, right:4, minWidth:250, bottom:42, zIndex:1000, opacity:1, showEffect: Element.show, resizable: true, title: "Debug"})
+ debugWindow.getContent().innerHTML = " ";
+
+ //create hourglass icon and attach events to it.
+ var cont = "";
+
+ new Insertion.After('debug_window_maximize', cont);
+ Event.observe('debug_window_inspect', 'click', enterInspectionMode, false);
+
+ //create command text box
+ cont = "Eval:"
+ debugWindow.setStatusBar(cont);
+
+ Event.observe('debug_window_command', 'mousedown', donothing);
+ Event.observe('debug_window_command', 'keypress', evalJS, false);
+ }
+ debugWindow.show();
+}
+
+function donothing(evt){
+ Field.activate('debug_window_command');
+ return false;
+}
+
+function evalJS(evt){
+ if(evt.keyCode == Event.KEY_RETURN){
+ var js = $F('debug_window_command');
+ try{
+ var ret = eval(js);
+ if(ret != null)
+ debug(ret);
+ }catch(e){
+ debug(e);
+ }
+ $('debug_window_command').value = '';
+
+ Field.activate('debug_window_command');
+ commandHistory.push(js);
+ historyIndex = 0;
+ }
+
+ if(evt.keyCode == Event.KEY_UP){
+ if(commandHistory.length > historyIndex){
+ historyIndex++;
+ var js = commandHistory[commandHistory.length-historyIndex];
+ $('debug_window_command').value = js;
+ Event.stop(evt);
+ Field.activate('debug_window_command');
+ }
+ }
+
+ if(evt.keyCode == Event.KEY_DOWN){
+ if(commandHistory.length >= historyIndex && historyIndex > 1){
+ historyIndex--;
+ var js = commandHistory[commandHistory.length-historyIndex];
+ $('debug_window_command').value = js;
+ Event.stop(evt);
+ Field.activate('debug_window_command');
+ }
+ }
+}
+
+function enterInspectionMode(evt){
+ //stop observing magnifying glass
+ Event.stopObserving('debug_window_inspect', 'click', enterInspectionMode, false);
+ //change pointer
+ document.body.style.cursor='help';
+ //start observing mouse clicks
+ Event.observe(window, 'click', inspectItem, false);
+}
+
+function inspectItem(evt){
+ // the element that triggered the event
+ var element = Event.element(evt);
+ if(element.id!="debug_window_inspect"){
+ clearDebug()
+ //change pointer
+ document.body.style.cursor='default';
+ debug(element.id);
+ inspect(element);
+ //stop observing mouse clicks
+ Event.stopObserving(window, 'click', inspectItem, false);
+ //alert('doing something');
+ //start observing mag
+ Event.observe('debug_window_inspect', 'click', enterInspectionMode, false);
+ }
+}
+
+function clearDebug() {
+ var win = $('debug');
+ if (win == null)
+ return;
+
+ win.innerHTML=" ";
+ //clear inspections too
+ var divs = document.getElementsByClassName('inspector');
+ divs.each(function(div){
+ Element.remove(div);
+ });
+}
+
diff --git a/data/msfweb/public/javascripts/prototype.js b/data/msfweb/public/javascripts/prototype.js
index 0caf9cd7f0..0476b8fdcc 100644
--- a/data/msfweb/public/javascripts/prototype.js
+++ b/data/msfweb/public/javascripts/prototype.js
@@ -1,5 +1,5 @@
-/* Prototype JavaScript framework, version 1.5.0_rc0
- * (c) 2005 Sam Stephenson
+/* Prototype JavaScript framework, version 1.5.0
+ * (c) 2005-2007 Sam Stephenson
*
* Prototype is freely distributable under the terms of an MIT-style license.
* For details, see the Prototype web site: http://prototype.conio.net/
@@ -7,11 +7,14 @@
/*--------------------------------------------------------------------------*/
var Prototype = {
- Version: '1.5.0_rc0',
- ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)',
+ Version: '1.5.0',
+ BrowserFeatures: {
+ XPath: !!document.evaluate
+ },
+ ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)',
emptyFunction: function() {},
- K: function(x) {return x}
+ K: function(x) { return x }
}
var Class = {
@@ -31,16 +34,36 @@ Object.extend = function(destination, source) {
return destination;
}
-Object.inspect = function(object) {
- try {
- if (object == undefined) return 'undefined';
- if (object == null) return 'null';
- return object.inspect ? object.inspect() : object.toString();
- } catch (e) {
- if (e instanceof RangeError) return '...';
- throw e;
+Object.extend(Object, {
+ inspect: function(object) {
+ try {
+ if (object === undefined) return 'undefined';
+ if (object === null) return 'null';
+ return object.inspect ? object.inspect() : object.toString();
+ } catch (e) {
+ if (e instanceof RangeError) return '...';
+ throw e;
+ }
+ },
+
+ keys: function(object) {
+ var keys = [];
+ for (var property in object)
+ keys.push(property);
+ return keys;
+ },
+
+ values: function(object) {
+ var values = [];
+ for (var property in object)
+ values.push(object[property]);
+ return values;
+ },
+
+ clone: function(object) {
+ return Object.extend({}, object);
}
-}
+});
Function.prototype.bind = function() {
var __method = this, args = $A(arguments), object = args.shift();
@@ -50,9 +73,9 @@ Function.prototype.bind = function() {
}
Function.prototype.bindAsEventListener = function(object) {
- var __method = this;
+ var __method = this, args = $A(arguments), object = args.shift();
return function(event) {
- return __method.call(object, event || window.event);
+ return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
}
}
@@ -77,7 +100,7 @@ var Try = {
these: function() {
var returnValue;
- for (var i = 0; i < arguments.length; i++) {
+ for (var i = 0, length = arguments.length; i < length; i++) {
var lambda = arguments[i];
try {
returnValue = lambda();
@@ -102,20 +125,30 @@ PeriodicalExecuter.prototype = {
},
registerCallback: function() {
- setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+ this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+ },
+
+ stop: function() {
+ if (!this.timer) return;
+ clearInterval(this.timer);
+ this.timer = null;
},
onTimerEvent: function() {
if (!this.currentlyExecuting) {
try {
this.currentlyExecuting = true;
- this.callback();
+ this.callback(this);
} finally {
this.currentlyExecuting = false;
}
}
}
}
+String.interpret = function(value){
+ return value == null ? '' : String(value);
+}
+
Object.extend(String.prototype, {
gsub: function(pattern, replacement) {
var result = '', source = this, match;
@@ -124,7 +157,7 @@ Object.extend(String.prototype, {
while (source.length > 0) {
if (match = source.match(pattern)) {
result += source.slice(0, match.index);
- result += (replacement(match) || '').toString();
+ result += String.interpret(replacement(match));
source = source.slice(match.index + match[0].length);
} else {
result += source, source = '';
@@ -189,15 +222,28 @@ Object.extend(String.prototype, {
unescapeHTML: function() {
var div = document.createElement('div');
div.innerHTML = this.stripTags();
- return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
+ return div.childNodes[0] ? (div.childNodes.length > 1 ?
+ $A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) :
+ div.childNodes[0].nodeValue) : '';
},
- toQueryParams: function() {
- var pairs = this.match(/^\??(.*)$/)[1].split('&');
- return pairs.inject({}, function(params, pairString) {
- var pair = pairString.split('=');
- params[pair[0]] = pair[1];
- return params;
+ toQueryParams: function(separator) {
+ var match = this.strip().match(/([^?#]*)(#.*)?$/);
+ if (!match) return {};
+
+ return match[1].split(separator || '&').inject({}, function(hash, pair) {
+ if ((pair = pair.split('='))[0]) {
+ var name = decodeURIComponent(pair[0]);
+ var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;
+
+ if (hash[name] !== undefined) {
+ if (hash[name].constructor != Array)
+ hash[name] = [hash[name]];
+ if (value) hash[name].push(value);
+ }
+ else hash[name] = value;
+ }
+ return hash;
});
},
@@ -205,24 +251,43 @@ Object.extend(String.prototype, {
return this.split('');
},
- camelize: function() {
- var oStringList = this.split('-');
- if (oStringList.length == 1) return oStringList[0];
-
- var camelizedString = this.indexOf('-') == 0
- ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
- : oStringList[0];
-
- for (var i = 1, len = oStringList.length; i < len; i++) {
- var s = oStringList[i];
- camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
- }
-
- return camelizedString;
+ succ: function() {
+ return this.slice(0, this.length - 1) +
+ String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
},
- inspect: function() {
- return "'" + this.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') + "'";
+ camelize: function() {
+ var parts = this.split('-'), len = parts.length;
+ if (len == 1) return parts[0];
+
+ var camelized = this.charAt(0) == '-'
+ ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+ : parts[0];
+
+ for (var i = 1; i < len; i++)
+ camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+
+ return camelized;
+ },
+
+ capitalize: function(){
+ return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+ },
+
+ underscore: function() {
+ return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
+ },
+
+ dasherize: function() {
+ return this.gsub(/_/,'-');
+ },
+
+ inspect: function(useDoubleQuotes) {
+ var escapedString = this.replace(/\\/g, '\\\\');
+ if (useDoubleQuotes)
+ return '"' + escapedString.replace(/"/g, '\\"') + '"';
+ else
+ return "'" + escapedString.replace(/'/g, '\\\'') + "'";
}
});
@@ -246,7 +311,7 @@ Template.prototype = {
return this.template.gsub(this.pattern, function(match) {
var before = match[1];
if (before == '\\') return match[2];
- return before + (object[match[3]] || '').toString();
+ return before + String.interpret(object[match[3]]);
});
}
}
@@ -268,6 +333,14 @@ var Enumerable = {
} catch (e) {
if (e != $break) throw e;
}
+ return this;
+ },
+
+ eachSlice: function(number, iterator) {
+ var index = -number, slices = [], array = this.toArray();
+ while ((index += number) < array.length)
+ slices.push(array.slice(index, index+number));
+ return slices.map(iterator);
},
all: function(iterator) {
@@ -280,7 +353,7 @@ var Enumerable = {
},
any: function(iterator) {
- var result = true;
+ var result = false;
this.each(function(value, index) {
if (result = !!(iterator || Prototype.K)(value, index))
throw $break;
@@ -291,12 +364,12 @@ var Enumerable = {
collect: function(iterator) {
var results = [];
this.each(function(value, index) {
- results.push(iterator(value, index));
+ results.push((iterator || Prototype.K)(value, index));
});
return results;
},
- detect: function (iterator) {
+ detect: function(iterator) {
var result;
this.each(function(value, index) {
if (iterator(value, index)) {
@@ -337,6 +410,14 @@ var Enumerable = {
return found;
},
+ inGroupsOf: function(number, fillWith) {
+ fillWith = fillWith === undefined ? null : fillWith;
+ return this.eachSlice(number, function(slice) {
+ while(slice.length < number) slice.push(fillWith);
+ return slice;
+ });
+ },
+
inject: function(memo, iterator) {
this.each(function(value, index) {
memo = iterator(memo, value, index);
@@ -346,7 +427,7 @@ var Enumerable = {
invoke: function(method) {
var args = $A(arguments).slice(1);
- return this.collect(function(value) {
+ return this.map(function(value) {
return value[method].apply(value, args);
});
},
@@ -398,7 +479,7 @@ var Enumerable = {
},
sortBy: function(iterator) {
- return this.collect(function(value, index) {
+ return this.map(function(value, index) {
return {value: value, criteria: iterator(value, index)};
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
@@ -407,7 +488,7 @@ var Enumerable = {
},
toArray: function() {
- return this.collect(Prototype.K);
+ return this.map();
},
zip: function() {
@@ -421,6 +502,10 @@ var Enumerable = {
});
},
+ size: function() {
+ return this.toArray().length;
+ },
+
inspect: function() {
return '#';
}
@@ -439,7 +524,7 @@ var $A = Array.from = function(iterable) {
return iterable.toArray();
} else {
var results = [];
- for (var i = 0; i < iterable.length; i++)
+ for (var i = 0, length = iterable.length; i < length; i++)
results.push(iterable[i]);
return results;
}
@@ -452,7 +537,7 @@ if (!Array.prototype._reverse)
Object.extend(Array.prototype, {
_each: function(iterator) {
- for (var i = 0; i < this.length; i++)
+ for (var i = 0, length = this.length; i < length; i++)
iterator(this[i]);
},
@@ -471,7 +556,7 @@ Object.extend(Array.prototype, {
compact: function() {
return this.select(function(value) {
- return value != undefined || value != null;
+ return value != null;
});
},
@@ -490,7 +575,7 @@ Object.extend(Array.prototype, {
},
indexOf: function(object) {
- for (var i = 0; i < this.length; i++)
+ for (var i = 0, length = this.length; i < length; i++)
if (this[i] == object) return i;
return -1;
},
@@ -499,15 +584,88 @@ Object.extend(Array.prototype, {
return (inline !== false ? this : this.toArray())._reverse();
},
+ reduce: function() {
+ return this.length > 1 ? this : this[0];
+ },
+
+ uniq: function() {
+ return this.inject([], function(array, value) {
+ return array.include(value) ? array : array.concat([value]);
+ });
+ },
+
+ clone: function() {
+ return [].concat(this);
+ },
+
+ size: function() {
+ return this.length;
+ },
+
inspect: function() {
return '[' + this.map(Object.inspect).join(', ') + ']';
}
});
-var Hash = {
+
+Array.prototype.toArray = Array.prototype.clone;
+
+function $w(string){
+ string = string.strip();
+ return string ? string.split(/\s+/) : [];
+}
+
+if(window.opera){
+ Array.prototype.concat = function(){
+ var array = [];
+ for(var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+ for(var i = 0, length = arguments.length; i < length; i++) {
+ if(arguments[i].constructor == Array) {
+ for(var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
+ array.push(arguments[i][j]);
+ } else {
+ array.push(arguments[i]);
+ }
+ }
+ return array;
+ }
+}
+var Hash = function(obj) {
+ Object.extend(this, obj || {});
+};
+
+Object.extend(Hash, {
+ toQueryString: function(obj) {
+ var parts = [];
+
+ this.prototype._each.call(obj, function(pair) {
+ if (!pair.key) return;
+
+ if (pair.value && pair.value.constructor == Array) {
+ var values = pair.value.compact();
+ if (values.length < 2) pair.value = values.reduce();
+ else {
+ key = encodeURIComponent(pair.key);
+ values.each(function(value) {
+ value = value != undefined ? encodeURIComponent(value) : '';
+ parts.push(key + '=' + encodeURIComponent(value));
+ });
+ return;
+ }
+ }
+ if (pair.value == undefined) pair[1] = '';
+ parts.push(pair.map(encodeURIComponent).join('='));
+ });
+
+ return parts.join('&');
+ }
+});
+
+Object.extend(Hash.prototype, Enumerable);
+Object.extend(Hash.prototype, {
_each: function(iterator) {
for (var key in this) {
var value = this[key];
- if (typeof value == 'function') continue;
+ if (value && value == Hash.prototype[key]) continue;
var pair = [key, value];
pair.key = key;
@@ -525,16 +683,30 @@ var Hash = {
},
merge: function(hash) {
- return $H(hash).inject($H(this), function(mergedHash, pair) {
+ return $H(hash).inject(this, function(mergedHash, pair) {
mergedHash[pair.key] = pair.value;
return mergedHash;
});
},
+ remove: function() {
+ var result;
+ for(var i = 0, length = arguments.length; i < length; i++) {
+ var value = this[arguments[i]];
+ if (value !== undefined){
+ if (result === undefined) result = value;
+ else {
+ if (result.constructor != Array) result = [result];
+ result.push(value)
+ }
+ }
+ delete this[arguments[i]];
+ }
+ return result;
+ },
+
toQueryString: function() {
- return this.map(function(pair) {
- return pair.map(encodeURIComponent).join('=');
- }).join('&');
+ return Hash.toQueryString(this);
},
inspect: function() {
@@ -542,14 +714,12 @@ var Hash = {
return pair.map(Object.inspect).join(': ');
}).join(', ') + '}>';
}
-}
+});
function $H(object) {
- var hash = Object.extend({}, object || {});
- Object.extend(hash, Enumerable);
- Object.extend(hash, Hash);
- return hash;
-}
+ if (object && object.constructor == Hash) return object;
+ return new Hash(object);
+};
ObjectRange = Class.create();
Object.extend(ObjectRange.prototype, Enumerable);
Object.extend(ObjectRange.prototype, {
@@ -561,10 +731,10 @@ Object.extend(ObjectRange.prototype, {
_each: function(iterator) {
var value = this.start;
- do {
+ while (this.include(value)) {
iterator(value);
value = value.succ();
- } while (this.include(value));
+ }
},
include: function(value) {
@@ -599,18 +769,18 @@ Ajax.Responders = {
this.responders._each(iterator);
},
- register: function(responderToAdd) {
- if (!this.include(responderToAdd))
- this.responders.push(responderToAdd);
+ register: function(responder) {
+ if (!this.include(responder))
+ this.responders.push(responder);
},
- unregister: function(responderToRemove) {
- this.responders = this.responders.without(responderToRemove);
+ unregister: function(responder) {
+ this.responders = this.responders.without(responder);
},
dispatch: function(callback, request, transport, json) {
this.each(function(responder) {
- if (responder[callback] && typeof responder[callback] == 'function') {
+ if (typeof responder[callback] == 'function') {
try {
responder[callback].apply(responder, [request, transport, json]);
} catch (e) {}
@@ -625,7 +795,6 @@ Ajax.Responders.register({
onCreate: function() {
Ajax.activeRequestCount++;
},
-
onComplete: function() {
Ajax.activeRequestCount--;
}
@@ -638,19 +807,14 @@ Ajax.Base.prototype = {
method: 'post',
asynchronous: true,
contentType: 'application/x-www-form-urlencoded',
+ encoding: 'UTF-8',
parameters: ''
}
Object.extend(this.options, options || {});
- },
- responseIsSuccess: function() {
- return this.transport.status == undefined
- || this.transport.status == 0
- || (this.transport.status >= 200 && this.transport.status < 300);
- },
-
- responseIsFailure: function() {
- return !this.responseIsSuccess();
+ this.options.method = this.options.method.toLowerCase();
+ if (typeof this.options.parameters == 'string')
+ this.options.parameters = this.options.parameters.toQueryParams();
}
}
@@ -659,6 +823,8 @@ Ajax.Request.Events =
['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
+ _complete: false,
+
initialize: function(url, options) {
this.transport = Ajax.getTransport();
this.setOptions(options);
@@ -666,74 +832,138 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
},
request: function(url) {
- var parameters = this.options.parameters || '';
- if (parameters.length > 0) parameters += '&_=';
+ this.url = url;
+ this.method = this.options.method;
+ var params = this.options.parameters;
+
+ if (!['get', 'post'].include(this.method)) {
+ // simulate other verbs over post
+ params['_method'] = this.method;
+ this.method = 'post';
+ }
+
+ params = Hash.toQueryString(params);
+ if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_='
+
+ // when GET, append parameters to URL
+ if (this.method == 'get' && params)
+ this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params;
try {
- this.url = url;
- if (this.options.method == 'get' && parameters.length > 0)
- this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;
-
Ajax.Responders.dispatch('onCreate', this, this.transport);
- this.transport.open(this.options.method, this.url,
+ this.transport.open(this.method.toUpperCase(), this.url,
this.options.asynchronous);
- if (this.options.asynchronous) {
- this.transport.onreadystatechange = this.onStateChange.bind(this);
- setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
- }
+ if (this.options.asynchronous)
+ setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
+ this.transport.onreadystatechange = this.onStateChange.bind(this);
this.setRequestHeaders();
- var body = this.options.postBody ? this.options.postBody : parameters;
- this.transport.send(this.options.method == 'post' ? body : null);
+ var body = this.method == 'post' ? (this.options.postBody || params) : null;
- } catch (e) {
+ this.transport.send(body);
+
+ /* Force Firefox to handle ready state 4 for synchronous requests */
+ if (!this.options.asynchronous && this.transport.overrideMimeType)
+ this.onStateChange();
+
+ }
+ catch (e) {
this.dispatchException(e);
}
},
- setRequestHeaders: function() {
- var requestHeaders =
- ['X-Requested-With', 'XMLHttpRequest',
- 'X-Prototype-Version', Prototype.Version,
- 'Accept', 'text/javascript, text/html, application/xml, text/xml, */*'];
-
- if (this.options.method == 'post') {
- requestHeaders.push('Content-type', this.options.contentType);
-
- /* Force "Connection: close" for Mozilla browsers to work around
- * a bug where XMLHttpReqeuest sends an incorrect Content-length
- * header. See Mozilla Bugzilla #246651.
- */
- if (this.transport.overrideMimeType)
- requestHeaders.push('Connection', 'close');
- }
-
- if (this.options.requestHeaders)
- requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
-
- for (var i = 0; i < requestHeaders.length; i += 2)
- this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
- },
-
onStateChange: function() {
var readyState = this.transport.readyState;
- if (readyState != 1)
+ if (readyState > 1 && !((readyState == 4) && this._complete))
this.respondToReadyState(this.transport.readyState);
},
- header: function(name) {
+ setRequestHeaders: function() {
+ var headers = {
+ 'X-Requested-With': 'XMLHttpRequest',
+ 'X-Prototype-Version': Prototype.Version,
+ 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+ };
+
+ if (this.method == 'post') {
+ headers['Content-type'] = this.options.contentType +
+ (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+ /* Force "Connection: close" for older Mozilla browsers to work
+ * around a bug where XMLHttpRequest sends an incorrect
+ * Content-length header. See Mozilla Bugzilla #246651.
+ */
+ if (this.transport.overrideMimeType &&
+ (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+ headers['Connection'] = 'close';
+ }
+
+ // user-defined headers
+ if (typeof this.options.requestHeaders == 'object') {
+ var extras = this.options.requestHeaders;
+
+ if (typeof extras.push == 'function')
+ for (var i = 0, length = extras.length; i < length; i += 2)
+ headers[extras[i]] = extras[i+1];
+ else
+ $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+ }
+
+ for (var name in headers)
+ this.transport.setRequestHeader(name, headers[name]);
+ },
+
+ success: function() {
+ return !this.transport.status
+ || (this.transport.status >= 200 && this.transport.status < 300);
+ },
+
+ respondToReadyState: function(readyState) {
+ var state = Ajax.Request.Events[readyState];
+ var transport = this.transport, json = this.evalJSON();
+
+ if (state == 'Complete') {
+ try {
+ this._complete = true;
+ (this.options['on' + this.transport.status]
+ || this.options['on' + (this.success() ? 'Success' : 'Failure')]
+ || Prototype.emptyFunction)(transport, json);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+
+ if ((this.getHeader('Content-type') || 'text/javascript').strip().
+ match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
+ this.evalResponse();
+ }
+
+ try {
+ (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
+ Ajax.Responders.dispatch('on' + state, this, transport, json);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+
+ if (state == 'Complete') {
+ // avoid memory leak in MSIE: clean up
+ this.transport.onreadystatechange = Prototype.emptyFunction;
+ }
+ },
+
+ getHeader: function(name) {
try {
return this.transport.getResponseHeader(name);
- } catch (e) {}
+ } catch (e) { return null }
},
evalJSON: function() {
try {
- return eval('(' + this.header('X-JSON') + ')');
- } catch (e) {}
+ var json = this.getHeader('X-JSON');
+ return json ? eval('(' + json + ')') : null;
+ } catch (e) { return null }
},
evalResponse: function() {
@@ -744,35 +974,6 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
}
},
- respondToReadyState: function(readyState) {
- var event = Ajax.Request.Events[readyState];
- var transport = this.transport, json = this.evalJSON();
-
- if (event == 'Complete') {
- try {
- (this.options['on' + this.transport.status]
- || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
- || Prototype.emptyFunction)(transport, json);
- } catch (e) {
- this.dispatchException(e);
- }
-
- if ((this.header('Content-type') || '').match(/^text\/javascript/i))
- this.evalResponse();
- }
-
- try {
- (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
- Ajax.Responders.dispatch('on' + event, this, transport, json);
- } catch (e) {
- this.dispatchException(e);
- }
-
- /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
- if (event == 'Complete')
- this.transport.onreadystatechange = Prototype.emptyFunction;
- },
-
dispatchException: function(exception) {
(this.options.onException || Prototype.emptyFunction)(this, exception);
Ajax.Responders.dispatch('onException', this, exception);
@@ -783,41 +984,37 @@ Ajax.Updater = Class.create();
Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
initialize: function(container, url, options) {
- this.containers = {
- success: container.success ? $(container.success) : $(container),
- failure: container.failure ? $(container.failure) :
- (container.success ? null : $(container))
+ this.container = {
+ success: (container.success || container),
+ failure: (container.failure || (container.success ? null : container))
}
this.transport = Ajax.getTransport();
this.setOptions(options);
var onComplete = this.options.onComplete || Prototype.emptyFunction;
- this.options.onComplete = (function(transport, object) {
+ this.options.onComplete = (function(transport, param) {
this.updateContent();
- onComplete(transport, object);
+ onComplete(transport, param);
}).bind(this);
this.request(url);
},
updateContent: function() {
- var receiver = this.responseIsSuccess() ?
- this.containers.success : this.containers.failure;
+ var receiver = this.container[this.success() ? 'success' : 'failure'];
var response = this.transport.responseText;
- if (!this.options.evalScripts)
- response = response.stripScripts();
+ if (!this.options.evalScripts) response = response.stripScripts();
- if (receiver) {
- if (this.options.insertion) {
+ if (receiver = $(receiver)) {
+ if (this.options.insertion)
new this.options.insertion(receiver, response);
- } else {
- Element.update(receiver, response);
- }
+ else
+ receiver.update(response);
}
- if (this.responseIsSuccess()) {
+ if (this.success()) {
if (this.onComplete)
setTimeout(this.onComplete.bind(this), 10);
}
@@ -846,7 +1043,7 @@ Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
},
stop: function() {
- this.updater.onComplete = undefined;
+ this.updater.options.onComplete = undefined;
clearTimeout(this.timer);
(this.onComplete || Prototype.emptyFunction).apply(this, arguments);
},
@@ -866,25 +1063,43 @@ Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
this.updater = new Ajax.Updater(this.container, this.url, this.options);
}
});
-function $() {
- var results = [], element;
- for (var i = 0; i < arguments.length; i++) {
- element = arguments[i];
- if (typeof element == 'string')
- element = document.getElementById(element);
- results.push(Element.extend(element));
+function $(element) {
+ if (arguments.length > 1) {
+ for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+ elements.push($(arguments[i]));
+ return elements;
}
- return results.length < 2 ? results[0] : results;
+ if (typeof element == 'string')
+ element = document.getElementById(element);
+ return Element.extend(element);
+}
+
+if (Prototype.BrowserFeatures.XPath) {
+ document._getElementsByXPath = function(expression, parentElement) {
+ var results = [];
+ var query = document.evaluate(expression, $(parentElement) || document,
+ null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ for (var i = 0, length = query.snapshotLength; i < length; i++)
+ results.push(query.snapshotItem(i));
+ return results;
+ };
}
document.getElementsByClassName = function(className, parentElement) {
- var children = ($(parentElement) || document.body).getElementsByTagName('*');
- return $A(children).inject([], function(elements, child) {
- if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
- elements.push(Element.extend(child));
+ if (Prototype.BrowserFeatures.XPath) {
+ var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
+ return document._getElementsByXPath(q, parentElement);
+ } else {
+ var children = ($(parentElement) || document.body).getElementsByTagName('*');
+ var elements = [], child;
+ for (var i = 0, length = children.length; i < length; i++) {
+ child = children[i];
+ if (Element.hasClassName(child, className))
+ elements.push(Element.extend(child));
+ }
return elements;
- });
-}
+ }
+};
/*--------------------------------------------------------------------------*/
@@ -892,21 +1107,28 @@ if (!window.Element)
var Element = new Object();
Element.extend = function(element) {
- if (!element) return;
- if (_nativeExtensions) return element;
+ if (!element || _nativeExtensions || element.nodeType == 3) return element;
if (!element._extended && element.tagName && element != window) {
- var methods = Element.Methods, cache = Element.extend.cache;
- for (property in methods) {
+ var methods = Object.clone(Element.Methods), cache = Element.extend.cache;
+
+ if (element.tagName == 'FORM')
+ Object.extend(methods, Form.Methods);
+ if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName))
+ Object.extend(methods, Form.Element.Methods);
+
+ Object.extend(methods, Element.Methods.Simulated);
+
+ for (var property in methods) {
var value = methods[property];
- if (typeof value == 'function')
+ if (typeof value == 'function' && !(property in element))
element[property] = cache.findOrStore(value);
}
}
element._extended = true;
return element;
-}
+};
Element.extend.cache = {
findOrStore: function(value) {
@@ -914,46 +1136,45 @@ Element.extend.cache = {
return value.apply(null, [this].concat($A(arguments)));
}
}
-}
+};
Element.Methods = {
visible: function(element) {
return $(element).style.display != 'none';
},
- toggle: function() {
- for (var i = 0; i < arguments.length; i++) {
- var element = $(arguments[i]);
- Element[Element.visible(element) ? 'hide' : 'show'](element);
- }
+ toggle: function(element) {
+ element = $(element);
+ Element[Element.visible(element) ? 'hide' : 'show'](element);
+ return element;
},
- hide: function() {
- for (var i = 0; i < arguments.length; i++) {
- var element = $(arguments[i]);
- element.style.display = 'none';
- }
+ hide: function(element) {
+ $(element).style.display = 'none';
+ return element;
},
- show: function() {
- for (var i = 0; i < arguments.length; i++) {
- var element = $(arguments[i]);
- element.style.display = '';
- }
+ show: function(element) {
+ $(element).style.display = '';
+ return element;
},
remove: function(element) {
element = $(element);
element.parentNode.removeChild(element);
+ return element;
},
update: function(element, html) {
+ html = typeof html == 'undefined' ? '' : html.toString();
$(element).innerHTML = html.stripScripts();
setTimeout(function() {html.evalScripts()}, 10);
+ return element;
},
replace: function(element, html) {
element = $(element);
+ html = typeof html == 'undefined' ? '' : html.toString();
if (element.outerHTML) {
element.outerHTML = html.stripScripts();
} else {
@@ -963,11 +1184,106 @@ Element.Methods = {
range.createContextualFragment(html.stripScripts()), element);
}
setTimeout(function() {html.evalScripts()}, 10);
+ return element;
+ },
+
+ inspect: function(element) {
+ element = $(element);
+ var result = '<' + element.tagName.toLowerCase();
+ $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+ var property = pair.first(), attribute = pair.last();
+ var value = (element[property] || '').toString();
+ if (value) result += ' ' + attribute + '=' + value.inspect(true);
+ });
+ return result + '>';
+ },
+
+ recursivelyCollect: function(element, property) {
+ element = $(element);
+ var elements = [];
+ while (element = element[property])
+ if (element.nodeType == 1)
+ elements.push(Element.extend(element));
+ return elements;
+ },
+
+ ancestors: function(element) {
+ return $(element).recursivelyCollect('parentNode');
+ },
+
+ descendants: function(element) {
+ return $A($(element).getElementsByTagName('*'));
+ },
+
+ immediateDescendants: function(element) {
+ if (!(element = $(element).firstChild)) return [];
+ while (element && element.nodeType != 1) element = element.nextSibling;
+ if (element) return [element].concat($(element).nextSiblings());
+ return [];
+ },
+
+ previousSiblings: function(element) {
+ return $(element).recursivelyCollect('previousSibling');
+ },
+
+ nextSiblings: function(element) {
+ return $(element).recursivelyCollect('nextSibling');
+ },
+
+ siblings: function(element) {
+ element = $(element);
+ return element.previousSiblings().reverse().concat(element.nextSiblings());
+ },
+
+ match: function(element, selector) {
+ if (typeof selector == 'string')
+ selector = new Selector(selector);
+ return selector.match($(element));
+ },
+
+ up: function(element, expression, index) {
+ return Selector.findElement($(element).ancestors(), expression, index);
+ },
+
+ down: function(element, expression, index) {
+ return Selector.findElement($(element).descendants(), expression, index);
+ },
+
+ previous: function(element, expression, index) {
+ return Selector.findElement($(element).previousSiblings(), expression, index);
+ },
+
+ next: function(element, expression, index) {
+ return Selector.findElement($(element).nextSiblings(), expression, index);
+ },
+
+ getElementsBySelector: function() {
+ var args = $A(arguments), element = $(args.shift());
+ return Selector.findChildElements(element, args);
+ },
+
+ getElementsByClassName: function(element, className) {
+ return document.getElementsByClassName(className, element);
+ },
+
+ readAttribute: function(element, name) {
+ element = $(element);
+ if (document.all && !window.opera) {
+ var t = Element._attributeTranslations;
+ if (t.values[name]) return t.values[name](element, name);
+ if (t.names[name]) name = t.names[name];
+ var attribute = element.attributes[name];
+ if(attribute) return attribute.nodeValue;
+ }
+ return element.getAttribute(name);
},
getHeight: function(element) {
- element = $(element);
- return element.offsetHeight;
+ return $(element).getDimensions().height;
+ },
+
+ getWidth: function(element) {
+ return $(element).getDimensions().width;
},
classNames: function(element) {
@@ -976,34 +1292,60 @@ Element.Methods = {
hasClassName: function(element, className) {
if (!(element = $(element))) return;
- return Element.classNames(element).include(className);
+ var elementClassName = element.className;
+ if (elementClassName.length == 0) return false;
+ if (elementClassName == className ||
+ elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+ return true;
+ return false;
},
addClassName: function(element, className) {
if (!(element = $(element))) return;
- return Element.classNames(element).add(className);
+ Element.classNames(element).add(className);
+ return element;
},
removeClassName: function(element, className) {
if (!(element = $(element))) return;
- return Element.classNames(element).remove(className);
+ Element.classNames(element).remove(className);
+ return element;
+ },
+
+ toggleClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
+ return element;
+ },
+
+ observe: function() {
+ Event.observe.apply(Event, arguments);
+ return $A(arguments).first();
+ },
+
+ stopObserving: function() {
+ Event.stopObserving.apply(Event, arguments);
+ return $A(arguments).first();
},
// removes whitespace-only text node children
cleanWhitespace: function(element) {
element = $(element);
- for (var i = 0; i < element.childNodes.length; i++) {
- var node = element.childNodes[i];
+ var node = element.firstChild;
+ while (node) {
+ var nextNode = node.nextSibling;
if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
- Element.remove(node);
+ element.removeChild(node);
+ node = nextNode;
}
+ return element;
},
empty: function(element) {
return $(element).innerHTML.match(/^\s*$/);
},
- childOf: function(element, ancestor) {
+ descendantOf: function(element, ancestor) {
element = $(element), ancestor = $(ancestor);
while (element = element.parentNode)
if (element == ancestor) return true;
@@ -1012,38 +1354,69 @@ Element.Methods = {
scrollTo: function(element) {
element = $(element);
- var x = element.x ? element.x : element.offsetLeft,
- y = element.y ? element.y : element.offsetTop;
- window.scrollTo(x, y);
+ var pos = Position.cumulativeOffset(element);
+ window.scrollTo(pos[0], pos[1]);
+ return element;
},
getStyle: function(element, style) {
element = $(element);
- var value = element.style[style.camelize()];
+ if (['float','cssFloat'].include(style))
+ style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat');
+ style = style.camelize();
+ var value = element.style[style];
if (!value) {
if (document.defaultView && document.defaultView.getComputedStyle) {
var css = document.defaultView.getComputedStyle(element, null);
- value = css ? css.getPropertyValue(style) : null;
+ value = css ? css[style] : null;
} else if (element.currentStyle) {
- value = element.currentStyle[style.camelize()];
+ value = element.currentStyle[style];
}
}
+ if((value == 'auto') && ['width','height'].include(style) && (element.getStyle('display') != 'none'))
+ value = element['offset'+style.capitalize()] + 'px';
+
if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
if (Element.getStyle(element, 'position') == 'static') value = 'auto';
-
+ if(style == 'opacity') {
+ if(value) return parseFloat(value);
+ if(value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+ if(value[1]) return parseFloat(value[1]) / 100;
+ return 1.0;
+ }
return value == 'auto' ? null : value;
},
setStyle: function(element, style) {
element = $(element);
- for (var name in style)
- element.style[name.camelize()] = style[name];
+ for (var name in style) {
+ var value = style[name];
+ if(name == 'opacity') {
+ if (value == 1) {
+ value = (/Gecko/.test(navigator.userAgent) &&
+ !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0;
+ if(/MSIE/.test(navigator.userAgent) && !window.opera)
+ element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+ } else if(value === '') {
+ if(/MSIE/.test(navigator.userAgent) && !window.opera)
+ element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+ } else {
+ if(value < 0.00001) value = 0;
+ if(/MSIE/.test(navigator.userAgent) && !window.opera)
+ element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
+ 'alpha(opacity='+value*100+')';
+ }
+ } else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
+ element.style[name.camelize()] = value;
+ }
+ return element;
},
getDimensions: function(element) {
element = $(element);
- if (Element.getStyle(element, 'display') != 'none')
+ var display = $(element).getStyle('display');
+ if (display != 'none' && display != null) // Safari bug
return {width: element.offsetWidth, height: element.offsetHeight};
// All *Width and *Height properties give 0 on elements with display none,
@@ -1051,12 +1424,13 @@ Element.Methods = {
var els = element.style;
var originalVisibility = els.visibility;
var originalPosition = els.position;
+ var originalDisplay = els.display;
els.visibility = 'hidden';
els.position = 'absolute';
- els.display = '';
+ els.display = 'block';
var originalWidth = element.clientWidth;
var originalHeight = element.clientHeight;
- els.display = 'none';
+ els.display = originalDisplay;
els.position = originalPosition;
els.visibility = originalVisibility;
return {width: originalWidth, height: originalHeight};
@@ -1075,6 +1449,7 @@ Element.Methods = {
element.style.left = 0;
}
}
+ return element;
},
undoPositioned: function(element) {
@@ -1087,49 +1462,153 @@ Element.Methods = {
element.style.bottom =
element.style.right = '';
}
+ return element;
},
makeClipping: function(element) {
element = $(element);
- if (element._overflow) return;
- element._overflow = element.style.overflow;
+ if (element._overflow) return element;
+ element._overflow = element.style.overflow || 'auto';
if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
element.style.overflow = 'hidden';
+ return element;
},
undoClipping: function(element) {
element = $(element);
- if (element._overflow) return;
- element.style.overflow = element._overflow;
- element._overflow = undefined;
+ if (!element._overflow) return element;
+ element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+ element._overflow = null;
+ return element;
}
-}
+};
+
+Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf});
+
+Element._attributeTranslations = {};
+
+Element._attributeTranslations.names = {
+ colspan: "colSpan",
+ rowspan: "rowSpan",
+ valign: "vAlign",
+ datetime: "dateTime",
+ accesskey: "accessKey",
+ tabindex: "tabIndex",
+ enctype: "encType",
+ maxlength: "maxLength",
+ readonly: "readOnly",
+ longdesc: "longDesc"
+};
+
+Element._attributeTranslations.values = {
+ _getAttr: function(element, attribute) {
+ return element.getAttribute(attribute, 2);
+ },
+
+ _flag: function(element, attribute) {
+ return $(element).hasAttribute(attribute) ? attribute : null;
+ },
+
+ style: function(element) {
+ return element.style.cssText.toLowerCase();
+ },
+
+ title: function(element) {
+ var node = element.getAttributeNode('title');
+ return node.specified ? node.nodeValue : null;
+ }
+};
+
+Object.extend(Element._attributeTranslations.values, {
+ href: Element._attributeTranslations.values._getAttr,
+ src: Element._attributeTranslations.values._getAttr,
+ disabled: Element._attributeTranslations.values._flag,
+ checked: Element._attributeTranslations.values._flag,
+ readonly: Element._attributeTranslations.values._flag,
+ multiple: Element._attributeTranslations.values._flag
+});
+
+Element.Methods.Simulated = {
+ hasAttribute: function(element, attribute) {
+ var t = Element._attributeTranslations;
+ attribute = t.names[attribute] || attribute;
+ return $(element).getAttributeNode(attribute).specified;
+ }
+};
+
+// IE is missing .innerHTML support for TABLE-related elements
+if (document.all && !window.opera){
+ Element.Methods.update = function(element, html) {
+ element = $(element);
+ html = typeof html == 'undefined' ? '' : html.toString();
+ var tagName = element.tagName.toUpperCase();
+ if (['THEAD','TBODY','TR','TD'].include(tagName)) {
+ var div = document.createElement('div');
+ switch (tagName) {
+ case 'THEAD':
+ case 'TBODY':
+ div.innerHTML = '' + html.stripScripts() + '
';
+ depth = 2;
+ break;
+ case 'TR':
+ div.innerHTML = '' + html.stripScripts() + '
';
+ depth = 3;
+ break;
+ case 'TD':
+ div.innerHTML = '| ' + html.stripScripts() + ' |
';
+ depth = 4;
+ }
+ $A(element.childNodes).each(function(node){
+ element.removeChild(node)
+ });
+ depth.times(function(){ div = div.firstChild });
+
+ $A(div.childNodes).each(
+ function(node){ element.appendChild(node) });
+ } else {
+ element.innerHTML = html.stripScripts();
+ }
+ setTimeout(function() {html.evalScripts()}, 10);
+ return element;
+ }
+};
Object.extend(Element, Element.Methods);
var _nativeExtensions = false;
-if(!HTMLElement && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
- var HTMLElement = {}
- HTMLElement.prototype = document.createElement('div').__proto__;
-}
+if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+ ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) {
+ var className = 'HTML' + tag + 'Element';
+ if(window[className]) return;
+ var klass = window[className] = {};
+ klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__;
+ });
Element.addMethods = function(methods) {
Object.extend(Element.Methods, methods || {});
- if(typeof HTMLElement != 'undefined') {
- var methods = Element.Methods, cache = Element.extend.cache;
- for (property in methods) {
+ function copy(methods, destination, onlyIfAbsent) {
+ onlyIfAbsent = onlyIfAbsent || false;
+ var cache = Element.extend.cache;
+ for (var property in methods) {
var value = methods[property];
- if (typeof value == 'function')
- HTMLElement.prototype[property] = cache.findOrStore(value);
+ if (!onlyIfAbsent || !(property in destination))
+ destination[property] = cache.findOrStore(value);
}
+ }
+
+ if (typeof HTMLElement != 'undefined') {
+ copy(Element.Methods, HTMLElement.prototype);
+ copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+ copy(Form.Methods, HTMLFormElement.prototype);
+ [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) {
+ copy(Form.Element.Methods, klass.prototype);
+ });
_nativeExtensions = true;
}
}
-Element.addMethods();
-
var Toggle = new Object();
Toggle.display = Element.toggle;
@@ -1148,8 +1627,8 @@ Abstract.Insertion.prototype = {
try {
this.element.insertAdjacentHTML(this.adjacency, this.content);
} catch (e) {
- var tagName = this.element.tagName.toLowerCase();
- if (tagName == 'tbody' || tagName == 'tr') {
+ var tagName = this.element.tagName.toUpperCase();
+ if (['TBODY', 'TR'].include(tagName)) {
this.insertContent(this.contentFromAnonymousTable());
} else {
throw e;
@@ -1248,20 +1727,18 @@ Element.ClassNames.prototype = {
add: function(classNameToAdd) {
if (this.include(classNameToAdd)) return;
- this.set(this.toArray().concat(classNameToAdd).join(' '));
+ this.set($A(this).concat(classNameToAdd).join(' '));
},
remove: function(classNameToRemove) {
if (!this.include(classNameToRemove)) return;
- this.set(this.select(function(className) {
- return className != classNameToRemove;
- }).join(' '));
+ this.set($A(this).without(classNameToRemove).join(' '));
},
toString: function() {
- return this.toArray().join(' ');
+ return $A(this).join(' ');
}
-}
+};
Object.extend(Element.ClassNames.prototype, Enumerable);
var Selector = Class.create();
@@ -1308,15 +1785,15 @@ Selector.prototype = {
if (params.wildcard)
conditions.push('true');
if (clause = params.id)
- conditions.push('element.id == ' + clause.inspect());
+ conditions.push('element.readAttribute("id") == ' + clause.inspect());
if (clause = params.tagName)
conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
if ((clause = params.classNames).length > 0)
- for (var i = 0; i < clause.length; i++)
- conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')');
+ for (var i = 0, length = clause.length; i < length; i++)
+ conditions.push('element.hasClassName(' + clause[i].inspect() + ')');
if (clause = params.attributes) {
clause.each(function(attribute) {
- var value = 'element.getAttribute(' + attribute.name.inspect() + ')';
+ var value = 'element.readAttribute(' + attribute.name.inspect() + ')';
var splitValueBy = function(delimiter) {
return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
}
@@ -1329,7 +1806,7 @@ Selector.prototype = {
); break;
case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break;
case '':
- case undefined: conditions.push(value + ' != null'); break;
+ case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break;
default: throw 'Unknown operator ' + attribute.operator + ' in selector';
}
});
@@ -1340,6 +1817,7 @@ Selector.prototype = {
compileMatcher: function() {
this.match = new Function('element', 'if (!element.tagName) return false; \
+ element = $(element); \
return ' + this.buildMatchExpression());
},
@@ -1354,7 +1832,7 @@ Selector.prototype = {
scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
var results = [];
- for (var i = 0; i < scope.length; i++)
+ for (var i = 0, length = scope.length; i < length; i++)
if (this.match(element = scope[i]))
results.push(Element.extend(element));
@@ -1366,206 +1844,241 @@ Selector.prototype = {
}
}
-function $$() {
- return $A(arguments).map(function(expression) {
- return expression.strip().split(/\s+/).inject([null], function(results, expr) {
- var selector = new Selector(expr);
- return results.map(selector.findElements.bind(selector)).flatten();
- });
- }).flatten();
-}
-var Field = {
- clear: function() {
- for (var i = 0; i < arguments.length; i++)
- $(arguments[i]).value = '';
+Object.extend(Selector, {
+ matchElements: function(elements, expression) {
+ var selector = new Selector(expression);
+ return elements.select(selector.match.bind(selector)).map(Element.extend);
},
- focus: function(element) {
- $(element).focus();
+ findElement: function(elements, expression, index) {
+ if (typeof expression == 'number') index = expression, expression = false;
+ return Selector.matchElements(elements, expression || '*')[index || 0];
},
- present: function() {
- for (var i = 0; i < arguments.length; i++)
- if ($(arguments[i]).value == '') return false;
- return true;
- },
-
- select: function(element) {
- $(element).select();
- },
-
- activate: function(element) {
- element = $(element);
- element.focus();
- if (element.select)
- element.select();
+ findChildElements: function(element, expressions) {
+ return expressions.map(function(expression) {
+ return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) {
+ var selector = new Selector(expr);
+ return results.inject([], function(elements, result) {
+ return elements.concat(selector.findElements(result || element));
+ });
+ });
+ }).flatten();
}
+});
+
+function $$() {
+ return Selector.findChildElements(document, $A(arguments));
}
-
-/*--------------------------------------------------------------------------*/
-
var Form = {
- serialize: function(form) {
- var elements = Form.getElements($(form));
- var queryComponents = new Array();
+ reset: function(form) {
+ $(form).reset();
+ return form;
+ },
- for (var i = 0; i < elements.length; i++) {
- var queryComponent = Form.Element.serialize(elements[i]);
- if (queryComponent)
- queryComponents.push(queryComponent);
- }
+ serializeElements: function(elements, getHash) {
+ var data = elements.inject({}, function(result, element) {
+ if (!element.disabled && element.name) {
+ var key = element.name, value = $(element).getValue();
+ if (value != undefined) {
+ if (result[key]) {
+ if (result[key].constructor != Array) result[key] = [result[key]];
+ result[key].push(value);
+ }
+ else result[key] = value;
+ }
+ }
+ return result;
+ });
- return queryComponents.join('&');
+ return getHash ? data : Hash.toQueryString(data);
+ }
+};
+
+Form.Methods = {
+ serialize: function(form, getHash) {
+ return Form.serializeElements(Form.getElements(form), getHash);
},
getElements: function(form) {
- form = $(form);
- var elements = new Array();
-
- for (var tagName in Form.Element.Serializers) {
- var tagElements = form.getElementsByTagName(tagName);
- for (var j = 0; j < tagElements.length; j++)
- elements.push(tagElements[j]);
- }
- return elements;
+ return $A($(form).getElementsByTagName('*')).inject([],
+ function(elements, child) {
+ if (Form.Element.Serializers[child.tagName.toLowerCase()])
+ elements.push(Element.extend(child));
+ return elements;
+ }
+ );
},
getInputs: function(form, typeName, name) {
form = $(form);
var inputs = form.getElementsByTagName('input');
- if (!typeName && !name)
- return inputs;
+ if (!typeName && !name) return $A(inputs).map(Element.extend);
- var matchingInputs = new Array();
- for (var i = 0; i < inputs.length; i++) {
+ for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
var input = inputs[i];
- if ((typeName && input.type != typeName) ||
- (name && input.name != name))
+ if ((typeName && input.type != typeName) || (name && input.name != name))
continue;
- matchingInputs.push(input);
+ matchingInputs.push(Element.extend(input));
}
return matchingInputs;
},
disable: function(form) {
- var elements = Form.getElements(form);
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
+ form = $(form);
+ form.getElements().each(function(element) {
element.blur();
element.disabled = 'true';
- }
+ });
+ return form;
},
enable: function(form) {
- var elements = Form.getElements(form);
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
+ form = $(form);
+ form.getElements().each(function(element) {
element.disabled = '';
- }
+ });
+ return form;
},
findFirstElement: function(form) {
- return Form.getElements(form).find(function(element) {
+ return $(form).getElements().find(function(element) {
return element.type != 'hidden' && !element.disabled &&
['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
});
},
focusFirstElement: function(form) {
- Field.activate(Form.findFirstElement(form));
- },
-
- reset: function(form) {
- $(form).reset();
+ form = $(form);
+ form.findFirstElement().activate();
+ return form;
}
}
+Object.extend(Form, Form.Methods);
+
+/*--------------------------------------------------------------------------*/
+
Form.Element = {
+ focus: function(element) {
+ $(element).focus();
+ return element;
+ },
+
+ select: function(element) {
+ $(element).select();
+ return element;
+ }
+}
+
+Form.Element.Methods = {
serialize: function(element) {
element = $(element);
- var method = element.tagName.toLowerCase();
- var parameter = Form.Element.Serializers[method](element);
-
- if (parameter) {
- var key = encodeURIComponent(parameter[0]);
- if (key.length == 0) return;
-
- if (parameter[1].constructor != Array)
- parameter[1] = [parameter[1]];
-
- return parameter[1].map(function(value) {
- return key + '=' + encodeURIComponent(value);
- }).join('&');
+ if (!element.disabled && element.name) {
+ var value = element.getValue();
+ if (value != undefined) {
+ var pair = {};
+ pair[element.name] = value;
+ return Hash.toQueryString(pair);
+ }
}
+ return '';
},
getValue: function(element) {
element = $(element);
var method = element.tagName.toLowerCase();
- var parameter = Form.Element.Serializers[method](element);
+ return Form.Element.Serializers[method](element);
+ },
- if (parameter)
- return parameter[1];
+ clear: function(element) {
+ $(element).value = '';
+ return element;
+ },
+
+ present: function(element) {
+ return $(element).value != '';
+ },
+
+ activate: function(element) {
+ element = $(element);
+ element.focus();
+ if (element.select && ( element.tagName.toLowerCase() != 'input' ||
+ !['button', 'reset', 'submit'].include(element.type) ) )
+ element.select();
+ return element;
+ },
+
+ disable: function(element) {
+ element = $(element);
+ element.disabled = true;
+ return element;
+ },
+
+ enable: function(element) {
+ element = $(element);
+ element.blur();
+ element.disabled = false;
+ return element;
}
}
+Object.extend(Form.Element, Form.Element.Methods);
+var Field = Form.Element;
+var $F = Form.Element.getValue;
+
+/*--------------------------------------------------------------------------*/
+
Form.Element.Serializers = {
input: function(element) {
switch (element.type.toLowerCase()) {
- case 'submit':
- case 'hidden':
- case 'password':
- case 'text':
- return Form.Element.Serializers.textarea(element);
case 'checkbox':
case 'radio':
return Form.Element.Serializers.inputSelector(element);
+ default:
+ return Form.Element.Serializers.textarea(element);
}
- return false;
},
inputSelector: function(element) {
- if (element.checked)
- return [element.name, element.value];
+ return element.checked ? element.value : null;
},
textarea: function(element) {
- return [element.name, element.value];
+ return element.value;
},
select: function(element) {
- return Form.Element.Serializers[element.type == 'select-one' ?
+ return this[element.type == 'select-one' ?
'selectOne' : 'selectMany'](element);
},
selectOne: function(element) {
- var value = '', opt, index = element.selectedIndex;
- if (index >= 0) {
- opt = element.options[index];
- value = opt.value || opt.text;
- }
- return [element.name, value];
+ var index = element.selectedIndex;
+ return index >= 0 ? this.optionValue(element.options[index]) : null;
},
selectMany: function(element) {
- var value = [];
- for (var i = 0; i < element.length; i++) {
+ var values, length = element.length;
+ if (!length) return null;
+
+ for (var i = 0, values = []; i < length; i++) {
var opt = element.options[i];
- if (opt.selected)
- value.push(opt.value || opt.text);
+ if (opt.selected) values.push(this.optionValue(opt));
}
- return [element.name, value];
+ return values;
+ },
+
+ optionValue: function(opt) {
+ // extend element because hasAttribute may not be native
+ return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
}
}
/*--------------------------------------------------------------------------*/
-var $F = Form.Element.getValue;
-
-/*--------------------------------------------------------------------------*/
-
Abstract.TimedObserver = function() {}
Abstract.TimedObserver.prototype = {
initialize: function(element, frequency, callback) {
@@ -1583,7 +2096,9 @@ Abstract.TimedObserver.prototype = {
onTimerEvent: function() {
var value = this.getValue();
- if (this.lastValue != value) {
+ var changed = ('string' == typeof this.lastValue && 'string' == typeof value
+ ? this.lastValue != value : String(this.lastValue) != String(value));
+ if (changed) {
this.callback(this.element, value);
this.lastValue = value;
}
@@ -1628,9 +2143,7 @@ Abstract.EventObserver.prototype = {
},
registerFormCallbacks: function() {
- var elements = Form.getElements(this.element);
- for (var i = 0; i < elements.length; i++)
- this.registerCallback(elements[i]);
+ Form.getElements(this.element).each(this.registerCallback.bind(this));
},
registerCallback: function(element) {
@@ -1640,11 +2153,7 @@ Abstract.EventObserver.prototype = {
case 'radio':
Event.observe(element, 'click', this.onElementEvent.bind(this));
break;
- case 'password':
- case 'text':
- case 'textarea':
- case 'select-one':
- case 'select-multiple':
+ default:
Event.observe(element, 'change', this.onElementEvent.bind(this));
break;
}
@@ -1679,6 +2188,10 @@ Object.extend(Event, {
KEY_RIGHT: 39,
KEY_DOWN: 40,
KEY_DELETE: 46,
+ KEY_HOME: 36,
+ KEY_END: 35,
+ KEY_PAGEUP: 33,
+ KEY_PAGEDOWN: 34,
element: function(event) {
return event.target || event.srcElement;
@@ -1734,7 +2247,7 @@ Object.extend(Event, {
unloadCache: function() {
if (!Event.observers) return;
- for (var i = 0; i < Event.observers.length; i++) {
+ for (var i = 0, length = Event.observers.length; i < length; i++) {
Event.stopObserving.apply(this, Event.observers[i]);
Event.observers[i][0] = null;
}
@@ -1742,7 +2255,7 @@ Object.extend(Event, {
},
observe: function(element, name, observer, useCapture) {
- var element = $(element);
+ element = $(element);
useCapture = useCapture || false;
if (name == 'keypress' &&
@@ -1750,11 +2263,11 @@ Object.extend(Event, {
|| element.attachEvent))
name = 'keydown';
- this._observeAndCache(element, name, observer, useCapture);
+ Event._observeAndCache(element, name, observer, useCapture);
},
stopObserving: function(element, name, observer, useCapture) {
- var element = $(element);
+ element = $(element);
useCapture = useCapture || false;
if (name == 'keypress' &&
@@ -1765,7 +2278,9 @@ Object.extend(Event, {
if (element.removeEventListener) {
element.removeEventListener(name, observer, useCapture);
} else if (element.detachEvent) {
- element.detachEvent('on' + name, observer);
+ try {
+ element.detachEvent('on' + name, observer);
+ } catch (e) {}
}
}
});
@@ -1819,7 +2334,8 @@ var Position = {
valueL += element.offsetLeft || 0;
element = element.offsetParent;
if (element) {
- p = Element.getStyle(element, 'position');
+ if(element.tagName=='BODY') break;
+ var p = Element.getStyle(element, 'position');
if (p == 'relative' || p == 'absolute') break;
}
} while (element);
@@ -1875,17 +2391,6 @@ var Position = {
element.offsetWidth;
},
- clone: function(source, target) {
- source = $(source);
- target = $(target);
- target.style.position = 'absolute';
- var offsets = this.cumulativeOffset(source);
- target.style.top = offsets[1] + 'px';
- target.style.left = offsets[0] + 'px';
- target.style.width = source.offsetWidth + 'px';
- target.style.height = source.offsetHeight + 'px';
- },
-
page: function(forElement) {
var valueT = 0, valueL = 0;
@@ -1902,8 +2407,10 @@ var Position = {
element = forElement;
do {
- valueT -= element.scrollTop || 0;
- valueL -= element.scrollLeft || 0;
+ if (!window.opera || element.tagName=='BODY') {
+ valueT -= element.scrollTop || 0;
+ valueL -= element.scrollLeft || 0;
+ }
} while (element = element.parentNode);
return [valueL, valueT];
@@ -1964,10 +2471,10 @@ var Position = {
element._originalHeight = element.style.height;
element.style.position = 'absolute';
- element.style.top = top + 'px';;
- element.style.left = left + 'px';;
- element.style.width = width + 'px';;
- element.style.height = height + 'px';;
+ element.style.top = top + 'px';
+ element.style.left = left + 'px';
+ element.style.width = width + 'px';
+ element.style.height = height + 'px';
},
relativize: function(element) {
@@ -2003,4 +2510,6 @@ if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
return [valueL, valueT];
}
-}
\ No newline at end of file
+}
+
+Element.addMethods();
\ No newline at end of file
diff --git a/data/msfweb/public/javascripts/tooltip.js b/data/msfweb/public/javascripts/tooltip.js
new file mode 100644
index 0000000000..4b9ac45a3f
--- /dev/null
+++ b/data/msfweb/public/javascripts/tooltip.js
@@ -0,0 +1,239 @@
+// Singleton class TooltipWindow
+// This class works with special className. The tooltip content could be in your HTML page as an hidden element or
+// can be retreive by an AJAX call.
+//
+// To work, You just need to set two class name on elements that should show tooltips
+// - One to say to TooltipManager that this element must have a tooltip ('tooltip' by default)
+// - Another to indicate how to find the tooltip content
+// It could be html_XXXX if tootltip content is somewhere hidden in your page, XXX must be DOM ID of this hidden element
+// It could be ajax_XXXX if tootltip content must be find by an ajax request, XXX will be the string send as id parameter to your server.
+// Check samples/tooltips/tooltip.html to see how it works
+//
+TooltipManager = {
+ options: {cssClassName: 'tooltip', delayOver: 200, delayOut: 1000, shiftX: 10, shiftY: 10,
+ className: 'alphacube', width: 200, height: null,
+ draggable: false, minimizable: false, maximizable: false, showEffect: Element.show, hideEffect: Element.hide},
+ ajaxInfo: null,
+ elements: null,
+ showTimer: null,
+ hideTimer: null,
+
+ // Init tooltip manager
+ // parameters:
+ // - cssClassName (string) : CSS class name where tooltip should be shown.
+ // - ajaxOptions (hash) : Ajax options for ajax tooltip.
+ // For examples {url: "/tooltip/get.php", options: {method: 'get'}}
+ // see Ajax.Request documentation for details
+ //- tooltipOptions (hash) : available keys
+ // - delayOver: int in ms (default 10) delay before showing tooltip
+ // - delayOut: int in ms (default 1000) delay before hidding tooltip
+ // - shiftX: int in pixels (default 10) left shift of the tooltip window
+ // - shiftY: int in pixels (default 10) top shift of the tooltip window
+ // and All window options like showEffect: Element.show, hideEffect: Element.hide to remove animation
+ // default: {className: 'alphacube', width: 200, height: null, draggable: false, minimizable: false, maximizable: false}
+
+ init: function(cssClassName, ajaxInfo, tooltipOptions) {
+ TooltipManager.options = Object.extend(TooltipManager.options, tooltipOptions || {});
+
+ cssClassName = TooltipManager.options.cssClassName || "tooltip";
+ TooltipManager.ajaxInfo = ajaxInfo;
+ TooltipManager.elements = $$("." + cssClassName);
+ TooltipManager.elements.each(function(element) {
+ element = $(element)
+ var info = TooltipManager._getInfo(element);
+ if (info.ajax) {
+ element.ajaxId = info.id;
+ element.ajaxInfo = ajaxInfo;
+ }
+ else {
+ element.tooltipElement = $(info.id);
+ }
+ element.observe("mouseover", TooltipManager._mouseOver);
+ element.observe("mouseout", TooltipManager._mouseOut);
+ });
+ Windows.addObserver(this);
+ },
+
+ addHTML: function(element, tooltipElement) {
+ element = $(element);
+ tooltipElement = $(tooltipElement);
+ element.tooltipElement = tooltipElement;
+
+ element.observe("mouseover", TooltipManager._mouseOver);
+ element.observe("mouseout", TooltipManager._mouseOut);
+ },
+
+ addAjax: function(element, ajaxInfo) {
+ element = $(element);
+ element.ajaxInfo = ajaxInfo;
+ element.observe("mouseover", TooltipManager._mouseOver);
+ element.observe("mouseout", TooltipManager._mouseOut);
+ },
+
+ addURL: function(element, url, width, height) {
+ element = $(element);
+ element.url = url;
+ element.frameWidth = width;
+ element.frameHeight = height;
+ element.observe("mouseover", TooltipManager._mouseOver);
+ element.observe("mouseout", TooltipManager._mouseOut);
+ },
+
+ close: function() {
+ if (TooltipManager.tooltipWindow)
+ TooltipManager.tooltipWindow.hide();
+ },
+
+ preloadImages: function(path, images, extension) {
+ if (!extension)
+ extension = ".gif";
+
+ //preload images
+ $A(images).each(function(i) {
+ var image = new Image();
+ image.src= path + "/" + i + extension;
+ });
+ },
+
+ _showTooltip: function(element) {
+ if (this.element == element)
+ return;
+ // Get original element
+ while (element && (!element.tooltipElement && !element.ajaxInfo && !element.url))
+ element = element.parentNode;
+ this.element = element;
+
+ TooltipManager.showTimer = null;
+ if (TooltipManager.hideTimer)
+ clearTimeout(TooltipManager.hideTimer);
+
+ var position = Position.cumulativeOffset(element);
+ var dimension = element.getDimensions();
+
+ if (! this.tooltipWindow)
+ this.tooltipWindow = new Window("__tooltip__", TooltipManager.options);
+
+ this.tooltipWindow.hide();
+ this.tooltipWindow.setLocation(position[1] + dimension.height + TooltipManager.options.shiftY, position[0] + TooltipManager.options.shiftX);
+
+ Event.observe(this.tooltipWindow.element, "mouseover", function(event) {TooltipManager._tooltipOver(event, element)});
+ Event.observe(this.tooltipWindow.element, "mouseout", function(event) {TooltipManager._tooltipOut(event, element)});
+
+ // Reset width/height for computation
+ this.tooltipWindow.height = TooltipManager.options.height;
+ this.tooltipWindow.width = TooltipManager.options.width;
+
+ // Ajax content
+ if (element.ajaxInfo) {
+ var p = element.ajaxInfo.options.parameters;
+ var saveParam = p;
+
+ // Set by CSS
+ if (element.ajaxId) {
+ if (p)
+ p += "&id=" + element.ajaxId;
+ else
+ p = "id=" + element.ajaxId;
+ }
+ element.ajaxInfo.options.parameters = p || "";
+ this.tooltipWindow.setHTMLContent("");
+ this.tooltipWindow.setAjaxContent(element.ajaxInfo.url, element.ajaxInfo.options);
+ element.ajaxInfo.options.parameters = saveParam;
+ }
+ // URL content
+ else if (element.url) {
+ this.tooltipWindow.setURL(element.url);
+ this.tooltipWindow.setSize(element.frameWidth, element.frameHeight);
+
+ // Set tooltip size
+ this.tooltipWindow.height = element.frameHeight;
+ this.tooltipWindow.width = element.frameWidth;
+ }
+ // HTML content
+ else
+ this.tooltipWindow.setHTMLContent(element.tooltipElement.innerHTML);
+
+ if (!element.ajaxInfo)
+ this.tooltipWindow.show();
+ },
+
+ _hideTooltip: function(element) {
+ if (this.tooltipWindow) {
+ this.tooltipWindow.hide();
+ this.element = null;
+ }
+ },
+
+ _mouseOver: function (event) {
+ var element = Event.element(event);
+ if (TooltipManager.showTimer)
+ clearTimeout(TooltipManager.showTimer);
+
+ TooltipManager.showTimer = setTimeout(function() {TooltipManager._showTooltip(element)}, TooltipManager.options.delayOver)
+ },
+
+ _mouseOut: function(event) {
+ var element = Event.element(event);
+ if (TooltipManager.showTimer) {
+ clearTimeout(TooltipManager.showTimer);
+ TooltipManager.showTimer = null;
+ return;
+ }
+ if (TooltipManager.tooltipWindow)
+ TooltipManager.hideTimer = setTimeout(function() {TooltipManager._hideTooltip(element)}, TooltipManager.options.delayOut)
+ },
+
+ _tooltipOver: function(event, element) {
+ if (TooltipManager.hideTimer) {
+ clearTimeout(TooltipManager.hideTimer);
+ TooltipManager.hideTimer = null;
+ }
+ },
+
+ _tooltipOut: function(event, element) {
+ if (TooltipManager.hideTimer == null)
+ TooltipManager.hideTimer = setTimeout(function() {TooltipManager._hideTooltip(element)}, TooltipManager.options.delayOut)
+ },
+
+ _getInfo: function(element) {
+ // Find html_ for static content
+ var id = element.className.split(' ').detect(function(name) {return name.indexOf("html_") == 0});
+ var ajax = true;
+ if (id)
+ ajax = false;
+ else
+ // Find ajax_ for ajax content
+ id = element.className.split(' ').detect(function(name) {return name.indexOf("ajax_") == 0});
+
+ id = id.substr(id.indexOf('_')+1, id.length)
+ return id ? {ajax: ajax, id: id} : null;
+ },
+
+ onBeforeShow: function(eventName, win) {
+ var top = parseFloat(win.getLocation().top);
+ var dim = win.element.getDimensions();
+
+ if (top + dim.height > TooltipManager._getScrollTop() + TooltipManager._getPageHeight()) {
+ var position = Position.cumulativeOffset(this.element);
+
+ var top = position[1] - TooltipManager.options.shiftY - dim.height;
+ win.setLocation(top, position[0] + TooltipManager.options.shiftX)
+ }
+ },
+
+ _getPageWidth: function(){
+ return window.innerWidth || document.documentElement.clientWidth || 0;
+ },
+
+ _getPageHeight: function(){
+ return window.innerHeight || document.documentElement.clientHeight || 0;
+ },
+
+ _getScrollTop: function(){
+ return document.documentElement.scrollTop || window.pageYOffset || 0;
+ },
+
+ _getScrollLeft: function(){
+ return document.documentElement.scrollLeft || window.pageXOffset || 0;
+ }
+};
diff --git a/data/msfweb/public/javascripts/window.js b/data/msfweb/public/javascripts/window.js
index 4a8b6d62eb..20378171d4 100644
--- a/data/msfweb/public/javascripts/window.js
+++ b/data/msfweb/public/javascripts/window.js
@@ -19,21 +19,41 @@
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-// VERSION 0.96.3
+// VERSION 1.1
var Window = Class.create();
+Window.keepMultiModalWindow = false;
Window.prototype = {
- // Constructor
- // Available parameters : className, title, minWidth, minHeight, maxWidth, maxHeight, width, height, top, left, bottom, right, resizable, zIndex, opacity,
- // hideEffect, showEffect, showEffectOptions, hideEffectOptions, effectOptions, url, draggable, closable, minimizable, maximizable, parent, onload
- initialize: function(id) {
- if ($(id))
- alert("Window " + id + " is already register is the DOM!!, be sure to use setDestroyOnClose()")
-
- this.hasEffectLib = String.prototype.parseColor != null;
- this.options = Object.extend({
- className: "dialog",
- minWidth: 100,
+ // Constructor
+ // Available parameters : className, title, minWidth, minHeight, maxWidth, maxHeight, width, height, top, left, bottom, right, resizable, zIndex, opacity, recenterAuto, wiredDrag
+ // hideEffect, showEffect, showEffectOptions, hideEffectOptions, effectOptions, url, draggable, closable, minimizable, maximizable, parent, onload
+ // add all callbacks (if you do not use an observer)
+ // onDestroy onStartResize onStartMove onResize onMove onEndResize onEndMove onFocus onBeforeShow onShow onHide onMinimize onMaximize onClose
+
+ initialize: function() {
+ var id;
+ var optionIndex = 0;
+ // For backward compatibility like win= new Window("id", {...}) instead of win = new Window({id: "id", ...})
+ if (arguments.length > 0) {
+ if (typeof arguments[0] == "string" ) {
+ id = arguments[0];
+ optionIndex = 1;
+ }
+ else
+ id = arguments[0] ? arguments[0].id : null;
+ }
+
+ // Generate unique ID if not specified
+ if (!id)
+ id = "window_" + new Date().getTime();
+
+ if ($(id))
+ alert("Window " + id + " is already registered in the DOM! Make sure you use setDestroyOnClose() or destroyOnClose: true in the constructor");
+
+ this.hasEffectLib = String.prototype.parseColor != null;
+ this.options = Object.extend({
+ className: "dialog",
+ minWidth: 100,
minHeight: 20,
resizable: true,
closable: true,
@@ -46,513 +66,713 @@ Window.prototype = {
showEffectOptions: {},
hideEffectOptions: {},
effectOptions: null,
- parent: document.getElementsByTagName("body").item(0),
+ parent: document.body,
title: " ",
url: null,
onload: Prototype.emptyFunction,
width: 200,
height: 300,
- opacity: 1
- }, arguments[1] || {});
-
- if (this.options.effectOptions) {
- Object.extend(this.options.hideEffectOptions, this.options.effectOptions);
- Object.extend(this.options.showEffectOptions, this.options.effectOptions);
- }
- if (this.options.hideEffect == Element.hide)
- this.options.hideEffect = function(){ Element.hide(this.element); if (this.destroyOnClose) this.destroy(); }.bind(this)
-
- this.element = this._createWindow(id);
-
- // Bind event listener
+ opacity: 1,
+ recenterAuto: true,
+ wiredDrag: false,
+ closeCallback: null,
+ destroyOnClose: false
+ }, arguments[optionIndex] || {});
+
+ if (typeof this.options.top == "undefined" && typeof this.options.bottom == "undefined")
+ this.options.top = Math.random()*500;
+ if (typeof this.options.left == "undefined" && typeof this.options.right == "undefined")
+ this.options.left = Math.random()*500;
+
+ if (this.options.effectOptions) {
+ Object.extend(this.options.hideEffectOptions, this.options.effectOptions);
+ Object.extend(this.options.showEffectOptions, this.options.effectOptions);
+ if (this.options.showEffect == Element.Appear)
+ this.options.showEffectOptions.to = this.options.opacity;
+ }
+ if (this.hasEffectLib) {
+ if (this.options.showEffect == Effect.Appear)
+ this.options.showEffectOptions.to = this.options.opacity;
+
+ if (this.options.hideEffect == Effect.Fade)
+ this.options.hideEffectOptions.from = this.options.opacity;
+ }
+ if (this.options.hideEffect == Element.hide)
+ this.options.hideEffect = function(){ Element.hide(this.element); if (this.options.destroyOnClose) this.destroy(); }.bind(this)
+
+ if (this.options.parent != document.body)
+ this.options.parent = $(this.options.parent);
+
+ this.element = this._createWindow(id);
+
+ // Bind event listener
this.eventMouseDown = this._initDrag.bindAsEventListener(this);
- this.eventMouseUp = this._endDrag.bindAsEventListener(this);
- this.eventMouseMove = this._updateDrag.bindAsEventListener(this);
- this.eventKeyPress = this._keyPress.bindAsEventListener(this);
- this.eventOnLoad = this._getWindowBorderSize.bindAsEventListener(this);
+ this.eventMouseUp = this._endDrag.bindAsEventListener(this);
+ this.eventMouseMove = this._updateDrag.bindAsEventListener(this);
+ this.eventOnLoad = this._getWindowBorderSize.bindAsEventListener(this);
this.eventMouseDownContent = this.toFront.bindAsEventListener(this);
this.eventResize = this._recenter.bindAsEventListener(this);
- this.topbar = $(this.element.id + "_top");
- this.bottombar = $(this.element.id + "_bottom");
+ this.topbar = $(this.element.id + "_top");
+ this.bottombar = $(this.element.id + "_bottom");
this.content = $(this.element.id + "_content");
- Event.observe(this.topbar, "mousedown", this.eventMouseDown);
- Event.observe(this.bottombar, "mousedown", this.eventMouseDown);
- Event.observe(this.content, "mousedown", this.eventMouseDownContent);
- Event.observe(window, "load", this.eventOnLoad);
- Event.observe(window, "resize", this.eventResize);
- Event.observe(window, "scroll", this.eventResize);
-
- if (this.options.draggable) {
- this.bottombar.addClassName("bottom_draggable");
- this.topbar.addClassName("top_draggable");
- }
+ Event.observe(this.topbar, "mousedown", this.eventMouseDown);
+ Event.observe(this.bottombar, "mousedown", this.eventMouseDown);
+ Event.observe(this.content, "mousedown", this.eventMouseDownContent);
+ Event.observe(window, "load", this.eventOnLoad);
+ Event.observe(window, "resize", this.eventResize);
+ Event.observe(window, "scroll", this.eventResize);
- if (this.options.resizable) {
- this.sizer = $(this.element.id + "_sizer");
- Event.observe(this.sizer, "mousedown", this.eventMouseDown);
- }
+ if (this.options.draggable) {
+ var that = this;
+ [this.topbar, this.topbar.up().previous(), this.topbar.up().next()].each(function(element) {
+ element.observe("mousedown", that.eventMouseDown);
+ element.addClassName("top_draggable");
+ });
+ [this.bottombar.up(), this.bottombar.up().previous(), this.bottombar.up().next()].each(function(element) {
+ element.observe("mousedown", that.eventMouseDown);
+ element.addClassName("bottom_draggable");
+ });
+
+ }
+
+ if (this.options.resizable) {
+ this.sizer = $(this.element.id + "_sizer");
+ Event.observe(this.sizer, "mousedown", this.eventMouseDown);
+ }
this.useLeft = null;
this.useTop = null;
- if (arguments[1].left != null) {
- this.element.setStyle({left: parseFloat(arguments[1].left) + 'px'});
- this.useLeft = true;
- }
- if (arguments[1].right != null) {
- this.element.setStyle({right: parseFloat(arguments[1].right) + 'px'});
- this.useLeft = false;
- }
- if (this.useLeft == null) {
- this.element.setStyle({left: "0px"});
- this.useLeft = true;
+ if (typeof this.options.left != "undefined") {
+ this.element.setStyle({left: parseFloat(this.options.left) + 'px'});
+ this.useLeft = true;
+ }
+ else {
+ this.element.setStyle({right: parseFloat(this.options.right) + 'px'});
+ this.useLeft = false;
}
- if (arguments[1].top != null) {
- this.element.setStyle({top: parseFloat(arguments[1].top) + 'px'});
- this.useTop = true;
- }
- if (arguments[1].bottom != null) {
- this.element.setStyle({bottom: parseFloat(arguments[1].bottom) + 'px'});
- this.useTop = false;
- }
- if (this.useTop == null) {
- this.element.setStyle({top: "0px"});
- this.useTop = true;
+ if (typeof this.options.top != "undefined") {
+ this.element.setStyle({top: parseFloat(this.options.top) + 'px'});
+ this.useTop = true;
}
-
+ else {
+ this.element.setStyle({bottom: parseFloat(this.options.bottom) + 'px'});
+ this.useTop = false;
+ }
+
this.storedLocation = null;
- this.setOpacity(this.options.opacity);
- if (this.options.zIndex)
- this.setZIndex(this.options.zIndex)
+ this.setOpacity(this.options.opacity);
+ if (this.options.zIndex)
+ this.setZIndex(this.options.zIndex)
- this.destroyOnClose = false;
+ if (this.options.destroyOnClose)
+ this.setDestroyOnClose(true);
this._getWindowBorderSize();
this.width = this.options.width;
this.height = this.options.height;
+ this.visible = false;
+
+ this.constraint = false;
+ this.constraintPad = {top: 0, left:0, bottom:0, right:0};
if (this.width && this.height)
- this.setSize(this.options.width, this.options.height);
- this.setTitle(this.options.title)
- Windows.register(this);
+ this.setSize(this.options.width, this.options.height);
+ this.setTitle(this.options.title)
+ Windows.register(this);
},
- // Destructor
- destroy: function() {
- Windows.notify("onDestroy", this);
- Event.stopObserving(this.topbar, "mousedown", this.eventMouseDown);
- Event.stopObserving(this.bottombar, "mousedown", this.eventMouseDown);
- Event.stopObserving(this.content, "mousedown", this.eventMouseDownContent);
+ // Destructor
+ destroy: function() {
+ this._notify("onDestroy");
+ Event.stopObserving(this.topbar, "mousedown", this.eventMouseDown);
+ Event.stopObserving(this.bottombar, "mousedown", this.eventMouseDown);
+ Event.stopObserving(this.content, "mousedown", this.eventMouseDownContent);
- Event.stopObserving(window, "load", this.eventOnLoad);
- Event.stopObserving(window, "resize", this.eventResize);
- Event.stopObserving(window, "scroll", this.eventResize);
-
- Event.stopObserving(this.content, "load", this.options.onload);
+ Event.stopObserving(window, "load", this.eventOnLoad);
+ Event.stopObserving(window, "resize", this.eventResize);
+ Event.stopObserving(window, "scroll", this.eventResize);
+
+ Event.stopObserving(this.content, "load", this.options.onload);
- if (this.sizer)
- Event.stopObserving(this.sizer, "mousedown", this.eventMouseDown);
+ if (this._oldParent) {
+ var content = this.getContent();
+ var originalContent = null;
+ for(var i = 0; i < content.childNodes.length; i++) {
+ originalContent = content.childNodes[i];
+ if (originalContent.nodeType == 1)
+ break;
+ originalContent = null;
+ }
+ if (originalContent)
+ this._oldParent.appendChild(originalContent);
+ this._oldParent = null;
+ }
- if (this.options.url)
- this.content.src = null
+ if (this.sizer)
+ Event.stopObserving(this.sizer, "mousedown", this.eventMouseDown);
- if(this.iefix)
- Element.remove(this.iefix);
+ if (this.options.url)
+ this.content.src = null
+
+ if(this.iefix)
+ Element.remove(this.iefix);
Element.remove(this.element);
- Windows.unregister(this);
- },
-
- // Sets window deleagte, should have functions: "canClose(window)"
- setDelegate: function(delegate) {
- this.delegate = delegate
- },
-
- // Gets current window delegate
- getDelegate: function() {
- return this.delegate;
- },
-
- // Gets window content
- getContent: function () {
- return this.content;
- },
-
- // Sets the content with an element id
- setContent: function(id, autoresize, autoposition) {
- var d = null;
- var p = null;
+ Windows.unregister(this);
+ },
+
+ // Sets close callback, if it sets, it should return true to be able to close the window.
+ setCloseCallback: function(callback) {
+ this.options.closeCallback = callback;
+ },
+
+ // Gets window content
+ getContent: function () {
+ return this.content;
+ },
+
+ // Sets the content with an element id
+ setContent: function(id, autoresize, autoposition) {
+ var element = $(id);
+ if (null == element) throw "Unable to find element '" + id + "' in DOM";
+ this._oldParent = element.parentNode;
- if (autoresize)
- d = Element.getDimensions(id);
- if (autoposition)
- p = Position.cumulativeOffset($(id));
+ var d = null;
+ var p = null;
- var content = this.getContent()
- content.appendChild($(id));
- $(id).show();
- if (autoresize)
- this.setSize(d.width, d.height);
- if (autoposition)
- this.setLocation(p[1] - this.heightN, p[0] - this.widthW);
- },
-
- setAjaxContent: function(url, options, showCentered, showModal) {
- this.showFunction = showCentered ? "showCenter" : "show";
- this.showModal = showModal || false;
-
- if (options == null)
- options = {}
- this.onComplete = options.onComplete;
- options.onComplete = this._setAjaxContent.bind(this);
-
- new Ajax.Request(url, options);
- },
-
- _setAjaxContent: function(originalRequest) {
- this.getContent().innerHTML = originalRequest.responseText;
- if (this.onComplete)
- this.onComplete(originalRequest);
- this[this.showFunction](this.showModal)
- },
-
- // Stores position/size in a cookie, by default named with window id
- setCookie: function(name, expires, path, domain, secure) {
- name = name || this.element.id;
- this.cookie = [name, expires, path, domain, secure];
-
- // Get cookie
- var value = WindowUtilities.getCookie(name)
- // If exists
- if (value) {
- var values = value.split(',');
- var x = values[0].split(':');
- var y = values[1].split(':');
+ if (autoresize)
+ d = Element.getDimensions(element);
+ if (autoposition)
+ p = Position.cumulativeOffset(element);
- var w = parseFloat(values[2]), h = parseFloat(values[3]);
- var mini = values[4];
- var maxi = values[5];
-
- this.setSize(w, h);
- if (mini == "true")
- this.doMinimize = true; // Minimize will be done at onload window event
- else if (maxi == "true")
- this.doMaximize = true; // Maximize will be done at onload window event
-
- this.useLeft = x[0] == "l";
- this.useTop = y[0] == "t";
-
- this.element.setStyle(this.useLeft ? {left: x[1]} : {right: x[1]});
- this.element.setStyle(this.useTop ? {top: y[1]} : {bottom: y[1]});
- }
- },
-
- // Gets window ID
- getId: function() {
- return this.element.id;
- },
-
- // Detroys itself when closing
- setDestroyOnClose: function() {
- var destroyFunc = this.destroy.bind(this);
- if (this.options.hideEffectOptions.afterFinish) {
- var func = this.options.hideEffectOptions.afterFinish;
- this.options.hideEffectOptions.afterFinish = function() {func();destroyFunc() }
+ var content = this.getContent();
+ // Clear HTML (and even iframe)
+ this.setHTMLContent("");
+ content = this.getContent();
+
+ content.appendChild(element);
+ element.show();
+ if (autoresize)
+ this.setSize(d.width, d.height);
+ if (autoposition)
+ this.setLocation(p[1] - this.heightN, p[0] - this.widthW);
+ },
+
+ setHTMLContent: function(html) {
+ // It was an url (iframe), recreate a div content instead of iframe content
+ if (this.options.url) {
+ this.content.src = null;
+ this.options.url = null;
+
+ var content ="
";
+ $(this.getId() +"_table_content").innerHTML = content;
+
+ this.content = $(this.element.id + "_content");
}
- else
- this.options.hideEffectOptions.afterFinish = function() {destroyFunc() }
- this.destroyOnClose = true;
- },
-
- // initDrag event
- _initDrag: function(event) {
+
+ this.getContent().innerHTML = html;
+ },
+
+ setAjaxContent: function(url, options, showCentered, showModal) {
+ this.showFunction = showCentered ? "showCenter" : "show";
+ this.showModal = showModal || false;
+
+ options = options || {};
+
+ // Clear HTML (and even iframe)
+ this.setHTMLContent("");
+
+ this.onComplete = options.onComplete;
+ if (! this._onCompleteHandler)
+ this._onCompleteHandler = this._setAjaxContent.bind(this);
+ options.onComplete = this._onCompleteHandler;
+
+ new Ajax.Request(url, options);
+ options.onComplete = this.onComplete;
+ },
+
+ _setAjaxContent: function(originalRequest) {
+ Element.update(this.getContent(), originalRequest.responseText);
+ if (this.onComplete)
+ this.onComplete(originalRequest);
+ this.onComplete = null;
+ this[this.showFunction](this.showModal)
+ },
+
+ setURL: function(url) {
+ // Not an url content, change div to iframe
+ if (!this.options.url) {
+ this.options.url = url;
+ var content= "";
+ $(this.getId() +"_table_content").innerHTML = content;
+
+ this.content = $(this.element.id + "_content");
+ } else {
+ this.options.url = url;
+ $(this.element.getAttribute('id') + '_content').src = url;
+ }
+ },
+
+ getURL: function() {
+ return this.options.url ? this.options.url : null;
+ },
+
+ refresh: function() {
+ if (this.options.url)
+ $(this.element.getAttribute('id') + '_content').src = this.options.url;
+ },
+
+ // Stores position/size in a cookie, by default named with window id
+ setCookie: function(name, expires, path, domain, secure) {
+ name = name || this.element.id;
+ this.cookie = [name, expires, path, domain, secure];
+
+ // Get cookie
+ var value = WindowUtilities.getCookie(name)
+ // If exists
+ if (value) {
+ var values = value.split(',');
+ var x = values[0].split(':');
+ var y = values[1].split(':');
+
+ var w = parseFloat(values[2]), h = parseFloat(values[3]);
+ var mini = values[4];
+ var maxi = values[5];
+
+ this.setSize(w, h);
+ if (mini == "true")
+ this.doMinimize = true; // Minimize will be done at onload window event
+ else if (maxi == "true")
+ this.doMaximize = true; // Maximize will be done at onload window event
+
+ this.useLeft = x[0] == "l";
+ this.useTop = y[0] == "t";
+
+ this.element.setStyle(this.useLeft ? {left: x[1]} : {right: x[1]});
+ this.element.setStyle(this.useTop ? {top: y[1]} : {bottom: y[1]});
+ }
+ },
+
+ // Gets window ID
+ getId: function() {
+ return this.element.id;
+ },
+
+ // Detroys itself when closing
+ setDestroyOnClose: function() {
+ this.options.destroyOnClose = true;
+ },
+
+ setConstraint: function(bool, padding) {
+ this.constraint = bool;
+ this.constraintPad = Object.extend(this.constraintPad, padding || {});
+ // Reset location to apply constraint
+ if (this.useTop && this.useLeft)
+ this.setLocation(parseFloat(this.element.style.top), parseFloat(this.element.style.left));
+ },
+
+ // initDrag event
+
+ _initDrag: function(event) {
+ // No resize on minimized window
+ if (Event.element(event) == this.sizer && this.isMinimized())
+ return;
+
+ // No move on maximzed window
+ if (Event.element(event) != this.sizer && this.isMaximized())
+ return;
+
+ if (isIE && this.heightN == 0)
+ this._getWindowBorderSize();
+
// Get pointer X,Y
- this.pointer = [Event.pointerX(event), Event.pointerY(event)];
-
+ this.pointer = [Event.pointerX(event), Event.pointerY(event)];
+
+ if (this.options.wiredDrag)
+ this.currentDrag = this._createWiredElement();
+ else
+ this.currentDrag = this.element;
+
// Resize
- if (Event.element(event) == this.sizer) {
- this.doResize = true;
- this.widthOrg = this.width;
- this.heightOrg = this.height;
- this.bottomOrg = parseFloat(this.element.getStyle('bottom'));
- this.rightOrg = parseFloat(this.element.getStyle('right'));
- Windows.notify("onStartResize", this);
- }
+ if (Event.element(event) == this.sizer) {
+ this.doResize = true;
+ this.widthOrg = this.width;
+ this.heightOrg = this.height;
+ this.bottomOrg = parseFloat(this.element.getStyle('bottom'));
+ this.rightOrg = parseFloat(this.element.getStyle('right'));
+ this._notify("onStartResize");
+ }
else {
- this.doResize = false;
+ this.doResize = false;
- // Check if click on close button,
- var closeButton = $(this.getId() + '_close');
- if (closeButton && Position.within(closeButton, this.pointer[0], this.pointer[1]))
- return;
+ // Check if click on close button,
+ var closeButton = $(this.getId() + '_close');
+ if (closeButton && Position.within(closeButton, this.pointer[0], this.pointer[1])) {
+ this.currentDrag = null;
+ return;
+ }
- this.toFront();
+ this.toFront();
- if (! this.options.draggable)
- return;
- Windows.notify("onStartMove", this);
- }
- // Register global event to capture mouseUp and mouseMove
- Event.observe(document, "mouseup", this.eventMouseUp, false);
+ if (! this.options.draggable)
+ return;
+ this._notify("onStartMove");
+ }
+ // Register global event to capture mouseUp and mouseMove
+ Event.observe(document, "mouseup", this.eventMouseUp, false);
Event.observe(document, "mousemove", this.eventMouseMove, false);
-
- // Add an invisible div to keep catching mouse event over iframes
- WindowUtilities.disableScreen('__invisible__', '__invisible__');
+
+ // Add an invisible div to keep catching mouse event over iframes
+ WindowUtilities.disableScreen('__invisible__', '__invisible__');
// Stop selection while dragging
document.body.ondrag = function () { return false; };
document.body.onselectstart = function () { return false; };
+ this.currentDrag.show();
Event.stop(event);
},
// updateDrag event
- _updateDrag: function(event) {
- var pointer = [Event.pointerX(event), Event.pointerY(event)];
- var dx = pointer[0] - this.pointer[0];
- var dy = pointer[1] - this.pointer[1];
-
- // Resize case, update width/height
- if (this.doResize) {
- this.setSize(this.widthOrg + dx , this.heightOrg + dy);
-
+ _updateDrag: function(event) {
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
+ var dx = pointer[0] - this.pointer[0];
+ var dy = pointer[1] - this.pointer[1];
+
+ // Resize case, update width/height
+ if (this.doResize) {
+ var w = this.widthOrg + dx;
+ var h = this.heightOrg + dy;
+
dx = this.width - this.widthOrg
dy = this.height - this.heightOrg
-
- // Check if it's a right position, update it to keep upper-left corner at the same position
- if (! this.useLeft)
- this.element.setStyle({right: (this.rightOrg -dx) + 'px'});
- // Check if it's a bottom position, update it to keep upper-left corner at the same position
- if (! this.useTop)
- this.element.setStyle({bottom: (this.bottomOrg -dy) + 'px'});
- }
- // Move case, update top/left
- else {
- this.pointer = pointer;
-
- if (this.useLeft)
- this.element.setStyle({left: parseFloat(this.element.getStyle('left')) + dx + 'px'});
- else
- this.element.setStyle({right: parseFloat(this.element.getStyle('right')) - dx + 'px'});
-
- if (this.useTop)
- this.element.setStyle({top: parseFloat(this.element.getStyle('top')) + dy + 'px'});
- else
- this.element.setStyle({bottom: parseFloat(this.element.getStyle('bottom')) - dy + 'px'});
- }
- if (this.iefix)
- this._fixIEOverlapping();
-
- this._removeStoreLocation();
+
+ // Check if it's a right position, update it to keep upper-left corner at the same position
+ if (this.useLeft)
+ w = this._updateWidthConstraint(w)
+ else
+ this.currentDrag.setStyle({right: (this.rightOrg -dx) + 'px'});
+ // Check if it's a bottom position, update it to keep upper-left corner at the same position
+ if (this.useTop)
+ h = this._updateHeightConstraint(h)
+ else
+ this.currentDrag.setStyle({bottom: (this.bottomOrg -dy) + 'px'});
+
+ this.setSize(w , h);
+ this._notify("onResize");
+ }
+ // Move case, update top/left
+ else {
+ this.pointer = pointer;
+
+ if (this.useLeft) {
+ var left = parseFloat(this.currentDrag.getStyle('left')) + dx;
+ var newLeft = this._updateLeftConstraint(left);
+ // Keep mouse pointer correct
+ this.pointer[0] += newLeft-left;
+ this.currentDrag.setStyle({left: newLeft + 'px'});
+ }
+ else
+ this.currentDrag.setStyle({right: parseFloat(this.currentDrag.getStyle('right')) - dx + 'px'});
+
+ if (this.useTop) {
+ var top = parseFloat(this.currentDrag.getStyle('top')) + dy;
+ var newTop = this._updateTopConstraint(top);
+ // Keep mouse pointer correct
+ this.pointer[1] += newTop - top;
+ this.currentDrag.setStyle({top: newTop + 'px'});
+ }
+ else
+ this.currentDrag.setStyle({bottom: parseFloat(this.currentDrag.getStyle('bottom')) - dy + 'px'});
+
+ this._notify("onMove");
+ }
+ if (this.iefix)
+ this._fixIEOverlapping();
+
+ this._removeStoreLocation();
Event.stop(event);
- },
+ },
- // endDrag callback
- _endDrag: function(event) {
- // Remove temporary div over iframes
- WindowUtilities.enableScreen('__invisible__');
-
- if (this.doResize)
- Windows.notify("onEndResize", this);
- else
- Windows.notify("onEndMove", this);
-
- // Release event observing
- Event.stopObserving(document, "mouseup", this.eventMouseUp,false);
+ // endDrag callback
+ _endDrag: function(event) {
+ // Remove temporary div over iframes
+ WindowUtilities.enableScreen('__invisible__');
+
+ if (this.doResize)
+ this._notify("onEndResize");
+ else
+ this._notify("onEndMove");
+
+ // Release event observing
+ Event.stopObserving(document, "mouseup", this.eventMouseUp,false);
Event.stopObserving(document, "mousemove", this.eventMouseMove, false);
- // Store new location/size if need be
- this._saveCookie()
-
Event.stop(event);
+ this._hideWiredElement();
+
+ // Store new location/size if need be
+ this._saveCookie()
+
// Restore selection
document.body.ondrag = null;
document.body.onselectstart = null;
},
- _keyPress: function(event) {
- //Dialog.cancelCallback();
- },
-
- // Creates HTML window code
- _createWindow: function(id) {
- var className = this.options.className;
- var win = document.createElement("div");
- win.setAttribute('id', id);
- win.className = "dialog";
+ _updateLeftConstraint: function(left) {
+ if (this.constraint && this.useLeft && this.useTop) {
+ var width = this.options.parent == document.body ? WindowUtilities.getPageSize().windowWidth : this.options.parent.getDimensions().width;
- var content;
- if (this.options.url)
- content= "";
- else
- content ="
";
-
- var closeDiv = this.options.closable ? "
" : "";
- var minDiv = this.options.minimizable ? "
" : "";
- var maxDiv = this.options.maximizable ? "
" : "";
- var seAttributes = this.options.resizable ? "class='" + className + "_sizer' id='" + id + "_sizer'" : "class='" + className + "_se'";
-
+ if (left < this.constraintPad.left)
+ left = this.constraintPad.left;
+ if (left + this.width + this.widthE + this.widthW > width - this.constraintPad.right)
+ left = width - this.constraintPad.right - this.width - this.widthE - this.widthW;
+ }
+ return left;
+ },
+
+ _updateTopConstraint: function(top) {
+ if (this.constraint && this.useLeft && this.useTop) {
+ var height = this.options.parent == document.body ? WindowUtilities.getPageSize().windowHeight : this.options.parent.getDimensions().height;
+
+ var h = this.height + this.heightN + this.heightS;
+
+ if (top < this.constraintPad.top)
+ top = this.constraintPad.top;
+ if (top + h > height - this.constraintPad.bottom)
+ top = height - this.constraintPad.bottom - h;
+ }
+ return top;
+ },
+
+ _updateWidthConstraint: function(w) {
+ if (this.constraint && this.useLeft && this.useTop) {
+ var width = this.options.parent == document.body ? WindowUtilities.getPageSize().windowWidth : this.options.parent.getDimensions().width;
+ var left = parseFloat(this.element.getStyle("left"));
+
+ if (left + w + this.widthE + this.widthW > width - this.constraintPad.right)
+ w = width - this.constraintPad.right - left - this.widthE - this.widthW;
+ }
+ return w;
+ },
+
+ _updateHeightConstraint: function(h) {
+ if (this.constraint && this.useLeft && this.useTop) {
+ var height = this.options.parent == document.body ? WindowUtilities.getPageSize().windowHeight : this.options.parent.getDimensions().height;
+ var top = parseFloat(this.element.getStyle("top"));
+
+ if (top + h + this.heightN + this.heightS > height - this.constraintPad.bottom)
+ h = height - this.constraintPad.bottom - top - this.heightN - this.heightS;
+ }
+ return h;
+ },
+
+
+ // Creates HTML window code
+ _createWindow: function(id) {
+ var className = this.options.className;
+ var win = document.createElement("div");
+ win.setAttribute('id', id);
+ win.className = "dialog";
+
+ var content;
+ if (this.options.url)
+ content= "";
+ else
+ content ="
";
+
+ var closeDiv = this.options.closable ? "
" : "";
+ var minDiv = this.options.minimizable ? "
" : "";
+ var maxDiv = this.options.maximizable ? "
" : "";
+ var seAttributes = this.options.resizable ? "class='" + className + "_sizer' id='" + id + "_sizer'" : "class='" + className + "_se'";
+ var blank = "../themes/default/blank.gif";
+
win.innerHTML = closeDiv + minDiv + maxDiv + "\
\
\
- | | \
+ | \
"+ this.options.title +" | \
- | \
+ | \
\
\
\
\
| \
- "+ content +" | \
+ " + content + " | \
| \
\
\
\
\
- | | \
- | \
- | \
+ | \
+
| \
+ | \
\
\
";
+ Element.hide(win);
+ this.options.parent.insertBefore(win, this.options.parent.firstChild);
+ Event.observe($(id + "_content"), "load", this.options.onload);
+ return win;
+ },
+
+
+ changeClassName: function(newClassName) {
+ var className = this.options.className;
+ var id = this.getId();
+ var win = this;
+ $A(["_close","_minimize","_maximize","_sizer", "_content"]).each(function(value) { win._toggleClassName($(id + value), className + value, newClassName + value) });
+ $$("#" + id + " td").each(function(td) {td.className = td.className.sub(className,newClassName) });
+ this.options.className = newClassName;
+ },
+
+ _toggleClassName: function(element, oldClassName, newClassName) {
+ if (element) {
+ element.removeClassName(oldClassName);
+ element.addClassName(newClassName);
+ }
+ },
+
+ // Sets window location
+ setLocation: function(top, left) {
+ top = this._updateTopConstraint(top);
+ left = this._updateLeftConstraint(left);
+
+ this.element.setStyle({top: top + 'px'});
+ this.element.setStyle({left: left + 'px'});
+
+ this.useLeft = true;
+ this.useTop = true;
+ },
- Element.hide(win);
- this.options.parent.insertBefore(win, this.options.parent.firstChild);
- Event.observe($(id + "_content"), "load", this.options.onload);
- return win;
- },
-
- // Sets window location
- setLocation: function(top, left) {
- if (top < 0)
- top = 0;
- if (left < 0)
- left= 0
- this.element.setStyle({top: top + 'px'});
- this.element.setStyle({left: left + 'px'});
- this.useLeft = true;
- this.useTop = true;
- },
-
- getLocation: function() {
- var location = {};
- if (this.useTop)
- location = Object.extend(location, {top: this.element.getStyle("top")});
+ getLocation: function() {
+ var location = {};
+ if (this.useTop)
+ location = Object.extend(location, {top: this.element.getStyle("top")});
else
location = Object.extend(location, {bottom: this.element.getStyle("bottom")});
- if (this.useLeft)
- location = Object.extend(location, {left: this.element.getStyle("left")});
+ if (this.useLeft)
+ location = Object.extend(location, {left: this.element.getStyle("left")});
else
location = Object.extend(location, {right: this.element.getStyle("right")});
-
- return location;
- },
-
- // Gets window size
- getSize: function() {
- return {width: this.width, height: this.height};
- },
-
- // Sets window size
- setSize: function(width, height) {
- width = parseFloat(width);
- height = parseFloat(height);
-
- // Check min and max size
- if (width < this.options.minWidth)
- width = this.options.minWidth;
+
+ return location;
+ },
+
+ // Gets window size
+ getSize: function() {
+ return {width: this.width, height: this.height};
+ },
+
+ // Sets window size
+ setSize: function(width, height) {
+ width = parseFloat(width);
+ height = parseFloat(height);
+
+ // Check min and max size
+ if (width < this.options.minWidth)
+ width = this.options.minWidth;
- if (height < this.options.minHeight)
- height = this.options.minHeight;
-
- if (this.options. maxHeight && height > this.options. maxHeight)
- height = this.options. maxHeight;
+ if (height < this.options.minHeight)
+ height = this.options.minHeight;
+
+ if (this.options. maxHeight && height > this.options. maxHeight)
+ height = this.options. maxHeight;
- if (this.options. maxWidth && width > this.options. maxWidth)
- width = this.options. maxWidth;
+ if (this.options. maxWidth && width > this.options. maxWidth)
+ width = this.options. maxWidth;
- this.width = width;
- this.height = height;
- this.element.setStyle({width: width + this.widthW + this.widthE + "px"})
- this.element.setStyle({height: height + this.heightN + this.heightS + "px"})
+ this.width = width;
+ this.height = height;
+ var e = this.currentDrag ? this.currentDrag : this.element;
+ e.setStyle({width: width + this.widthW + this.widthE + "px"})
+ e.setStyle({height: height + this.heightN + this.heightS + "px"})
- // Update content height
- var content = $(this.element.id + '_content')
- content.setStyle({height: height + 'px'});
- content.setStyle({width: width + 'px'});
- },
-
- updateHeight: function() {
+ // Update content height
+ if (!this.currentDrag || this.currentDrag == this.element) {
+ var content = $(this.element.id + '_content');
+ content.setStyle({height: height + 'px'});
+ content.setStyle({width: width + 'px'});
+ }
+ },
+
+ updateHeight: function() {
this.setSize(this.width, this.content.scrollHeight)
- },
-
- updateWidth: function() {
+ },
+
+ updateWidth: function() {
this.setSize(this.content.scrollWidth, this.height)
- },
-
- // Brings window to front
- toFront: function() {
- if (Windows.focusedWindow == this)
- return;
+ },
+
+ // Brings window to front
+ toFront: function() {
+ if (Windows.focusedWindow == this)
+ return;
this.setZIndex(Windows.maxZIndex + 20);
- Windows.notify("onFocus", this);
- },
-
- // Displays window modal state or not
- show: function(modal) {
- if (modal) {
- WindowUtilities.disableScreen(this.options.className, 'overlay_modal', this.getId());
- this.modal = true;
- this.setZIndex(Windows.maxZIndex + 20);
- Windows.unsetOverflow(this);
- Event.observe(document, "keypress", this.eventKeyPress);
- }
-
- // To restore overflow if need be
- if (this.oldStyle)
- this.getContent().setStyle({overflow: this.oldStyle});
-
- if (! this.width || !this.height) {
- var size = WindowUtilities._computeSize(this.content.innerHTML, this.content.id, this.width, this.height, 0)
- if (this.height)
- this.width = size + 5
- else
- this.height = size + 5
- }
+ this._notify("onFocus");
+ if (this.iefix)
+ this._fixIEOverlapping();
+ },
+
+ // Displays window modal state or not
+ show: function(modal) {
+ if (modal) {
+ Windows.addModalWindow(this);
+
+ this.modal = true;
+ this.setZIndex(Windows.maxZIndex + 20);
+ Windows.unsetOverflow(this);
+ }
+
+ // To restore overflow if need be
+ if (this.oldStyle)
+ this.getContent().setStyle({overflow: this.oldStyle});
+
+ if (! this.width || !this.height) {
+ var size = WindowUtilities._computeSize(this.content.innerHTML, this.content.id, this.width, this.height, 0, this.options.className)
+ if (this.height)
+ this.width = size + 5
+ else
+ this.height = size + 5
+ }
- this.setSize(this.width, this.height);
- if (this.centered)
- this._center(this.centerTop, this.centerLeft);
-
- if (this.options.showEffect != Element.show && this.options.showEffectOptions )
- this.options.showEffect(this.element, this.options.showEffectOptions);
- else
- this.options.showEffect(this.element);
-
+ this.setSize(this.width, this.height);
+ if (this.centered)
+ this._center(this.centerTop, this.centerLeft);
+
+ this._notify("onBeforeShow");
+ if (this.options.showEffect != Element.show && this.options.showEffectOptions )
+ this.options.showEffect(this.element, this.options.showEffectOptions);
+ else
+ this.options.showEffect(this.element);
+
this._checkIEOverlapping();
- Windows.notify("onShow", this);
- },
-
- // Displays window modal state or not at the center of the page
- showCenter: function(modal, top, left) {
+ this.visible = true;
+ WindowUtilities.focusedWindow = this
+ this._notify("onShow");
+ },
+
+ // Displays window modal state or not at the center of the page
+ showCenter: function(modal, top, left) {
this.centered = true;
this.centerTop = top;
this.centerLeft = left;
- this.show(modal);
- },
-
- isVisible: function() {
- return this.element.visible();
- },
-
- _center: function(top, left) {
- var windowScroll = WindowUtilities.getWindowScroll();
- var pageSize = WindowUtilities.getPageSize();
+ this.show(modal);
+ },
+
+ isVisible: function() {
+ return this.visible;
+ },
+
+ _center: function(top, left) {
+ var windowScroll = WindowUtilities.getWindowScroll();
+ var pageSize = WindowUtilities.getPageSize();
if (!top)
top = (pageSize.windowHeight - (this.height + this.heightN + this.heightS))/2;
@@ -564,94 +784,152 @@ Window.prototype = {
this.setLocation(top, left);
this.toFront();
- },
-
- _recenter: function(event) {
- if (this.modal) {
- var pageSize = WindowUtilities.getPageSize();
- // set height of Overlay to take up whole page and show
- if ($('overlay_modal')) {
- $('overlay_modal').style.height = (pageSize.pageHeight + 'px');
- $('overlay_modal').style.width = (pageSize.pageWidth + 'px');
- }
- if (this.centered)
- this._center(this.centerTop, this.centerLeft);
- }
- },
-
- // Hides window
- hide: function() {
- if (this.modal) {
- WindowUtilities.enableScreen();
- Windows.resetOverflow();
- Event.stopObserving(document, "keypress", this.eventKeyPress);
- }
- // To avoid bug on scrolling bar
- this.oldStyle = this.getContent().getStyle('overflow') || "auto"
- this.getContent().setStyle({overflow: "hidden"});
+ },
+
+ _recenter: function(event) {
+ if (this.modal && this.centered) {
+ var pageSize = WindowUtilities.getPageSize();
+ // Check for this stupid IE that sends dumb events
+ if (this.pageSize && this.pageSize.pageWidth == pageSize.windowWidth && this.pageSize.pageHeight == pageSize.windowHeight)
+ return;
+
+ this.pageSize = pageSize;
+ // set height of Overlay to take up whole page and show
+ if ($('overlay_modal')) {
+ $('overlay_modal').style.height = (pageSize.pageHeight + 'px');
+ $('overlay_modal').style.width = (pageSize.pageWidth + 'px');
+ }
+ if (this.options.recenterAuto)
+ this._center(this.centerTop, this.centerLeft);
+ }
+ },
+
+ // Hides window
+ hide: function() {
+ this.visible = false;
+ if (this.modal) {
+ Windows.removeModalWindow(this);
+ Windows.resetOverflow();
+ }
+ // To avoid bug on scrolling bar
+ this.oldStyle = this.getContent().getStyle('overflow') || "auto"
+ this.getContent().setStyle({overflow: "hidden"});
- this.options.hideEffect(this.element, this.options.hideEffectOptions);
+ this.options.hideEffect(this.element, this.options.hideEffectOptions);
- if(this.iefix)
- this.iefix.hide();
- Windows.notify("onHide", this);
- },
+ if(this.iefix)
+ this.iefix.hide();
+ if (!this.doNotNotifyHide)
+ this._notify("onHide");
+ },
+
+ close: function() {
+ // Asks closeCallback if exists
+ if (this.visible) {
+ if (this.options.closeCallback && ! this.options.closeCallback(this))
+ return;
+
+ if (this.options.destroyOnClose) {
+ var destroyFunc = this.destroy.bind(this);
+ if (this.options.hideEffectOptions.afterFinish) {
+ var func = this.options.hideEffectOptions.afterFinish;
+ this.options.hideEffectOptions.afterFinish = function() {func();destroyFunc() }
+ }
+ else
+ this.options.hideEffectOptions.afterFinish = function() {destroyFunc() }
+ }
+ Windows.updateFocusedWindow();
+
+ this.doNotNotifyHide = true;
+ this.hide();
+ this.doNotNotifyHide = false;
+ this._notify("onClose");
+ }
+ },
+
minimize: function() {
var r2 = $(this.getId() + "_row2");
var dh = r2.getDimensions().height;
if (r2.visible()) {
- var h = this.element.getHeight() - dh
+ var h = this.element.getHeight() - dh;
+ this.height -= dh;
+
r2.hide()
- this.element.setStyle({height: h + "px"})
- if (! this.useTop) {
- var bottom = parseFloat(this.element.getStyle('bottom'));
- this.element.setStyle({bottom: (bottom + dh) + 'px'});
- }
- }
- else {
- var h = this.element.getHeight() + dh;
this.element.setStyle({height: h + "px"})
- if (! this.useTop) {
- var bottom = parseFloat(this.element.getStyle('bottom'));
- this.element.setStyle({bottom: (bottom - dh) + 'px'});
- }
+ if (! this.useTop) {
+ var bottom = parseFloat(this.element.getStyle('bottom'));
+ this.element.setStyle({bottom: (bottom + dh) + 'px'});
+ }
+ }
+ else {
+ var h = this.element.getHeight() + dh;
+ this.height += dh;
+
+ this.element.setStyle({height: h + "px"})
+ if (! this.useTop) {
+ var bottom = parseFloat(this.element.getStyle('bottom'));
+ this.element.setStyle({bottom: (bottom - dh) + 'px'});
+ }
r2.show();
-
this.toFront();
}
- Windows.notify("onMinimize", this);
-
+ this._notify("onMinimize");
+
// Store new location/size if need be
- this._saveCookie()
+ this._saveCookie()
},
maximize: function() {
+ if (this.isMinimized())
+ return;
+
+ if (isIE && this.heightN == 0)
+ this._getWindowBorderSize();
+
if (this.storedLocation != null) {
this._restoreLocation();
if(this.iefix)
- this.iefix.hide();
+ this.iefix.hide();
}
else {
this._storeLocation();
Windows.unsetOverflow(this);
var windowScroll = WindowUtilities.getWindowScroll();
- var pageSize = WindowUtilities.getPageSize();
+ var pageSize = WindowUtilities.getPageSize();
+ var left = windowScroll.left;
+ var top = windowScroll.top;
+
+ if (this.options.parent != document.body) {
+ windowScroll = {top:0, left:0, bottom:0, right:0};
+ var dim = this.options.parent.getDimensions();
+ pageSize.windowWidth = dim.width;
+ pageSize.windowHeight = dim.height;
+ top = 0;
+ left = 0;
+ }
+
+ if (this.constraint) {
+ pageSize.windowWidth -= Math.max(0, this.constraintPad.left) + Math.max(0, this.constraintPad.right);
+ pageSize.windowHeight -= Math.max(0, this.constraintPad.top) + Math.max(0, this.constraintPad.bottom);
+ left += Math.max(0, this.constraintPad.left);
+ top += Math.max(0, this.constraintPad.top);
+ }
+
+ this.element.setStyle(this.useLeft ? {left: left} : {right: left});
+ this.element.setStyle(this.useTop ? {top: top} : {bottom: top});
- this.element.setStyle(this.useLeft ? {left: windowScroll.left} : {right: windowScroll.left});
- this.element.setStyle(this.useTop ? {top: windowScroll.top} : {bottom: windowScroll.top});
-
- this.setSize(pageSize.windowWidth - this.widthW - this.widthE, pageSize.windowHeight - this.heightN - this.heightS)
+ this.setSize(pageSize.windowWidth - this.widthW - this.widthE , pageSize.windowHeight - this.heightN - this.heightS)
this.toFront();
if (this.iefix)
- this._fixIEOverlapping();
+ this._fixIEOverlapping();
}
- Windows.notify("onMaximize", this);
+ this._notify("onMaximize");
- // Store new location/size if need be
- this._saveCookie()
+ // Store new location/size if need be
+ this._saveCookie()
},
isMinimized: function() {
@@ -663,25 +941,25 @@ Window.prototype = {
return (this.storedLocation != null);
},
- setOpacity: function(opacity) {
- if (Element.setOpacity)
- Element.setOpacity(this.element, opacity);
- },
-
- setZIndex: function(zindex) {
- this.element.setStyle({zIndex: zindex});
- Windows.updateZindex(zindex, this);
- },
-
- setTitle: function(newTitle) {
- if (!newTitle || newTitle == "")
- newTitle = " ";
-
- Element.update(this.element.id + '_top', newTitle);
+ setOpacity: function(opacity) {
+ if (Element.setOpacity)
+ Element.setOpacity(this.element, opacity);
+ },
+
+ setZIndex: function(zindex) {
+ this.element.setStyle({zIndex: zindex});
+ Windows.updateZindex(zindex, this);
},
- setStatusBar: function(element) {
- var statusBar = $(this.getId() + "_bottom");
+ setTitle: function(newTitle) {
+ if (!newTitle || newTitle == "")
+ newTitle = " ";
+
+ Element.update(this.element.id + '_top', newTitle);
+ },
+
+ setStatusBar: function(element) {
+ var statusBar = $(this.getId() + "_bottom");
if (typeof(element) == "object") {
if (this.bottombar.firstChild)
@@ -690,81 +968,88 @@ Window.prototype = {
this.bottombar.appendChild(element);
}
else
- this.bottombar.innerHTML = element;
- },
+ this.bottombar.innerHTML = element;
+ },
- _checkIEOverlapping: function() {
+ _checkIEOverlapping: function() {
if(!this.iefix && (navigator.appVersion.indexOf('MSIE')>0) && (navigator.userAgent.indexOf('Opera')<0) && (this.element.getStyle('position')=='absolute')) {
new Insertion.After(this.element.id, '');
this.iefix = $(this.element.id+'_iefix');
}
if(this.iefix)
- setTimeout(this._fixIEOverlapping.bind(this), 50);
- },
+ setTimeout(this._fixIEOverlapping.bind(this), 50);
+ },
- _fixIEOverlapping: function() {
- Position.clone(this.element, this.iefix);
- this.iefix.style.zIndex = this.element.style.zIndex - 1;
- this.iefix.show();
- },
-
- _getWindowBorderSize: function(event) {
+ _fixIEOverlapping: function() {
+ Position.clone(this.element, this.iefix);
+ this.iefix.style.zIndex = this.element.style.zIndex - 1;
+ this.iefix.show();
+ },
+
+ _getWindowBorderSize: function(event) {
// Hack to get real window border size!!
var div = this._createHiddenDiv(this.options.className + "_n")
- this.heightN = Element.getDimensions(div).height;
- div.parentNode.removeChild(div)
+ this.heightN = Element.getDimensions(div).height;
+ div.parentNode.removeChild(div)
var div = this._createHiddenDiv(this.options.className + "_s")
- this.heightS = Element.getDimensions(div).height;
- div.parentNode.removeChild(div)
+ this.heightS = Element.getDimensions(div).height;
+ div.parentNode.removeChild(div)
var div = this._createHiddenDiv(this.options.className + "_e")
- this.widthE = Element.getDimensions(div).width;
- div.parentNode.removeChild(div)
+ this.widthE = Element.getDimensions(div).width;
+ div.parentNode.removeChild(div)
var div = this._createHiddenDiv(this.options.className + "_w")
- this.widthW = Element.getDimensions(div).width;
- div.parentNode.removeChild(div);
- // Safari size fix
- if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
- this.setSize(this.width, this.height);
- if (this.doMaximize)
- this.maximize();
- if (this.doMinimize)
- this.minimize();
+ this.widthW = Element.getDimensions(div).width;
+ div.parentNode.removeChild(div);
+
+ // Workaround for IE!!
+ if (isIE) {
+ this.heightS = $(this.getId() +"_row3").getDimensions().height;
+ this.heightN = $(this.getId() +"_row1").getDimensions().height;
+ }
+
+ // Safari size fix
+ if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+ this.setSize(this.width, this.height);
+ if (this.doMaximize)
+ this.maximize();
+ if (this.doMinimize)
+ this.minimize();
},
_createHiddenDiv: function(className) {
- var objBody = document.getElementsByTagName("body").item(0);
+ var objBody = document.body;
var win = document.createElement("div");
- win.setAttribute('id', this.element.id+ "_tmp");
- win.className = className;
- win.style.display = 'none';
- win.innerHTML = '';
- objBody.insertBefore(win, objBody.firstChild);
- return win;
+ win.setAttribute('id', this.element.id+ "_tmp");
+ win.className = className;
+ win.style.display = 'none';
+ win.innerHTML = '';
+ objBody.insertBefore(win, objBody.firstChild);
+ return win;
+ },
+
+ _storeLocation: function() {
+ if (this.storedLocation == null) {
+ this.storedLocation = {useTop: this.useTop, useLeft: this.useLeft,
+ top: this.element.getStyle('top'), bottom: this.element.getStyle('bottom'),
+ left: this.element.getStyle('left'), right: this.element.getStyle('right'),
+ width: this.width, height: this.height };
+ }
},
- _storeLocation: function() {
- if (this.storedLocation == null) {
- this.storedLocation = {useTop: this.useTop, useLeft: this.useLeft,
- top: this.element.getStyle('top'), bottom: this.element.getStyle('bottom'),
- left: this.element.getStyle('left'), right: this.element.getStyle('right'),
- width: this.width, height: this.height };
- }
- },
-
_restoreLocation: function() {
if (this.storedLocation != null) {
this.useLeft = this.storedLocation.useLeft;
this.useTop = this.storedLocation.useTop;
this.element.setStyle(this.useLeft ? {left: this.storedLocation.left} : {right: this.storedLocation.right});
- this.element.setStyle(this.useTop ? {top: this.storedLocation.top} : {bottom: this.storedLocation.bottom});
- this.setSize(this.storedLocation.width, this.storedLocation.height);
+ this.element.setStyle(this.useTop ? {top: this.storedLocation.top} : {bottom: this.storedLocation.bottom});
+ this.setSize(this.storedLocation.width, this.storedLocation.height);
- Windows.resetOverflow();
- this._removeStoreLocation();
+ Windows.resetOverflow();
+ this._removeStoreLocation();
}
},
@@ -774,28 +1059,87 @@ Window.prototype = {
_saveCookie: function() {
if (this.cookie) {
- var value = "";
- if (this.useLeft)
- value += "l:" + (this.storedLocation ? this.storedLocation.left : this.element.getStyle('left'))
- else
- value += "r:" + (this.storedLocation ? this.storedLocation.right : this.element.getStyle('right'))
- if (this.useTop)
- value += ",t:" + (this.storedLocation ? this.storedLocation.top : this.element.getStyle('top'))
- else
- value += ",b:" + (this.storedLocation ? this.storedLocation.bottom :this.element.getStyle('bottom'))
-
- value += "," + (this.storedLocation ? this.storedLocation.width : this.width);
- value += "," + (this.storedLocation ? this.storedLocation.height : this.height);
- value += "," + this.isMinimized();
- value += "," + this.isMaximized();
- WindowUtilities.setCookie(value, this.cookie)
+ var value = "";
+ if (this.useLeft)
+ value += "l:" + (this.storedLocation ? this.storedLocation.left : this.element.getStyle('left'))
+ else
+ value += "r:" + (this.storedLocation ? this.storedLocation.right : this.element.getStyle('right'))
+ if (this.useTop)
+ value += ",t:" + (this.storedLocation ? this.storedLocation.top : this.element.getStyle('top'))
+ else
+ value += ",b:" + (this.storedLocation ? this.storedLocation.bottom :this.element.getStyle('bottom'))
+
+ value += "," + (this.storedLocation ? this.storedLocation.width : this.width);
+ value += "," + (this.storedLocation ? this.storedLocation.height : this.height);
+ value += "," + this.isMinimized();
+ value += "," + this.isMaximized();
+ WindowUtilities.setCookie(value, this.cookie)
}
+ },
+
+ _createWiredElement: function() {
+ if (! this.wiredElement) {
+ if (isIE)
+ this._getWindowBorderSize();
+ var div = document.createElement("div");
+ div.className = "wired_frame " + this.options.className + "_wired_frame";
+
+ div.style.position = 'absolute';
+ this.options.parent.insertBefore(div, this.options.parent.firstChild);
+ this.wiredElement = $(div);
+ }
+ if (this.useLeft)
+ this.wiredElement.setStyle({left: this.element.getStyle('left')});
+ else
+ this.wiredElement.setStyle({right: this.element.getStyle('right')});
+
+ if (this.useTop)
+ this.wiredElement.setStyle({top: this.element.getStyle('top')});
+ else
+ this.wiredElement.setStyle({bottom: this.element.getStyle('bottom')});
+
+ var dim = this.element.getDimensions();
+ this.wiredElement.setStyle({width: dim.width + "px", height: dim.height +"px"});
+
+ this.wiredElement.setStyle({zIndex: Windows.maxZIndex+30});
+ return this.wiredElement;
+ },
+
+ _hideWiredElement: function() {
+ if (! this.wiredElement || ! this.currentDrag)
+ return;
+ if (this.currentDrag == this.element)
+ this.currentDrag = null;
+ else {
+ if (this.useLeft)
+ this.element.setStyle({left: this.currentDrag.getStyle('left')});
+ else
+ this.element.setStyle({right: this.currentDrag.getStyle('right')});
+
+ if (this.useTop)
+ this.element.setStyle({top: this.currentDrag.getStyle('top')});
+ else
+ this.element.setStyle({bottom: this.currentDrag.getStyle('bottom')});
+
+ this.currentDrag.hide();
+ this.currentDrag = null;
+ if (this.doResize)
+ this.setSize(this.width, this.height);
+ }
+ },
+
+ _notify: function(eventName) {
+ if (this.options[eventName])
+ this.options[eventName](this);
+ else
+ Windows.notify(eventName, this);
}
};
// Windows containers, register all page windows
var Windows = {
windows: [],
+ modalWindows: [],
observers: [],
focusedWindow: null,
maxZIndex: 0,
@@ -809,20 +1153,67 @@ var Windows = {
this.observers = this.observers.reject( function(o) { return o==observer });
},
- notify: function(eventName, win) { // onStartResize(), onEndResize(), onStartMove(), onEndMove(), onClose(), onDestroy(), onMinimize(), onMaximize(), onHide(), onShow(), onFocus()
+ // onDestroy onStartResize onStartMove onResize onMove onEndResize onEndMove onFocus onBeforeShow onShow onHide onMinimize onMaximize onClose
+ notify: function(eventName, win) {
this.observers.each( function(o) {if(o[eventName]) o[eventName](eventName, win);});
},
// Gets window from its id
getWindow: function(id) {
- return this.windows.detect(function(d) { return d.getId() ==id });
+ return this.windows.detect(function(d) { return d.getId() ==id });
},
// Gets the last focused window
getFocusedWindow: function() {
- return this.focusedWindow;
+ return this.focusedWindow;
},
+ updateFocusedWindow: function() {
+ this.focusedWindow = this.windows.length >=2 ? this.windows[this.windows.length-2] : null;
+ },
+
+ // Registers a new window (called by Windows constructor)
+ register: function(win) {
+ this.windows.push(win);
+ },
+
+ // Add a modal window in the stack
+ addModalWindow: function(win) {
+ // Disable screen if first modal window
+ if (this.modalWindows.length == 0)
+ WindowUtilities.disableScreen(win.options.className, 'overlay_modal', win.getId());
+ else {
+ // Move overlay over all windows
+ if (Window.keepMultiModalWindow) {
+ $('overlay_modal').style.zIndex = Windows.maxZIndex + 20;
+ Windows.maxZIndex += 20;
+ WindowUtilities._hideSelect(this.modalWindows.last().getId());
+ }
+ // Hide current modal window
+ else
+ this.modalWindows.last().element.hide();
+ // Fucking IE select issue
+ WindowUtilities._showSelect(win.getId());
+ }
+ this.modalWindows.push(win);
+ },
+
+ removeModalWindow: function(win) {
+ this.modalWindows.pop();
+
+ // No more modal windows
+ if (this.modalWindows.length == 0)
+ WindowUtilities.enableScreen();
+ else {
+ if (Window.keepMultiModalWindow) {
+ this.modalWindows.last().toFront();
+ WindowUtilities._showSelect(this.modalWindows.last().getId());
+ }
+ else
+ this.modalWindows.last().element.show();
+ }
+ },
+
// Registers a new window (called by Windows constructor)
register: function(win) {
this.windows.push(win);
@@ -832,220 +1223,237 @@ var Windows = {
unregister: function(win) {
this.windows = this.windows.reject(function(d) { return d==win });
},
-
- // Closes a window with its id
- close: function(event, id) {
- var win = this.getWindow(id);
- // Asks delegate if exists
- if (win) {
- if (win.getDelegate() && ! win.getDelegate().canClose(win))
- return;
- if ($(id + "_close"))
- $(id + "_close").onclick = null;
- if ($(id + "_minimize"))
- $(id + "_minimize").onclick = null;
- if ($(id + "_maximize"))
- $(id + "_maximize").onclick = null;
-
- this.notify("onClose", win);
- win.hide();
- }
- if (event)
- Event.stop(event);
- },
// Closes all windows
closeAll: function() {
this.windows.each( function(w) {Windows.close(w.getId())} );
},
+ closeAllModalWindows: function() {
+ WindowUtilities.enableScreen();
+ this.modalWindows.each( function(win) {win.hide()});
+ },
+
// Minimizes a window with its id
- minimize: function(event, id) {
- var win = this.getWindow(id)
- if (win)
- win.minimize();
- Event.stop(event);
+ minimize: function(id, event) {
+ var win = this.getWindow(id)
+ if (win && win.visible)
+ win.minimize();
+ Event.stop(event);
},
// Maximizes a window with its id
- maximize: function(event, id) {
- var win = this.getWindow(id)
- if (win)
- win.maximize();
- Event.stop(event);
+ maximize: function(id, event) {
+ var win = this.getWindow(id)
+ if (win && win.visible)
+ win.maximize();
+ Event.stop(event);
+ },
+
+ // Closes a window with its id
+ close: function(id, event) {
+ var win = this.getWindow(id);
+ if (win)
+ win.close()//win.options.destroyOnClose ? win.close() : win.hide();
+ if (event)
+ Event.stop(event);
},
- unsetOverflow: function(except) {
- this.windows.each(function(d) { d.oldOverflow = d.getContent().getStyle("overflow") || "auto" ; d.getContent().setStyle({overflow: "hidden"}) });
- if (except && except.oldOverflow)
- except.getContent().setStyle({overflow: except.oldOverflow});
+ unsetOverflow: function(except) {
+ this.windows.each(function(d) { d.oldOverflow = d.getContent().getStyle("overflow") || "auto" ; d.getContent().setStyle({overflow: "hidden"}) });
+ if (except && except.oldOverflow)
+ except.getContent().setStyle({overflow: except.oldOverflow});
},
resetOverflow: function() {
- this.windows.each(function(d) { if (d.oldOverflow) d.getContent().setStyle({overflow: d.oldOverflow}) });
+ this.windows.each(function(d) { if (d.oldOverflow) d.getContent().setStyle({overflow: d.oldOverflow}) });
},
updateZindex: function(zindex, win) {
- if (zindex > this.maxZIndex)
- this.maxZIndex = zindex;
+ if (zindex > this.maxZIndex)
+ this.maxZIndex = zindex;
this.focusedWindow = win;
}
};
var Dialog = {
dialogId: null,
- win: null,
onCompleteFunc: null,
callFunc: null,
parameters: null,
- confirm: function(content, parameters) {
- // Get Ajax return before
- if (typeof content != "string") {
- Dialog._runAjaxRequest(content, parameters, Dialog.confirm);
- return
- }
-
- parameters = parameters || {};
- var okLabel = parameters.okLabel ? parameters.okLabel : "Ok";
- var cancelLabel = parameters.cancelLabel ? parameters.cancelLabel : "Cancel";
-
- var windowParam = parameters.windowParameters || {};
- windowParam.className = windowParam.className || "alert";
-
- okButtonClass = "class ='" + (parameters.buttonClass ? parameters.buttonClass + " " : "") + " ok_button'"
- cancelButtonClass = "class ='" + (parameters.buttonClass ? parameters.buttonClass + " " : "") + " cancel_button'"
- var content = "\
- " + content + "
\
- \
- \
- \
-
\
- ";
- this._openDialog(content, parameters)
- return this.win
- },
-
- alert: function(content, parameters) {
- // Get Ajax return before
- if (typeof content != "string") {
- Dialog._runAjaxRequest(content, parameters, Dialog.alert);
- return
- }
-
- parameters = parameters || {};
- var okLabel = parameters.okLabel ? parameters.okLabel : "Ok";
-
- var windowParam = parameters.windowParameters || {};
- windowParam.className = windowParam.className || "alert";
-
- okButtonClass = "class ='" + (parameters.buttonClass ? parameters.buttonClass + " " : "") + " ok_button'"
- var content = "\
- " + content + "
\
- \
- \
-
";
- return this._openDialog(content, parameters)
- },
-
- info: function(content, parameters) {
- // Get Ajax return before
- if (typeof content != "string") {
- Dialog._runAjaxRequest(content, parameters, Dialog.info);
- return
- }
-
- parameters = parameters || {};
- parameters.windowParameters = parameters.windowParameters || {};
-
- var className = parameters.windowParameters.className || "alert";
-
- var content = "" + content + "
";
- if (parameters.showProgress)
- content += "
";
-
- parameters.windowParameters.ok = null;
- parameters.windowParameters.cancel = null;
- parameters.windowParameters.className = className;
-
- return this._openDialog(content, parameters)
- },
-
- setInfoMessage: function(message) {
- $('modal_dialog_message').update(message);
- },
-
- closeInfo: function() {
- Windows.close(null, this.dialogId);
- },
-
- _openDialog: function(content, parameters) {
- if (! parameters.windowParameters.height && ! parameters.windowParameters.width) {
- parameters.windowParameters.width = WindowUtilities.getPageSize().pageWidth / 2;
+ confirm: function(content, parameters) {
+ // Get Ajax return before
+ if (content && typeof content != "string") {
+ Dialog._runAjaxRequest(content, parameters, Dialog.confirm);
+ return
+ }
+ content = content || "";
+
+ parameters = parameters || {};
+ var okLabel = parameters.okLabel ? parameters.okLabel : "Ok";
+ var cancelLabel = parameters.cancelLabel ? parameters.cancelLabel : "Cancel";
+
+ // Backward compatibility
+ parameters = Object.extend(parameters, parameters.windowParameters || {});
+ parameters.windowParameters = parameters.windowParameters || {};
+
+ parameters.className = parameters.className || "alert";
+
+ var okButtonClass = "class ='" + (parameters.buttonClass ? parameters.buttonClass + " " : "") + " ok_button'"
+ var cancelButtonClass = "class ='" + (parameters.buttonClass ? parameters.buttonClass + " " : "") + " cancel_button'"
+ var content = "\
+ " + content + "
\
+ \
+ \
+ \
+
\
+ ";
+ return this._openDialog(content, parameters)
+ },
+
+ alert: function(content, parameters) {
+ // Get Ajax return before
+ if (content && typeof content != "string") {
+ Dialog._runAjaxRequest(content, parameters, Dialog.alert);
+ return
+ }
+ content = content || "";
+
+ parameters = parameters || {};
+ var okLabel = parameters.okLabel ? parameters.okLabel : "Ok";
+
+ // Backward compatibility
+ parameters = Object.extend(parameters, parameters.windowParameters || {});
+ parameters.windowParameters = parameters.windowParameters || {};
+
+ parameters.className = parameters.className || "alert";
+
+ var okButtonClass = "class ='" + (parameters.buttonClass ? parameters.buttonClass + " " : "") + " ok_button'"
+ var content = "\
+ " + content + "
\
+ \
+ \
+
";
+ return this._openDialog(content, parameters)
+ },
+
+ info: function(content, parameters) {
+ // Get Ajax return before
+ if (content && typeof content != "string") {
+ Dialog._runAjaxRequest(content, parameters, Dialog.info);
+ return
+ }
+ content = content || "";
+
+ // Backward compatibility
+ parameters = parameters || {};
+ parameters = Object.extend(parameters, parameters.windowParameters || {});
+ parameters.windowParameters = parameters.windowParameters || {};
+
+ parameters.className = parameters.className || "alert";
+
+ var content = "" + content + "
";
+ if (parameters.showProgress)
+ content += "
";
+
+ parameters.ok = null;
+ parameters.cancel = null;
+
+ return this._openDialog(content, parameters)
+ },
+
+ setInfoMessage: function(message) {
+ $('modal_dialog_message').update(message);
+ },
+
+ closeInfo: function() {
+ Windows.close(this.dialogId);
+ },
+
+ _openDialog: function(content, parameters) {
+ var className = parameters.className;
+
+ if (! parameters.height && ! parameters.width) {
+ parameters.width = WindowUtilities.getPageSize().pageWidth / 2;
+ }
+ if (parameters.id)
+ this.dialogId = parameters.id;
+ else {
+ var t = new Date();
+ this.dialogId = 'modal_dialog_' + t.getTime();
+ parameters.id = this.dialogId;
}
- this.dialogId = parameters.id ? parameters.id : 'modal_dialog';
// compute height or width if need be
- if (! parameters.windowParameters.height || ! parameters.windowParameters.width) {
- var size = WindowUtilities._computeSize(content, this.dialogId, parameters.windowParameters.width, parameters.windowParameters.height)
- if (parameters.windowParameters.height)
- parameters.windowParameters.width = size + 5
- else
- parameters.windowParameters.height = size + 5
+ if (! parameters.height || ! parameters.width) {
+ var size = WindowUtilities._computeSize(content, this.dialogId, parameters.width, parameters.height, 5, className)
+ if (parameters.height)
+ parameters.width = size + 5
+ else
+ parameters.height = size + 5
}
- var windowParam = parameters && parameters.windowParameters ? parameters.windowParameters : {};
- windowParam.resizable = windowParam.resizable || false;
-
- windowParam.effectOptions = windowParam.effectOptions || {duration: 1};
- windowParam.minimizable = false;
- windowParam.maximizable = false;
- windowParam.closable = false;
- this.win = new Window(this.dialogId, windowParam);
- this.win.getContent().innerHTML = content;
- this.win.showCenter(true, parameters.top, parameters.left);
- this.win.setDestroyOnClose();
-
- this.win.cancelCallback = parameters.cancel;
- this.win.okCallback = parameters.ok;
-
- return this.win;
- },
-
- _getAjaxContent: function(originalRequest) {
+ //parameters.resizable = parameters.resizable || false;
+
+ parameters.effectOptions = parameters.effectOptions || {duration: 1};
+ parameters.minimizable = false;
+ parameters.maximizable = false;
+ //parameters.draggable = false;
+ parameters.closable = false;
+
+ var win = new Window(parameters);
+ win.getContent().innerHTML = content;
+ win.showCenter(true, parameters.top, parameters.left);
+ win.setDestroyOnClose();
+
+ win.cancelCallback = parameters.onCancel || parameters.cancel;
+ win.okCallback = parameters.onOk || parameters.ok;
+
+ return win;
+ },
+
+ _getAjaxContent: function(originalRequest) {
Dialog.callFunc(originalRequest.responseText, Dialog.parameters)
},
_runAjaxRequest: function(message, parameters, callFunc) {
if (message.options == null)
- message.options ={}
- Dialog.onCompleteFunc = message.options.onComplete;
+ message.options = {}
+ Dialog.onCompleteFunc = message.options.onComplete;
Dialog.parameters = parameters;
Dialog.callFunc = callFunc;
- message.options.onComplete = Dialog._getAjaxContent;
+ message.options.onComplete = Dialog._getAjaxContent;
new Ajax.Request(message.url, message.options);
},
- okCallback: function() {
- if (!this.win.okCallback || this.win.okCallback(this.win))
- this.win.hide();
- },
+ okCallback: function() {
+ var win = Windows.focusedWindow;
+ if (!win.okCallback || win.okCallback(win)) {
+ // Remove onclick on button
+ $$("#" + win.getId()+" input").each(function(element) {element.onclick=null;})
+ win.close();
+ }
+ },
- cancelCallback: function() {
- this.win.hide();
- if (this.win.cancelCallback)
- this.win.cancelCallback(this.win);
- }
+ cancelCallback: function() {
+ var win = Windows.focusedWindow;
+ // Remove onclick on button
+ $$("#" + win.getId()+" input").each(function(element) {element.onclick=null})
+ win.close();
+ if (win.cancelCallback)
+ win.cancelCallback(win);
+ }
}
/*
- Based on Lightbox JS: Fullsize Image Overlays
- by Lokesh Dhakar - http://www.huddletogether.com
+ Based on Lightbox JS: Fullsize Image Overlays
+ by Lokesh Dhakar - http://www.huddletogether.com
- For more information on this script, visit:
- http://huddletogether.com/projects/lightbox/
+ For more information on this script, visit:
+ http://huddletogether.com/projects/lightbox/
- Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
- (basically, do anything you want, just leave my name and link)
+ Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
+ (basically, do anything you want, just leave my name and link)
*/
var isIE = navigator.appVersion.match(/MSIE/) == "MSIE";
@@ -1056,7 +1464,7 @@ var WindowUtilities = {
var w = window;
var T, L, W, H;
with (w.document) {
- if (w.document.documentElement && documentElement.scrollTop) {
+ if (w.document.documentElement && typeof documentElement.scrollTop != "undefined") {
T = documentElement.scrollTop;
L = documentElement.scrollLeft;
} else if (w.document.body) {
@@ -1066,7 +1474,7 @@ var WindowUtilities = {
if (w.innerWidth) {
W = w.innerWidth;
H = w.innerHeight;
- } else if (w.document.documentElement && documentElement.clientWidth) {
+ } else if (w.document.documentElement && typeof documentElement.clientWidth != "undefined") {
W = documentElement.clientWidth;
H = documentElement.clientHeight;
} else {
@@ -1075,7 +1483,6 @@ var WindowUtilities = {
}
}
return { top: T, left: L, width: W, height: H };
-
},
//
// getPageSize()
@@ -1084,113 +1491,150 @@ var WindowUtilities = {
// Edit for Firefox by pHaez
//
getPageSize: function(){
- var xScroll, yScroll;
+ var xScroll, yScroll;
- if (window.innerHeight && window.scrollMaxY) {
- xScroll = document.body.scrollWidth;
- yScroll = window.innerHeight + window.scrollMaxY;
- } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
- xScroll = document.body.scrollWidth;
- yScroll = document.body.scrollHeight;
- } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
- xScroll = document.body.offsetWidth;
- yScroll = document.body.offsetHeight;
- }
+ if (window.innerHeight && window.scrollMaxY) {
+ xScroll = document.body.scrollWidth;
+ yScroll = window.innerHeight + window.scrollMaxY;
+ } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
+ xScroll = document.body.scrollWidth;
+ yScroll = document.body.scrollHeight;
+ } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
+ xScroll = document.body.offsetWidth;
+ yScroll = document.body.offsetHeight;
+ }
- var windowWidth, windowHeight;
+ var windowWidth, windowHeight;
- if (self.innerHeight) { // all except Explorer
- windowWidth = self.innerWidth;
- windowHeight = self.innerHeight;
- } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
- windowWidth = document.documentElement.clientWidth;
- windowHeight = document.documentElement.clientHeight;
- } else if (document.body) { // other Explorers
- windowWidth = document.body.clientWidth;
- windowHeight = document.body.clientHeight;
- }
- var pageHeight, pageWidth;
+ if (self.innerHeight) { // all except Explorer
+ windowWidth = self.innerWidth;
+ windowHeight = self.innerHeight;
+ } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
+ windowWidth = document.documentElement.clientWidth;
+ windowHeight = document.documentElement.clientHeight;
+ } else if (document.body) { // other Explorers
+ windowWidth = document.body.clientWidth;
+ windowHeight = document.body.clientHeight;
+ }
+ var pageHeight, pageWidth;
- // for small pages with total height less then height of the viewport
- if(yScroll < windowHeight){
- pageHeight = windowHeight;
- } else {
- pageHeight = yScroll;
- }
+ // for small pages with total height less then height of the viewport
+ if(yScroll < windowHeight){
+ pageHeight = windowHeight;
+ } else {
+ pageHeight = yScroll;
+ }
- // for small pages with total width less then width of the viewport
- if(xScroll < windowWidth){
- pageWidth = windowWidth;
- } else {
- pageWidth = xScroll;
- }
+ // for small pages with total width less then width of the viewport
+ if(xScroll < windowWidth){
+ pageWidth = windowWidth;
+ } else {
+ pageWidth = xScroll;
+ }
- return {pageWidth: pageWidth ,pageHeight: pageHeight , windowWidth: windowWidth, windowHeight: windowHeight};
+ return {pageWidth: pageWidth ,pageHeight: pageHeight , windowWidth: windowWidth, windowHeight: windowHeight};
},
- disableScreen: function(className, overlayId, contentId) {
- WindowUtilities.initLightbox(overlayId, className);
- var objBody = document.getElementsByTagName("body").item(0);
+ disableScreen: function(className, overlayId, contentId) {
+ WindowUtilities.initLightbox(overlayId, className);
+ var objBody = document.body;
- // prep objects
- var objOverlay = $(overlayId);
+ // prep objects
+ var objOverlay = $(overlayId);
- var pageSize = WindowUtilities.getPageSize();
+ var pageSize = WindowUtilities.getPageSize();
- // Hide select boxes as they will 'peek' through the image in IE
- if (contentId && isIE) {
- $$('select').each(function(element) {element.style.visibility = "hidden"});
- $$('#'+contentId+' select').each(function(element) {element.style.visibility = "visible"});
- }
-
- // set height of Overlay to take up whole page and show
- objOverlay.style.height = (pageSize.pageHeight + 'px');
- objOverlay.style.width = (pageSize.windowWidth + 'px');
- objOverlay.style.display = 'block';
- },
+ // Hide select boxes as they will 'peek' through the image in IE, store old value
+ if (contentId && isIE) {
+ WindowUtilities._hideSelect();
+ WindowUtilities._showSelect(contentId);
+ }
+
+ // set height of Overlay to take up whole page and show
+ objOverlay.style.height = (pageSize.pageHeight + 'px');
+ objOverlay.style.width = (pageSize.windowWidth + 'px');
+ objOverlay.style.display = 'block';
+ },
- enableScreen: function(id) {
- id = id || 'overlay_modal';
- var objOverlay = $(id);
- if (objOverlay) {
- // hide lightbox and overlay
- objOverlay.style.display = 'none';
+ enableScreen: function(id) {
+ id = id || 'overlay_modal';
+ var objOverlay = $(id);
+ if (objOverlay) {
+ // hide lightbox and overlay
+ objOverlay.style.display = 'none';
- // make select boxes visible
- if (isIE) {
- $$('select').each(function(element) {element.style.visibility = "visible"});
- }
- objOverlay.parentNode.removeChild(objOverlay);
- }
- },
+ // make select boxes visible using old value
+ if (id != "__invisible__")
+ WindowUtilities._showSelect();
+
+ objOverlay.parentNode.removeChild(objOverlay);
+ }
+ },
- // initLightbox()
- // Function runs on window load, going through link tags looking for rel="lightbox".
- // These links receive onclick events that enable the lightbox display for their targets.
- // The function also inserts html markup at the top of the page which will be used as a
- // container for the overlay pattern and the inline image.
- initLightbox: function(id, className) {
- // Already done, just update zIndex
- if ($(id)) {
- Element.setStyle(id, {zIndex: Windows.maxZIndex + 10});
- }
- // create overlay div and hardcode some functional styles (aesthetic styles are in CSS file)
- else {
- var objBody = document.getElementsByTagName("body").item(0);
- var objOverlay = document.createElement("div");
- objOverlay.setAttribute('id', id);
- objOverlay.className = "overlay_" + className
- objOverlay.style.display = 'none';
- objOverlay.style.position = 'absolute';
- objOverlay.style.top = '0';
- objOverlay.style.left = '0';
- objOverlay.style.zIndex = Windows.maxZIndex + 10;
- objOverlay.style.width = '100%';
- objBody.insertBefore(objOverlay, objBody.firstChild);
- }
- },
-
- setCookie: function(value, parameters) {
+ _hideSelect: function(id) {
+ if (isIE) {
+ id = id == null ? "" : "#" + id + " ";
+ $$(id + 'select').each(function(element) {
+ if (! WindowUtilities.isDefined(element.oldVisibility)) {
+ element.oldVisibility = element.style.visibility ? element.style.visibility : "visible";
+ element.style.visibility = "hidden";
+ }
+ });
+ }
+ },
+
+ _showSelect: function(id) {
+ if (isIE) {
+ id = id == null ? "" : "#" + id + " ";
+ $$(id + 'select').each(function(element) {
+ if (WindowUtilities.isDefined(element.oldVisibility)) {
+ // Why?? Ask IE
+ try {
+ element.style.visibility = element.oldVisibility;
+ } catch(e) {
+ element.style.visibility = "visible";
+ }
+ element.oldVisibility = null;
+ }
+ else {
+ if (element.style.visibility)
+ element.style.visibility = "visible";
+ }
+ });
+ }
+ },
+
+ isDefined: function(object) {
+ return typeof(object) != "undefined" && object != null;
+ },
+
+ // initLightbox()
+ // Function runs on window load, going through link tags looking for rel="lightbox".
+ // These links receive onclick events that enable the lightbox display for their targets.
+ // The function also inserts html markup at the top of the page which will be used as a
+ // container for the overlay pattern and the inline image.
+ initLightbox: function(id, className) {
+ // Already done, just update zIndex
+ if ($(id)) {
+ Element.setStyle(id, {zIndex: Windows.maxZIndex + 10});
+ }
+ // create overlay div and hardcode some functional styles (aesthetic styles are in CSS file)
+ else {
+ var objBody = document.body;
+ var objOverlay = document.createElement("div");
+ objOverlay.setAttribute('id', id);
+ objOverlay.className = "overlay_" + className
+ objOverlay.style.display = 'none';
+ objOverlay.style.position = 'absolute';
+ objOverlay.style.top = '0';
+ objOverlay.style.left = '0';
+ objOverlay.style.zIndex = Windows.maxZIndex + 10;
+ objOverlay.style.width = '100%';
+ objBody.insertBefore(objOverlay, objBody.firstChild);
+ }
+ },
+
+ setCookie: function(value, parameters) {
document.cookie= parameters[0] + "=" + escape(value) +
((parameters[1]) ? "; expires=" + parameters[1].toGMTString() : "") +
((parameters[2]) ? "; path=" + parameters[2] : "") +
@@ -1214,37 +1658,33 @@ var WindowUtilities = {
}
return unescape(dc.substring(begin + prefix.length, end));
},
-
- _computeSize: function(content, id, width, height, margin) {
- if (margin == null)
- margin = 5;
+
+ _computeSize: function(content, id, width, height, margin, className) {
+ var objBody = document.body;
+ var tmpObj = document.createElement("div");
+ tmpObj.setAttribute('id', id);
+ tmpObj.className = className + "_content";
- var objBody = document.getElementsByTagName("body").item(0);
- var tmpObj = document.createElement("div");
- tmpObj.setAttribute('id', id);
-
- if (height)
- tmpObj.style.height = height + "px"
+ if (height)
+ tmpObj.style.height = height + "px"
else
tmpObj.style.width = width + "px"
- tmpObj.style.position = 'absolute';
- tmpObj.style.top = '0';
- tmpObj.style.left = '0';
+ tmpObj.style.position = 'absolute';
+ tmpObj.style.top = '0';
+ tmpObj.style.left = '0';
tmpObj.style.display = 'none';
tmpObj.innerHTML = content;
- objBody.insertBefore(tmpObj, objBody.firstChild);
-
- var size;
- if (height)
- size = $(id).getDimensions().width + margin;
+ objBody.insertBefore(tmpObj, objBody.firstChild);
+
+ var size;
+ if (height)
+ size = $(id).getDimensions().width + margin;
else
size = $(id).getDimensions().height + margin;
- objBody.removeChild(tmpObj);
-
- return size;
- }
+ objBody.removeChild(tmpObj);
+ return size;
+ }
}
-
diff --git a/data/msfweb/public/javascripts/window_ext.js b/data/msfweb/public/javascripts/window_ext.js
new file mode 100755
index 0000000000..da8a9ff082
--- /dev/null
+++ b/data/msfweb/public/javascripts/window_ext.js
@@ -0,0 +1,107 @@
+// Copyright (c) 2006 Sébastien Gruhier (http://xilinus.com, http://itseb.com)
+// YOU MUST INCLUDE window.js BEFORE
+//
+// Object to store hide/show windows status in a cookie
+// Just add at the end of your HTML file this javascript line: WindowStore.init()
+WindowStore = {
+ doSetCookie: false,
+ cookieName: "__window_store__",
+ expired: null,
+
+ // Init function with two optional parameters
+ // - cookieName (default = __window_store__)
+ // - expiration date (default 3 years from now)
+ init: function(cookieName, expired) {
+ WindowStore.cookieName = cookieName || WindowStore.cookieName
+
+ if (! expired) {
+ var today = new Date();
+ today.setYear(today.getYear()+1903);
+ WindowStore.expired = today;
+ }
+ else
+ WindowStore.expired = expired;
+
+ Windows.windows.each(function(win) {
+ win.setCookie(win.getId(), WindowStore.expired);
+ });
+
+ // Create observer on show/hide events
+ var myObserver = {
+ onShow: function(eventName, win) {
+ WindowStore._saveCookie();
+ },
+ onHide: function(eventName, win) {
+ WindowStore._saveCookie();
+ }
+ }
+ Windows.addObserver(myObserver);
+
+ WindowStore._restoreWindows();
+ WindowStore._saveCookie();
+ },
+
+ show: function(win) {
+ eval("var cookie = " + WindowUtilities.getCookie(Windows.cookieName));
+ if (cookie != null) {
+ if (cookie[win.getId()])
+ win.show();
+ }
+ else
+ win.show();
+ },
+
+ // Function to store windows show/hide status in a cookie
+ _saveCookie: function() {
+ if (!doSetCookie)
+ return;
+
+ var cookieValue = "{";
+ Windows.windows.each(function(win) {
+ if (cookieValue != "{")
+ cookieValue += ","
+ cookieValue += win.getId() + ": " + win.isVisible();
+ });
+ cookieValue += "}"
+
+ WindowUtilities.setCookie(cookieValue, [WindowStore.cookieName, WindowStore.expired]);
+ },
+
+ // Function to restore windows show/hide status from a cookie if exists
+ _restoreWindows: function() {
+ eval("var cookie = " + WindowUtilities.getCookie(Windows.cookieName));
+ if (cookie != null) {
+ doSetCookie = false;
+ Windows.windows.each(function(win) {
+ if (cookie[win.getId()])
+ win.show();
+ });
+ }
+ doSetCookie = true;
+ }
+}
+
+// Object to set a close key an all windows
+WindowCloseKey = {
+ keyCode: Event.KEY_ESC,
+
+ init: function(keyCode) {
+ if (keyCode)
+ WindowCloseKey.keyCode = keyCode;
+ Event.observe(document, 'keydown', this._closeCurrentWindow.bindAsEventListener(this));
+ },
+
+ _closeCurrentWindow: function(event) {
+ var e = event || window.event
+ var characterCode = e.which || e.keyCode;
+ var win = Windows.focusedWindow;
+ if (characterCode == WindowCloseKey.keyCode && win) {
+ if (win.cancelCallback)
+ Dialog.cancelCallback();
+ else if (win.okCallback)
+ Dialog.okCallback();
+ else
+ Windows.close(Windows.focusedWindow.getId());
+ }
+ }
+}
\ No newline at end of file