3
|
1 |
/**
|
|
2 |
* Copyright (c)2005-2009 Matt Kruse (javascripttoolbox.com)
|
|
3 |
*
|
|
4 |
* Dual licensed under the MIT and GPL licenses.
|
|
5 |
* This basically means you can use this code however you want for
|
|
6 |
* free, but don't claim to have written it yourself!
|
|
7 |
* Donations always accepted: http://www.JavascriptToolbox.com/donate/
|
|
8 |
*
|
|
9 |
* Please do not link to the .js files on javascripttoolbox.com from
|
|
10 |
* your site. Copy the files locally to your server instead.
|
|
11 |
*
|
|
12 |
*/
|
|
13 |
/* ******************************************************************* */
|
|
14 |
/* UTIL FUNCTIONS */
|
|
15 |
/* ******************************************************************* */
|
|
16 |
var Util = {'$VERSION':1.06};
|
|
17 |
|
|
18 |
// Util functions - these are GLOBAL so they
|
|
19 |
// look like built-in functions.
|
|
20 |
|
|
21 |
// Determine if an object is an array
|
|
22 |
function isArray(o) {
|
|
23 |
return (o!=null && typeof(o)=="object" && typeof(o.length)=="number" && (o.length==0 || defined(o[0])));
|
|
24 |
};
|
|
25 |
|
|
26 |
// Determine if an object is an Object
|
|
27 |
function isObject(o) {
|
|
28 |
return (o!=null && typeof(o)=="object" && defined(o.constructor) && o.constructor==Object && !defined(o.nodeName));
|
|
29 |
};
|
|
30 |
|
|
31 |
// Determine if a reference is defined
|
|
32 |
function defined(o) {
|
|
33 |
return (typeof(o)!="undefined");
|
|
34 |
};
|
|
35 |
|
|
36 |
// Iterate over an array, object, or list of items and run code against each item
|
|
37 |
// Similar functionality to Perl's map() function
|
|
38 |
function map(func) {
|
|
39 |
var i,j,o;
|
|
40 |
var results = [];
|
|
41 |
if (typeof(func)=="string") {
|
|
42 |
func = new Function('$_',func);
|
|
43 |
}
|
|
44 |
for (i=1; i<arguments.length; i++) {
|
|
45 |
o = arguments[i];
|
|
46 |
if (isArray(o)) {
|
|
47 |
for (j=0; j<o.length; j++) {
|
|
48 |
results[results.length] = func(o[j]);
|
|
49 |
}
|
|
50 |
}
|
|
51 |
else if (isObject(o)) {
|
|
52 |
for (j in o) {
|
|
53 |
results[results.length] = func(o[j]);
|
|
54 |
}
|
|
55 |
}
|
|
56 |
else {
|
|
57 |
results[results.length] = func(o);
|
|
58 |
}
|
|
59 |
}
|
|
60 |
return results;
|
|
61 |
};
|
|
62 |
|
|
63 |
// Set default values in an object if they are undefined
|
|
64 |
function setDefaultValues(o,values) {
|
|
65 |
if (!defined(o) || o==null) {
|
|
66 |
o = {};
|
|
67 |
}
|
|
68 |
if (!defined(values) || values==null) {
|
|
69 |
return o;
|
|
70 |
}
|
|
71 |
for (var val in values) {
|
|
72 |
if (!defined(o[val])) {
|
|
73 |
o[val] = values[val];
|
|
74 |
}
|
|
75 |
}
|
|
76 |
return o;
|
|
77 |
};
|
|
78 |
|
|
79 |
/* ******************************************************************* */
|
|
80 |
/* DEFAULT OBJECT PROTOTYPE ENHANCEMENTS */
|
|
81 |
/* ******************************************************************* */
|
|
82 |
// These functions add useful functionality to built-in objects
|
|
83 |
Array.prototype.contains = function(o) {
|
|
84 |
var i,l;
|
|
85 |
if (!(l = this.length)) { return false; }
|
|
86 |
for (i=0; i<l; i++) {
|
|
87 |
if (o==this[i]) {
|
|
88 |
return true;
|
|
89 |
}
|
|
90 |
}
|
|
91 |
};
|
|
92 |
|
|
93 |
/* ******************************************************************* */
|
|
94 |
/* DOM FUNCTIONS */
|
|
95 |
/* ******************************************************************* */
|
|
96 |
var DOM = (function() {
|
|
97 |
var dom = {};
|
|
98 |
|
|
99 |
// Get a parent tag with a given nodename
|
|
100 |
dom.getParentByTagName = function(o,tagNames) {
|
|
101 |
if(o==null) { return null; }
|
|
102 |
if (isArray(tagNames)) {
|
|
103 |
tagNames = map("return $_.toUpperCase()",tagNames);
|
|
104 |
while (o=o.parentNode) {
|
|
105 |
if (o.nodeName && tagNames.contains(o.nodeName)) {
|
|
106 |
return o;
|
|
107 |
}
|
|
108 |
}
|
|
109 |
}
|
|
110 |
else {
|
|
111 |
tagNames = tagNames.toUpperCase();
|
|
112 |
while (o=o.parentNode) {
|
|
113 |
if (o.nodeName && tagNames==o.nodeName) {
|
|
114 |
return o;
|
|
115 |
}
|
|
116 |
}
|
|
117 |
}
|
|
118 |
return null;
|
|
119 |
};
|
|
120 |
|
|
121 |
// Remove a node from its parent
|
|
122 |
dom.removeNode = function(o) {
|
|
123 |
if (o!=null && o.parentNode && o.parentNode.removeChild) {
|
|
124 |
// First remove all attributes which are func references, to avoid memory leaks
|
|
125 |
for (var i in o) {
|
|
126 |
if (typeof(o[i])=="function") {
|
|
127 |
o[i] = null;
|
|
128 |
}
|
|
129 |
}
|
|
130 |
o.parentNode.removeChild(o);
|
|
131 |
return true;
|
|
132 |
}
|
|
133 |
return false;
|
|
134 |
};
|
|
135 |
|
|
136 |
// Get the outer width in pixels of an object, including borders, padding, and margin
|
|
137 |
dom.getOuterWidth = function(o) {
|
|
138 |
if (defined(o.offsetWidth)) {
|
|
139 |
return o.offsetWidth;
|
|
140 |
}
|
|
141 |
return null;
|
|
142 |
};
|
|
143 |
|
|
144 |
// Get the outer height in pixels of an object, including borders, padding, and margin
|
|
145 |
dom.getOuterHeight = function(o) {
|
|
146 |
if (defined(o.offsetHeight)) {
|
|
147 |
return o.offsetHeight;
|
|
148 |
}
|
|
149 |
return null;
|
|
150 |
};
|
|
151 |
|
|
152 |
// Resolve an item, an array of items, or an object of items
|
|
153 |
dom.resolve = function() {
|
|
154 |
var results = new Array();
|
|
155 |
var i,j,o;
|
|
156 |
for (var i=0; i<arguments.length; i++) {
|
|
157 |
var o = arguments[i];
|
|
158 |
if (o==null) {
|
|
159 |
if (arguments.length==1) {
|
|
160 |
return null;
|
|
161 |
}
|
|
162 |
results[results.length] = null;
|
|
163 |
}
|
|
164 |
else if (typeof(o)=='string') {
|
|
165 |
if (document.getElementById) {
|
|
166 |
o = document.getElementById(o);
|
|
167 |
}
|
|
168 |
else if (document.all) {
|
|
169 |
o = document.all[o];
|
|
170 |
}
|
|
171 |
if (arguments.length==1) {
|
|
172 |
return o;
|
|
173 |
}
|
|
174 |
results[results.length] = o;
|
|
175 |
}
|
|
176 |
else if (isArray(o)) {
|
|
177 |
for (j=0; j<o.length; j++) {
|
|
178 |
results[results.length] = o[j];
|
|
179 |
}
|
|
180 |
}
|
|
181 |
else if (isObject(o)) {
|
|
182 |
for (j in o) {
|
|
183 |
results[results.length] = o[j];
|
|
184 |
}
|
|
185 |
}
|
|
186 |
else if (arguments.length==1) {
|
|
187 |
return o;
|
|
188 |
}
|
|
189 |
else {
|
|
190 |
results[results.length] = o;
|
|
191 |
}
|
|
192 |
}
|
|
193 |
return results;
|
|
194 |
};
|
|
195 |
dom.$ = dom.resolve;
|
|
196 |
|
|
197 |
return dom;
|
|
198 |
})();
|
|
199 |
|
|
200 |
/* ******************************************************************* */
|
|
201 |
/* CSS FUNCTIONS */
|
|
202 |
/* ******************************************************************* */
|
|
203 |
var CSS = (function(){
|
|
204 |
var css = {};
|
|
205 |
|
|
206 |
// Convert an RGB string in the form "rgb (255, 255, 255)" to "#ffffff"
|
|
207 |
css.rgb2hex = function(rgbString) {
|
|
208 |
if (typeof(rgbString)!="string" || !defined(rgbString.match)) { return null; }
|
|
209 |
var result = rgbString.match(/^\s*rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*/);
|
|
210 |
if (result==null) { return rgbString; }
|
|
211 |
var rgb = +result[1] << 16 | +result[2] << 8 | +result[3];
|
|
212 |
var hex = "";
|
|
213 |
var digits = "0123456789abcdef";
|
|
214 |
while(rgb!=0) {
|
|
215 |
hex = digits.charAt(rgb&0xf)+hex;
|
|
216 |
rgb>>>=4;
|
|
217 |
}
|
|
218 |
while(hex.length<6) { hex='0'+hex; }
|
|
219 |
return "#" + hex;
|
|
220 |
};
|
|
221 |
|
|
222 |
// Convert hyphen style names like border-width to camel case like borderWidth
|
|
223 |
css.hyphen2camel = function(property) {
|
|
224 |
if (!defined(property) || property==null) { return null; }
|
|
225 |
if (property.indexOf("-")<0) { return property; }
|
|
226 |
var str = "";
|
|
227 |
var c = null;
|
|
228 |
var l = property.length;
|
|
229 |
for (var i=0; i<l; i++) {
|
|
230 |
c = property.charAt(i);
|
|
231 |
str += (c!="-")?c:property.charAt(++i).toUpperCase();
|
|
232 |
}
|
|
233 |
return str;
|
|
234 |
};
|
|
235 |
|
|
236 |
// Determine if an object or class string contains a given class.
|
|
237 |
css.hasClass = function(obj,className) {
|
|
238 |
if (!defined(obj) || obj==null || !RegExp) { return false; }
|
|
239 |
var re = new RegExp("(^|\\s)" + className + "(\\s|$)");
|
|
240 |
if (typeof(obj)=="string") {
|
|
241 |
return re.test(obj);
|
|
242 |
}
|
|
243 |
else if (typeof(obj)=="object" && obj.className) {
|
|
244 |
return re.test(obj.className);
|
|
245 |
}
|
|
246 |
return false;
|
|
247 |
};
|
|
248 |
|
|
249 |
// Add a class to an object
|
|
250 |
css.addClass = function(obj,className) {
|
|
251 |
if (typeof(obj)!="object" || obj==null || !defined(obj.className)) { return false; }
|
|
252 |
if (obj.className==null || obj.className=='') {
|
|
253 |
obj.className = className;
|
|
254 |
return true;
|
|
255 |
}
|
|
256 |
if (css.hasClass(obj,className)) { return true; }
|
|
257 |
obj.className = obj.className + " " + className;
|
|
258 |
return true;
|
|
259 |
};
|
|
260 |
|
|
261 |
// Remove a class from an object
|
|
262 |
css.removeClass = function(obj,className) {
|
|
263 |
if (typeof(obj)!="object" || obj==null || !defined(obj.className) || obj.className==null) { return false; }
|
|
264 |
if (!css.hasClass(obj,className)) { return false; }
|
|
265 |
var re = new RegExp("(^|\\s+)" + className + "(\\s+|$)");
|
|
266 |
obj.className = obj.className.replace(re,' ');
|
|
267 |
return true;
|
|
268 |
};
|
|
269 |
|
|
270 |
// Fully replace a class with a new one
|
|
271 |
css.replaceClass = function(obj,className,newClassName) {
|
|
272 |
if (typeof(obj)!="object" || obj==null || !defined(obj.className) || obj.className==null) { return false; }
|
|
273 |
css.removeClass(obj,className);
|
|
274 |
css.addClass(obj,newClassName);
|
|
275 |
return true;
|
|
276 |
};
|
|
277 |
|
|
278 |
// Get the currently-applied style of an object
|
|
279 |
css.getStyle = function(o, property) {
|
|
280 |
if (o==null) { return null; }
|
|
281 |
var val = null;
|
|
282 |
var camelProperty = css.hyphen2camel(property);
|
|
283 |
// Handle "float" property as a special case
|
|
284 |
if (property=="float") {
|
|
285 |
val = css.getStyle(o,"cssFloat");
|
|
286 |
if (val==null) {
|
|
287 |
val = css.getStyle(o,"styleFloat");
|
|
288 |
}
|
|
289 |
}
|
|
290 |
else if (o.currentStyle && defined(o.currentStyle[camelProperty])) {
|
|
291 |
val = o.currentStyle[camelProperty];
|
|
292 |
}
|
|
293 |
else if (window.getComputedStyle) {
|
|
294 |
val = window.getComputedStyle(o,null).getPropertyValue(property);
|
|
295 |
}
|
|
296 |
else if (o.style && defined(o.style[camelProperty])) {
|
|
297 |
val = o.style[camelProperty];
|
|
298 |
}
|
|
299 |
// For color values, make the value consistent across browsers
|
|
300 |
// Convert rgb() colors back to hex for consistency
|
|
301 |
if (/^\s*rgb\s*\(/.test(val)) {
|
|
302 |
val = css.rgb2hex(val);
|
|
303 |
}
|
|
304 |
// Lowercase all #hex values
|
|
305 |
if (/^#/.test(val)) {
|
|
306 |
val = val.toLowerCase();
|
|
307 |
}
|
|
308 |
return val;
|
|
309 |
};
|
|
310 |
css.get = css.getStyle;
|
|
311 |
|
|
312 |
// Set a style on an object
|
|
313 |
css.setStyle = function(o, property, value) {
|
|
314 |
if (o==null || !defined(o.style) || !defined(property) || property==null || !defined(value)) { return false; }
|
|
315 |
if (property=="float") {
|
|
316 |
o.style["cssFloat"] = value;
|
|
317 |
o.style["styleFloat"] = value;
|
|
318 |
}
|
|
319 |
else if (property=="opacity") {
|
|
320 |
o.style['-moz-opacity'] = value;
|
|
321 |
o.style['-khtml-opacity'] = value;
|
|
322 |
o.style.opacity = value;
|
|
323 |
if (defined(o.style.filter)) {
|
|
324 |
o.style.filter = "alpha(opacity=" + value*100 + ")";
|
|
325 |
}
|
|
326 |
}
|
|
327 |
else {
|
|
328 |
o.style[css.hyphen2camel(property)] = value;
|
|
329 |
}
|
|
330 |
return true;
|
|
331 |
};
|
|
332 |
css.set = css.setStyle;
|
|
333 |
|
|
334 |
// Get a unique ID which doesn't already exist on the page
|
|
335 |
css.uniqueIdNumber=1000;
|
|
336 |
css.createId = function(o) {
|
|
337 |
if (defined(o) && o!=null && defined(o.id) && o.id!=null && o.id!="") {
|
|
338 |
return o.id;
|
|
339 |
}
|
|
340 |
var id = null;
|
|
341 |
while (id==null || document.getElementById(id)!=null) {
|
|
342 |
id = "ID_"+(css.uniqueIdNumber++);
|
|
343 |
}
|
|
344 |
if (defined(o) && o!=null && (!defined(o.id)||o.id=="")) {
|
|
345 |
o.id = id;
|
|
346 |
}
|
|
347 |
return id;
|
|
348 |
};
|
|
349 |
|
|
350 |
return css;
|
|
351 |
})();
|
|
352 |
|
|
353 |
/* ******************************************************************* */
|
|
354 |
/* EVENT FUNCTIONS */
|
|
355 |
/* ******************************************************************* */
|
|
356 |
|
|
357 |
var Event = (function(){
|
|
358 |
var ev = {};
|
|
359 |
|
|
360 |
// Resolve an event using IE's window.event if necessary
|
|
361 |
// --------------------------------------------------------------------
|
|
362 |
ev.resolve = function(e) {
|
|
363 |
if (!defined(e) && defined(window.event)) {
|
|
364 |
e = window.event;
|
|
365 |
}
|
|
366 |
return e;
|
|
367 |
};
|
|
368 |
|
|
369 |
// Add an event handler to a function
|
|
370 |
// Note: Don't use 'this' within functions added using this method, since
|
|
371 |
// the attachEvent and addEventListener models differ.
|
|
372 |
// --------------------------------------------------------------------
|
|
373 |
ev.add = function( obj, type, fn, capture ) {
|
|
374 |
if (obj.addEventListener) {
|
|
375 |
obj.addEventListener( type, fn, capture );
|
|
376 |
return true;
|
|
377 |
}
|
|
378 |
else if (obj.attachEvent) {
|
|
379 |
obj.attachEvent( "on"+type, fn );
|
|
380 |
return true;
|
|
381 |
}
|
|
382 |
return false;
|
|
383 |
};
|
|
384 |
|
|
385 |
// Get the mouse position of an event
|
|
386 |
// --------------------------------------------------------------------
|
|
387 |
// PageX/Y, where they exist, are more reliable than ClientX/Y because
|
|
388 |
// of some browser bugs in Opera/Safari
|
|
389 |
ev.getMouseX = function(e) {
|
|
390 |
e = ev.resolve(e);
|
|
391 |
if (defined(e.pageX)) {
|
|
392 |
return e.pageX;
|
|
393 |
}
|
|
394 |
if (defined(e.clientX)) {
|
|
395 |
return e.clientX+Screen.getScrollLeft();
|
|
396 |
}
|
|
397 |
return null;
|
|
398 |
};
|
|
399 |
ev.getMouseY = function(e) {
|
|
400 |
e = ev.resolve(e);
|
|
401 |
if (defined(e.pageY)) {
|
|
402 |
return e.pageY;
|
|
403 |
}
|
|
404 |
if (defined(e.clientY)) {
|
|
405 |
return e.clientY+Screen.getScrollTop();
|
|
406 |
}
|
|
407 |
return null;
|
|
408 |
};
|
|
409 |
|
|
410 |
// Stop the event from bubbling up to parent elements.
|
|
411 |
// Two method names map to the same function
|
|
412 |
// --------------------------------------------------------------------
|
|
413 |
ev.cancelBubble = function(e) {
|
|
414 |
e = ev.resolve(e);
|
|
415 |
if (typeof(e.stopPropagation)=="function") { e.stopPropagation(); }
|
|
416 |
if (defined(e.cancelBubble)) { e.cancelBubble = true; }
|
|
417 |
};
|
|
418 |
ev.stopPropagation = ev.cancelBubble;
|
|
419 |
|
|
420 |
// Prevent the default handling of the event to occur
|
|
421 |
// --------------------------------------------------------------------
|
|
422 |
ev.preventDefault = function(e) {
|
|
423 |
e = ev.resolve(e);
|
|
424 |
if (typeof(e.preventDefault)=="function") { e.preventDefault(); }
|
|
425 |
if (defined(e.returnValue)) { e.returnValue = false; }
|
|
426 |
};
|
|
427 |
|
|
428 |
return ev;
|
|
429 |
})();
|
|
430 |
|
|
431 |
/* ******************************************************************* */
|
|
432 |
/* SCREEN FUNCTIONS */
|
|
433 |
/* ******************************************************************* */
|
|
434 |
var Screen = (function() {
|
|
435 |
var screen = {};
|
|
436 |
|
|
437 |
// Get a reference to the body
|
|
438 |
// --------------------------------------------------------------------
|
|
439 |
screen.getBody = function() {
|
|
440 |
if (document.body) {
|
|
441 |
return document.body;
|
|
442 |
}
|
|
443 |
if (document.getElementsByTagName) {
|
|
444 |
var bodies = document.getElementsByTagName("BODY");
|
|
445 |
if (bodies!=null && bodies.length>0) {
|
|
446 |
return bodies[0];
|
|
447 |
}
|
|
448 |
}
|
|
449 |
return null;
|
|
450 |
};
|
|
451 |
|
|
452 |
// Get the amount that the main document has scrolled from top
|
|
453 |
// --------------------------------------------------------------------
|
|
454 |
screen.getScrollTop = function() {
|
|
455 |
if (document.documentElement && defined(document.documentElement.scrollTop) && document.documentElement.scrollTop>0) {
|
|
456 |
return document.documentElement.scrollTop;
|
|
457 |
}
|
|
458 |
if (document.body && defined(document.body.scrollTop)) {
|
|
459 |
return document.body.scrollTop;
|
|
460 |
}
|
|
461 |
return null;
|
|
462 |
};
|
|
463 |
|
|
464 |
// Get the amount that the main document has scrolled from left
|
|
465 |
// --------------------------------------------------------------------
|
|
466 |
screen.getScrollLeft = function() {
|
|
467 |
if (document.documentElement && defined(document.documentElement.scrollLeft) && document.documentElement.scrollLeft>0) {
|
|
468 |
return document.documentElement.scrollLeft;
|
|
469 |
}
|
|
470 |
if (document.body && defined(document.body.scrollLeft)) {
|
|
471 |
return document.body.scrollLeft;
|
|
472 |
}
|
|
473 |
return null;
|
|
474 |
};
|
|
475 |
|
|
476 |
// Util function to default a bad number to 0
|
|
477 |
// --------------------------------------------------------------------
|
|
478 |
screen.zero = function(n) {
|
|
479 |
return (!defined(n) || isNaN(n))?0:n;
|
|
480 |
};
|
|
481 |
|
|
482 |
// Get the width of the entire document
|
|
483 |
// --------------------------------------------------------------------
|
|
484 |
screen.getDocumentWidth = function() {
|
|
485 |
var width = 0;
|
|
486 |
var body = screen.getBody();
|
|
487 |
if (document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
|
|
488 |
var rightMargin = parseInt(CSS.get(body,'marginRight'),10) || 0;
|
|
489 |
var leftMargin = parseInt(CSS.get(body,'marginLeft'), 10) || 0;
|
|
490 |
width = Math.max(body.offsetWidth + leftMargin + rightMargin, document.documentElement.clientWidth);
|
|
491 |
}
|
|
492 |
else {
|
|
493 |
width = Math.max(body.clientWidth, body.scrollWidth);
|
|
494 |
}
|
|
495 |
if (isNaN(width) || width==0) {
|
|
496 |
width = screen.zero(self.innerWidth);
|
|
497 |
}
|
|
498 |
return width;
|
|
499 |
};
|
|
500 |
|
|
501 |
// Get the height of the entire document
|
|
502 |
// --------------------------------------------------------------------
|
|
503 |
screen.getDocumentHeight = function() {
|
|
504 |
var body = screen.getBody();
|
|
505 |
var innerHeight = (defined(self.innerHeight)&&!isNaN(self.innerHeight))?self.innerHeight:0;
|
|
506 |
if (document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
|
|
507 |
var topMargin = parseInt(CSS.get(body,'marginTop'),10) || 0;
|
|
508 |
var bottomMargin = parseInt(CSS.get(body,'marginBottom'), 10) || 0;
|
|
509 |
return Math.max(body.offsetHeight + topMargin + bottomMargin, document.documentElement.clientHeight, document.documentElement.scrollHeight, screen.zero(self.innerHeight));
|
|
510 |
}
|
|
511 |
return Math.max(body.scrollHeight, body.clientHeight, screen.zero(self.innerHeight));
|
|
512 |
};
|
|
513 |
|
|
514 |
// Get the width of the viewport (viewable area) in the browser window
|
|
515 |
// --------------------------------------------------------------------
|
|
516 |
screen.getViewportWidth = function() {
|
|
517 |
if (document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
|
|
518 |
return document.documentElement.clientWidth;
|
|
519 |
}
|
|
520 |
else if (document.compatMode && document.body) {
|
|
521 |
return document.body.clientWidth;
|
|
522 |
}
|
|
523 |
return screen.zero(self.innerWidth);
|
|
524 |
};
|
|
525 |
|
|
526 |
// Get the height of the viewport (viewable area) in the browser window
|
|
527 |
// --------------------------------------------------------------------
|
|
528 |
screen.getViewportHeight = function() {
|
|
529 |
if (!window.opera && document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
|
|
530 |
return document.documentElement.clientHeight;
|
|
531 |
}
|
|
532 |
else if (document.compatMode && !window.opera && document.body) {
|
|
533 |
return document.body.clientHeight;
|
|
534 |
}
|
|
535 |
return screen.zero(self.innerHeight);
|
|
536 |
};
|
|
537 |
|
|
538 |
return screen;
|
|
539 |
})();var Sort = (function(){
|
|
540 |
var sort = {};
|
|
541 |
sort.AlphaNumeric = function(a,b) {
|
|
542 |
if (a==b) { return 0; }
|
|
543 |
if (a<b) { return -1; }
|
|
544 |
return 1;
|
|
545 |
};
|
|
546 |
|
|
547 |
sort.Default = sort.AlphaNumeric;
|
|
548 |
|
|
549 |
sort.NumericConversion = function(val) {
|
|
550 |
if (typeof(val)!="number") {
|
|
551 |
if (typeof(val)=="string") {
|
|
552 |
val = parseFloat(val.replace(/,/g,''));
|
|
553 |
if (isNaN(val) || val==null) { val=0; }
|
|
554 |
}
|
|
555 |
else {
|
|
556 |
val = 0;
|
|
557 |
}
|
|
558 |
}
|
|
559 |
return val;
|
|
560 |
};
|
|
561 |
|
|
562 |
sort.Numeric = function(a,b) {
|
|
563 |
return sort.NumericConversion(a)-sort.NumericConversion(b);
|
|
564 |
};
|
|
565 |
|
|
566 |
sort.IgnoreCaseConversion = function(val) {
|
|
567 |
if (val==null) { val=""; }
|
|
568 |
return (""+val).toLowerCase();
|
|
569 |
};
|
|
570 |
|
|
571 |
sort.IgnoreCase = function(a,b) {
|
|
572 |
return sort.AlphaNumeric(sort.IgnoreCaseConversion(a),sort.IgnoreCaseConversion(b));
|
|
573 |
};
|
|
574 |
|
|
575 |
sort.CurrencyConversion = function(val) {
|
|
576 |
if (typeof(val)=="string") {
|
|
577 |
val = val.replace(/^[^\d\.]/,'');
|
|
578 |
}
|
|
579 |
return sort.NumericConversion(val);
|
|
580 |
};
|
|
581 |
|
|
582 |
sort.Currency = function(a,b) {
|
|
583 |
return sort.Numeric(sort.CurrencyConversion(a),sort.CurrencyConversion(b));
|
|
584 |
};
|
|
585 |
|
|
586 |
sort.DateConversion = function(val) {
|
|
587 |
// inner util function to parse date formats
|
|
588 |
function getdate(str) {
|
|
589 |
// inner util function to convert 2-digit years to 4
|
|
590 |
function fixYear(yr) {
|
|
591 |
yr = +yr;
|
|
592 |
if (yr<50) { yr += 2000; }
|
|
593 |
else if (yr<100) { yr += 1900; }
|
|
594 |
return yr;
|
|
595 |
};
|
|
596 |
var ret;
|
|
597 |
// YYYY-MM-DD
|
|
598 |
if (ret=str.match(/(\d{2,4})-(\d{1,2})-(\d{1,2})/)) {
|
|
599 |
return (fixYear(ret[1])*10000) + (ret[2]*100) + (+ret[3]);
|
|
600 |
}
|
|
601 |
// MM/DD/YY[YY] or MM-DD-YY[YY]
|
|
602 |
if (ret=str.match(/(\d{1,2})[\/-](\d{1,2})[\/-](\d{2,4})/)) {
|
|
603 |
return (fixYear(ret[3])*10000) + (ret[1]*100) + (+ret[2]);
|
|
604 |
}
|
|
605 |
return 99999999; // So non-parsed dates will be last, not first
|
|
606 |
};
|
|
607 |
return getdate(val);
|
|
608 |
};
|
|
609 |
|
|
610 |
sort.Date = function(a,b) {
|
|
611 |
return sort.Numeric(sort.DateConversion(a),sort.DateConversion(b));
|
|
612 |
};
|
|
613 |
|
|
614 |
return sort;
|
|
615 |
})();
|
|
616 |
|
|
617 |
var Position = (function() {
|
|
618 |
// Resolve a string identifier to an object
|
|
619 |
// ========================================
|
|
620 |
function resolveObject(s) {
|
|
621 |
if (document.getElementById && document.getElementById(s)!=null) {
|
|
622 |
return document.getElementById(s);
|
|
623 |
}
|
|
624 |
else if (document.all && document.all[s]!=null) {
|
|
625 |
return document.all[s];
|
|
626 |
}
|
|
627 |
else if (document.anchors && document.anchors.length && document.anchors.length>0 && document.anchors[0].x) {
|
|
628 |
for (var i=0; i<document.anchors.length; i++) {
|
|
629 |
if (document.anchors[i].name==s) {
|
|
630 |
return document.anchors[i]
|
|
631 |
}
|
|
632 |
}
|
|
633 |
}
|
|
634 |
}
|
|
635 |
|
|
636 |
var pos = {};
|
|
637 |
pos.$VERSION = 1.0;
|
|
638 |
|
|
639 |
// Set the position of an object
|
|
640 |
// =============================
|
|
641 |
pos.set = function(o,left,top) {
|
|
642 |
if (typeof(o)=="string") {
|
|
643 |
o = resolveObject(o);
|
|
644 |
}
|
|
645 |
if (o==null || !o.style) {
|
|
646 |
return false;
|
|
647 |
}
|
|
648 |
|
|
649 |
// If the second parameter is an object, it is assumed to be the result of getPosition()
|
|
650 |
if (typeof(left)=="object") {
|
|
651 |
var pos = left;
|
|
652 |
left = pos.left;
|
|
653 |
top = pos.top;
|
|
654 |
}
|
|
655 |
|
|
656 |
o.style.left = left + "px";
|
|
657 |
o.style.top = top + "px";
|
|
658 |
return true;
|
|
659 |
};
|
|
660 |
|
|
661 |
// Retrieve the position and size of an object
|
|
662 |
// ===========================================
|
|
663 |
pos.get = function(o) {
|
|
664 |
var fixBrowserQuirks = true;
|
|
665 |
// If a string is passed in instead of an object ref, resolve it
|
|
666 |
if (typeof(o)=="string") {
|
|
667 |
o = resolveObject(o);
|
|
668 |
}
|
|
669 |
|
|
670 |
if (o==null) {
|
|
671 |
return null;
|
|
672 |
}
|
|
673 |
|
|
674 |
var left = 0;
|
|
675 |
var top = 0;
|
|
676 |
var width = 0;
|
|
677 |
var height = 0;
|
|
678 |
var parentNode = null;
|
|
679 |
var offsetParent = null;
|
|
680 |
|
|
681 |
|
|
682 |
offsetParent = o.offsetParent;
|
|
683 |
var originalObject = o;
|
|
684 |
var el = o; // "el" will be nodes as we walk up, "o" will be saved for offsetParent references
|
|
685 |
while (el.parentNode!=null) {
|
|
686 |
el = el.parentNode;
|
|
687 |
if (el.offsetParent==null) {
|
|
688 |
}
|
|
689 |
else {
|
|
690 |
var considerScroll = true;
|
|
691 |
/*
|
|
692 |
In Opera, if parentNode of the first object is scrollable, then offsetLeft/offsetTop already
|
|
693 |
take its scroll position into account. If elements further up the chain are scrollable, their
|
|
694 |
scroll offsets still need to be added in. And for some reason, TR nodes have a scrolltop value
|
|
695 |
which must be ignored.
|
|
696 |
*/
|
|
697 |
if (fixBrowserQuirks && window.opera) {
|
|
698 |
if (el==originalObject.parentNode || el.nodeName=="TR") {
|
|
699 |
considerScroll = false;
|
|
700 |
}
|
|
701 |
}
|
|
702 |
if (considerScroll) {
|
|
703 |
if (el.scrollTop && el.scrollTop>0) {
|
|
704 |
top -= el.scrollTop;
|
|
705 |
}
|
|
706 |
if (el.scrollLeft && el.scrollLeft>0) {
|
|
707 |
left -= el.scrollLeft;
|
|
708 |
}
|
|
709 |
}
|
|
710 |
}
|
|
711 |
// If this node is also the offsetParent, add on the offsets and reset to the new offsetParent
|
|
712 |
if (el == offsetParent) {
|
|
713 |
left += o.offsetLeft;
|
|
714 |
if (el.clientLeft && el.nodeName!="TABLE") {
|
|
715 |
left += el.clientLeft;
|
|
716 |
}
|
|
717 |
top += o.offsetTop;
|
|
718 |
if (el.clientTop && el.nodeName!="TABLE") {
|
|
719 |
top += el.clientTop;
|
|
720 |
}
|
|
721 |
o = el;
|
|
722 |
if (o.offsetParent==null) {
|
|
723 |
if (o.offsetLeft) {
|
|
724 |
left += o.offsetLeft;
|
|
725 |
}
|
|
726 |
if (o.offsetTop) {
|
|
727 |
top += o.offsetTop;
|
|
728 |
}
|
|
729 |
}
|
|
730 |
offsetParent = o.offsetParent;
|
|
731 |
}
|
|
732 |
}
|
|
733 |
|
|
734 |
|
|
735 |
if (originalObject.offsetWidth) {
|
|
736 |
width = originalObject.offsetWidth;
|
|
737 |
}
|
|
738 |
if (originalObject.offsetHeight) {
|
|
739 |
height = originalObject.offsetHeight;
|
|
740 |
}
|
|
741 |
|
|
742 |
return {'left':left, 'top':top, 'width':width, 'height':height
|
|
743 |
};
|
|
744 |
};
|
|
745 |
|
|
746 |
// Retrieve the position of an object's center point
|
|
747 |
// =================================================
|
|
748 |
pos.getCenter = function(o) {
|
|
749 |
var c = this.get(o);
|
|
750 |
if (c==null) { return null; }
|
|
751 |
c.left = c.left + (c.width/2);
|
|
752 |
c.top = c.top + (c.height/2);
|
|
753 |
return c;
|
|
754 |
};
|
|
755 |
|
|
756 |
return pos;
|
|
757 |
})();// CLASS CONSTRUCTOR
|
|
758 |
// --------------------------------------------------------------------
|
|
759 |
var Popup = function(div, options) {
|
|
760 |
this.div = defined(div)?div:null;
|
|
761 |
this.index = Popup.maxIndex++;
|
|
762 |
this.ref = "Popup.objects["+this.index+"]";
|
|
763 |
Popup.objects[this.index] = this;
|
|
764 |
// Store a reference to the DIV by id, also
|
|
765 |
if (typeof(this.div)=="string") {
|
|
766 |
Popup.objectsById[this.div] = this;
|
|
767 |
}
|
|
768 |
if (defined(this.div) && this.div!=null && defined(this.div.id)) {
|
|
769 |
Popup.objectsById[this.div.id] = this.div.id;
|
|
770 |
}
|
|
771 |
// Apply passed-in options
|
|
772 |
if (defined(options) && options!=null && typeof(options)=="object") {
|
|
773 |
for (var i in options) {
|
|
774 |
this[i] = options[i];
|
|
775 |
}
|
|
776 |
}
|
|
777 |
return this;
|
|
778 |
};
|
|
779 |
|
|
780 |
// CLASS PROPERTIES
|
|
781 |
// --------------------------------------------------------------------
|
|
782 |
// Index of popup objects, to maintain a global reference if necessary
|
|
783 |
Popup.maxIndex = 0;
|
|
784 |
Popup.objects = {};
|
|
785 |
Popup.objectsById = {};
|
|
786 |
|
|
787 |
// The z-index value that popups will start at
|
|
788 |
Popup.minZIndex = 101;
|
|
789 |
|
|
790 |
// Class names to assign to other objects
|
|
791 |
Popup.screenClass = "PopupScreen";
|
|
792 |
Popup.iframeClass = "PopupIframe";
|
|
793 |
Popup.screenIframeClass = "PopupScreenIframe";
|
|
794 |
|
|
795 |
// CLASS METHODS
|
|
796 |
// --------------------------------------------------------------------
|
|
797 |
|
|
798 |
// Hide all currently-visible non-modal dialogs
|
|
799 |
Popup.hideAll = function() {
|
|
800 |
for (var i in Popup.objects) {
|
|
801 |
var p = Popup.objects[i];
|
|
802 |
if (!p.modal && p.autoHide) {
|
|
803 |
p.hide();
|
|
804 |
}
|
|
805 |
}
|
|
806 |
};
|
|
807 |
// Catch global events as a trigger to hide auto-hide popups
|
|
808 |
Event.add(document, "mouseup", Popup.hideAll, false);
|
|
809 |
|
|
810 |
// A simple class method to show a popup without creating an instance
|
|
811 |
Popup.show = function(divObject, referenceObject, position, options, modal) {
|
|
812 |
var popup;
|
|
813 |
if (defined(divObject)) {
|
|
814 |
popup = new Popup(divObject);
|
|
815 |
}
|
|
816 |
else {
|
|
817 |
popup = new Popup();
|
|
818 |
popup.destroyDivOnHide = true;
|
|
819 |
}
|
|
820 |
if (defined(referenceObject)) { popup.reference = DOM.resolve(referenceObject); }
|
|
821 |
if (defined(position)) { popup.position = position; }
|
|
822 |
if (defined(options) && options!=null && typeof(options)=="object") {
|
|
823 |
for (var i in options) {
|
|
824 |
popup[i] = options[i];
|
|
825 |
}
|
|
826 |
}
|
|
827 |
if (typeof(modal)=="boolean") {
|
|
828 |
popup.modal = modal;
|
|
829 |
}
|
|
830 |
popup.destroyObjectsOnHide = true;
|
|
831 |
popup.show();
|
|
832 |
return popup;
|
|
833 |
};
|
|
834 |
|
|
835 |
// A simple class method to show a modal popup
|
|
836 |
Popup.showModal = function(divObject, referenceObject, position, options) {
|
|
837 |
Popup.show(divObject, referenceObject, position, options, true);
|
|
838 |
};
|
|
839 |
|
|
840 |
// A method to retrieve a popup object based on a div ID
|
|
841 |
Popup.get = function(divId) {
|
|
842 |
if (defined(Popup.objectsById[divId])) {
|
|
843 |
return Popup.objectsById[divId];
|
|
844 |
}
|
|
845 |
return null;
|
|
846 |
};
|
|
847 |
|
|
848 |
// A method to hide a popup based on a div id
|
|
849 |
Popup.hide = function(divId) {
|
|
850 |
var popup = Popup.get(divId);
|
|
851 |
if (popup!=null) {
|
|
852 |
popup.hide();
|
|
853 |
}
|
|
854 |
};
|
|
855 |
|
|
856 |
// PROTOTYPE PROPERTIES
|
|
857 |
// --------------------------------------------------------------------
|
|
858 |
Popup.prototype.content = null;
|
|
859 |
Popup.prototype.className = "PopupDiv";
|
|
860 |
Popup.prototype.style = null; // Styles to be applied to the DIV
|
|
861 |
Popup.prototype.width = null;
|
|
862 |
Popup.prototype.height = null;
|
|
863 |
Popup.prototype.top = null;
|
|
864 |
Popup.prototype.left = null;
|
|
865 |
Popup.prototype.offsetLeft = 0;
|
|
866 |
Popup.prototype.offsetTop = 0;
|
|
867 |
Popup.prototype.constrainToScreen = true;
|
|
868 |
Popup.prototype.autoHide = true;
|
|
869 |
Popup.prototype.useIframeShim = false; /*@cc_on @*/ /*@if (@_win32) {Popup.prototype.useIframeShim = true;} @end @*/
|
|
870 |
Popup.prototype.iframe = null;
|
|
871 |
Popup.prototype.position = null; // vertical: "above top center bottom below", horizontal: "adjacent-left,left,center,right,adjacent-right"
|
|
872 |
Popup.prototype.reference = null;
|
|
873 |
Popup.prototype.modal = false;
|
|
874 |
Popup.prototype.destroyDivOnHide = false;
|
|
875 |
Popup.prototype.destroyObjectsOnHide = false;
|
|
876 |
Popup.prototype.screen = null;
|
|
877 |
Popup.prototype.screenIframeShim = null;
|
|
878 |
Popup.prototype.screenOpacity=.4;
|
|
879 |
Popup.prototype.screenColor="#cccccc";
|
|
880 |
|
|
881 |
// INSTANCE METHODS
|
|
882 |
// --------------------------------------------------------------------
|
|
883 |
|
|
884 |
// Show the popup
|
|
885 |
// --------------------------------------------------------------------
|
|
886 |
Popup.prototype.show = function(options, modal) {
|
|
887 |
this.modal = this.modal || (typeof(modal)=="boolean" && modal);
|
|
888 |
if (defined(options) && options!=null && typeof(options)=="object") {
|
|
889 |
for (var i in options) {
|
|
890 |
this[i] = options[i];
|
|
891 |
}
|
|
892 |
}
|
|
893 |
this.div = DOM.resolve(this.div);
|
|
894 |
CSS.setStyle(this.div,'position','absolute');
|
|
895 |
|
|
896 |
// If there is no div pre-defined to use, create one
|
|
897 |
if (this.div==null) {
|
|
898 |
this.div = this.createDiv();
|
|
899 |
}
|
|
900 |
if (this.content!=null) {
|
|
901 |
this.div.innerHTML = this.content;
|
|
902 |
this.content = null;
|
|
903 |
}
|
|
904 |
if (this.className!=null) {
|
|
905 |
this.div.className = this.className;
|
|
906 |
}
|
|
907 |
if (this.style!=null) {
|
|
908 |
this.applyStyle();
|
|
909 |
}
|
|
910 |
if (this.width!=null) {
|
|
911 |
this.div.style.width = this.width+"px";
|
|
912 |
this.div.style.overflowX="auto";
|
|
913 |
}
|
|
914 |
if (this.height!=null) {
|
|
915 |
this.div.style.height = this.height+"px";
|
|
916 |
this.div.style.overflowY="auto";
|
|
917 |
}
|
|
918 |
|
|
919 |
// Do the actual display - this is a separate method so display transitions can be implemented
|
|
920 |
this.transition();
|
|
921 |
|
|
922 |
// Make sure clicks on the DIV don't bubble up to the document
|
|
923 |
this.div.onclick = function(e) {
|
|
924 |
Event.cancelBubble(Event.resolve(e));
|
|
925 |
};
|
|
926 |
this.div.onmouseup = this.div.onclick;
|
|
927 |
|
|
928 |
// Focus to the DIV if possible
|
|
929 |
if (this.modal && this.div.focus) {
|
|
930 |
this.div.focus();
|
|
931 |
}
|
|
932 |
};
|
|
933 |
|
|
934 |
// Show the popup but make it modal
|
|
935 |
// --------------------------------------------------------------------
|
|
936 |
Popup.prototype.transition = function() {
|
|
937 |
if (this.modal) {
|
|
938 |
this.addScreen();
|
|
939 |
}
|
|
940 |
|
|
941 |
// Make the DIV displayed but hidden so its size can be measured
|
|
942 |
CSS.setStyle(this.div,'visibility','hidden');
|
|
943 |
CSS.setStyle(this.div,'display','block');
|
|
944 |
|
|
945 |
// Position the popup
|
|
946 |
this.setPosition();
|
|
947 |
|
|
948 |
// Add the shim if necessary
|
|
949 |
if (this.useIframeShim) {
|
|
950 |
this.addIframeShim();
|
|
951 |
}
|
|
952 |
|
|
953 |
// Make sure the DIV is higher than the shim
|
|
954 |
this.div.style.zIndex = Popup.minZIndex++;
|
|
955 |
|
|
956 |
CSS.setStyle(this.div,'display','block');
|
|
957 |
CSS.setStyle(this.div,'visibility','visible');
|
|
958 |
};
|
|
959 |
|
|
960 |
// Show the popup but make it modal
|
|
961 |
// --------------------------------------------------------------------
|
|
962 |
Popup.prototype.showModal = function(options) {
|
|
963 |
this.show(options,true);
|
|
964 |
};
|
|
965 |
|
|
966 |
// Apply user styles to the DIV
|
|
967 |
// --------------------------------------------------------------------
|
|
968 |
Popup.prototype.applyStyle = function() {
|
|
969 |
if (this.div!=null && this.style!=null && typeof(this.style)=="object") {
|
|
970 |
for (var i in this.style) {
|
|
971 |
this.div.style[i] = this.style[i];
|
|
972 |
}
|
|
973 |
}
|
|
974 |
};
|
|
975 |
|
|
976 |
// Hide the popup
|
|
977 |
// --------------------------------------------------------------------
|
|
978 |
Popup.prototype.hide = function() {
|
|
979 |
// If this was a temp object creating on-the-fly, then remove objects from the DOM so
|
|
980 |
// The document doesn't get littered with extra objects
|
|
981 |
if (this.destroyDivOnHide) {
|
|
982 |
DOM.removeNode(this.div);
|
|
983 |
this.div = null;
|
|
984 |
delete Popup.objects[this.id];
|
|
985 |
}
|
|
986 |
else if (this.div!=null) {
|
|
987 |
CSS.setStyle(this.div,'display','none');
|
|
988 |
}
|
|
989 |
|
|
990 |
if (this.destroyObjectsOnHide) {
|
|
991 |
DOM.removeNode(this.iframe);
|
|
992 |
DOM.removeNode(this.screen);
|
|
993 |
DOM.removeNode(this.screenIframeShim);
|
|
994 |
}
|
|
995 |
else {
|
|
996 |
if (this.iframe!=null) {
|
|
997 |
this.iframe.style.display = "none";
|
|
998 |
}
|
|
999 |
if (this.screen!=null) {
|
|
1000 |
this.screen.style.display = "none";
|
|
1001 |
}
|
|
1002 |
if (this.screenIframeShim!=null) {
|
|
1003 |
this.screenIframeShim.style.display = "none";
|
|
1004 |
}
|
|
1005 |
}
|
|
1006 |
};
|
|
1007 |
|
|
1008 |
// Util funcs for position
|
|
1009 |
// --------------------------------------------------------------------
|
|
1010 |
Popup.prototype.setTop = function(top) {
|
|
1011 |
this.div.style.top = top+"px";
|
|
1012 |
};
|
|
1013 |
Popup.prototype.setLeft = function(left) {
|
|
1014 |
this.div.style.left = left+"px";
|
|
1015 |
};
|
|
1016 |
Popup.prototype.getTop = function() {
|
|
1017 |
return parseInt(CSS.getStyle(this.div,"top"),10);
|
|
1018 |
};
|
|
1019 |
Popup.prototype.getLeft = function() {
|
|
1020 |
return parseInt(CSS.getStyle(this.div,"left"),10);
|
|
1021 |
};
|
|
1022 |
|
|
1023 |
// All the logic to position the popup based on various criteria
|
|
1024 |
// --------------------------------------------------------------------
|
|
1025 |
Popup.prototype.setPosition = function() {
|
|
1026 |
if (this.position!=null) {
|
|
1027 |
var m = this.position.match(/^(\S+)\s+(\S+)/);
|
|
1028 |
if (m!=null && m.length==3) {
|
|
1029 |
var v = m[1];
|
|
1030 |
var h = m[2];
|
|
1031 |
|
|
1032 |
var ref = this.reference;
|
|
1033 |
if (ref==null) { ref = Screen.getBody(); }
|
|
1034 |
var p = Position.get(ref);
|
|
1035 |
var refTop = p.top;
|
|
1036 |
var refLeft = p.left;
|
|
1037 |
var refWidth = DOM.getOuterWidth(ref);
|
|
1038 |
var refHeight = DOM.getOuterHeight(ref);
|
|
1039 |
|
|
1040 |
var width = DOM.getOuterWidth(this.div);
|
|
1041 |
var height = DOM.getOuterHeight(this.div);
|
|
1042 |
|
|
1043 |
var scrollLeft = Screen.getScrollLeft();
|
|
1044 |
var scrollTop = Screen.getScrollTop();
|
|
1045 |
|
|
1046 |
// Set vertical position relative to reference object
|
|
1047 |
if (v=="above") { this.setTop(refTop-height+this.offsetTop); }
|
|
1048 |
else if (v=="top") { this.setTop(refTop+this.offsetTop); }
|
|
1049 |
else if (v=="center") { this.setTop(refTop+(refHeight/2)-(height/2)+this.offsetTop); }
|
|
1050 |
else if (v=="bottom") { this.setTop(refTop+refHeight-height+this.offsetTop); }
|
|
1051 |
else if (v=="below") { this.setTop(refTop+refHeight+this.offsetTop); }
|
|
1052 |
|
|
1053 |
// Set horizontal position relative to reference object
|
|
1054 |
if (h=="adjacent-left") { this.setLeft(refLeft-width+this.offsetLeft); }
|
|
1055 |
else if (h=="left") { this.setLeft(refLeft+this.offsetLeft); }
|
|
1056 |
else if (h=="center") { this.setLeft(refLeft+(refWidth/2)-(width/2)+this.offsetLeft); }
|
|
1057 |
else if (h=="right") { this.setLeft(refLeft+refWidth-width+this.offsetLeft); }
|
|
1058 |
else if (h=="adjacent-right") { this.setLeft(refLeft+refWidth+this.offsetLeft); }
|
|
1059 |
}
|
|
1060 |
}
|
|
1061 |
else if (this.top==null && this.left==null) {
|
|
1062 |
this.center();
|
|
1063 |
}
|
|
1064 |
else {
|
|
1065 |
if (this.top==null) { this.top=0; }
|
|
1066 |
if (this.left==null) { this.left=0; }
|
|
1067 |
this.div.style.top = this.top+this.offsetTop+"px";
|
|
1068 |
this.div.style.left = this.left+this.offsetLeft+"px";
|
|
1069 |
}
|
|
1070 |
|
|
1071 |
// Re-position to make sure it stays on the screen
|
|
1072 |
if (this.constrainToScreen) {
|
|
1073 |
this.fitToScreen();
|
|
1074 |
}
|
|
1075 |
};
|
|
1076 |
|
|
1077 |
// Append an object to the body
|
|
1078 |
// --------------------------------------------------------------------
|
|
1079 |
Popup.prototype.appendToBody = function(o) {
|
|
1080 |
var body = Screen.getBody();
|
|
1081 |
if (body && body.appendChild) {
|
|
1082 |
body.appendChild(o);
|
|
1083 |
}
|
|
1084 |
};
|
|
1085 |
|
|
1086 |
// Create a new DIV object to be used for a popup
|
|
1087 |
// --------------------------------------------------------------------
|
|
1088 |
Popup.prototype.createDiv = function() {
|
|
1089 |
if (document.createElement) {
|
|
1090 |
var d = document.createElement("DIV");
|
|
1091 |
d.style.position="absolute";
|
|
1092 |
d.style.display="block";
|
|
1093 |
d.style.visibility="hidden";
|
|
1094 |
this.appendToBody(d);
|
|
1095 |
return d;
|
|
1096 |
}
|
|
1097 |
alert("ERROR: Couldn't create DIV element in Popup.prototype.createDiv()");
|
|
1098 |
return null;
|
|
1099 |
};
|
|
1100 |
|
|
1101 |
// Create a new IFRAME object to be used behind the popup
|
|
1102 |
// --------------------------------------------------------------------
|
|
1103 |
Popup.prototype.createIframe = function() {
|
|
1104 |
if (document.createElement) {
|
|
1105 |
var i= document.createElement("IFRAME");
|
|
1106 |
i.style.position="absolute";
|
|
1107 |
i.style.display="block";
|
|
1108 |
i.style.visibility="hidden";
|
|
1109 |
i.style.background="none";
|
|
1110 |
this.appendToBody(i);
|
|
1111 |
return i;
|
|
1112 |
}
|
|
1113 |
else {
|
|
1114 |
alert("ERROR: Couldn't create IFRAME object in Popup.prototype.createIframe()");
|
|
1115 |
}
|
|
1116 |
};
|
|
1117 |
|
|
1118 |
// Add an IFRAME shim for the DIV
|
|
1119 |
// --------------------------------------------------------------------
|
|
1120 |
Popup.prototype.addIframeShim = function() {
|
|
1121 |
if (this.iframe==null) {
|
|
1122 |
this.iframe = this.createIframe();
|
|
1123 |
}
|
|
1124 |
this.iframe.className = Popup.iframeClass;
|
|
1125 |
CSS.setStyle(this.iframe,'top',this.getTop()+"px");
|
|
1126 |
CSS.setStyle(this.iframe,'left',this.getLeft()+"px");
|
|
1127 |
CSS.setStyle(this.iframe,'width',DOM.getOuterWidth(this.div) + "px");
|
|
1128 |
CSS.setStyle(this.iframe,'height',DOM.getOuterHeight(this.div) + "px");
|
|
1129 |
CSS.setStyle(this.iframe,'zIndex',Popup.minZIndex++);
|
|
1130 |
CSS.setStyle(this.iframe,'opacity',0);
|
|
1131 |
CSS.setStyle(this.iframe,'visibility','visible');
|
|
1132 |
CSS.setStyle(this.iframe,'display','block');
|
|
1133 |
};
|
|
1134 |
|
|
1135 |
// Create a "screen" to make a popup modal
|
|
1136 |
// --------------------------------------------------------------------
|
|
1137 |
Popup.prototype.addScreen = function() {
|
|
1138 |
if (this.screen==null) {
|
|
1139 |
this.screen = this.createDiv();
|
|
1140 |
this.screen.style.top="0px";
|
|
1141 |
this.screen.style.left="0px";
|
|
1142 |
this.screen.style.backgroundColor = this.screenColor;
|
|
1143 |
this.screen.className=Popup.screenClass;;
|
|
1144 |
CSS.setStyle(this.screen,"opacity",this.screenOpacity);
|
|
1145 |
this.screen.onclick = function(e) { Event.cancelBubble(Event.resolve(e)); }
|
|
1146 |
}
|
|
1147 |
if (this.screenIframeShim==null) {
|
|
1148 |
this.screenIframeShim = this.createIframe();
|
|
1149 |
this.screenIframeShim.style.top="0px";
|
|
1150 |
this.screenIframeShim.style.left="0px";
|
|
1151 |
this.screenIframeShim.className=Popup.screenIframeClass;
|
|
1152 |
CSS.setStyle(this.screenIframeShim,"opacity",0);
|
|
1153 |
}
|
|
1154 |
this.screen.style.width = Screen.getDocumentWidth()+"px";
|
|
1155 |
this.screen.style.height = Screen.getDocumentHeight()+"px";
|
|
1156 |
this.screenIframeShim.style.width = Screen.getDocumentWidth()+"px";
|
|
1157 |
this.screenIframeShim.style.height = Screen.getDocumentHeight()+"px";
|
|
1158 |
this.screenIframeShim.style.zIndex = Popup.minZIndex++;
|
|
1159 |
this.screenIframeShim.style.visibility="visible";
|
|
1160 |
this.screenIframeShim.style.display="block";
|
|
1161 |
this.screen.style.zIndex = Popup.minZIndex++;
|
|
1162 |
this.screen.style.visibility="visible";
|
|
1163 |
this.screen.style.display="block";
|
|
1164 |
};
|
|
1165 |
|
|
1166 |
// Re-position the DIV so it stays on the screen
|
|
1167 |
// --------------------------------------------------------------------
|
|
1168 |
Popup.prototype.fitToScreen = function() {
|
|
1169 |
var width = DOM.getOuterWidth(this.div);
|
|
1170 |
var height = DOM.getOuterHeight(this.div);
|
|
1171 |
var top = this.getTop();
|
|
1172 |
var left = this.getLeft();
|
|
1173 |
|
|
1174 |
var clientWidth = Screen.getViewportWidth();
|
|
1175 |
var clientHeight = Screen.getViewportHeight();
|
|
1176 |
|
|
1177 |
var scrollLeft = Screen.getScrollLeft();
|
|
1178 |
var scrollTop = Screen.getScrollTop();
|
|
1179 |
|
|
1180 |
if (top-scrollTop+height>clientHeight) {
|
|
1181 |
top = top - ((top+height) - (scrollTop+clientHeight));
|
|
1182 |
this.div.style.top = top + "px";
|
|
1183 |
}
|
|
1184 |
if (left-scrollLeft+width>clientWidth) {
|
|
1185 |
left = left - ((left+width) - (scrollLeft+clientWidth));
|
|
1186 |
this.div.style.left = left + "px";
|
|
1187 |
}
|
|
1188 |
if (top<scrollTop) {
|
|
1189 |
this.div.style.top=scrollTop+"px";
|
|
1190 |
}
|
|
1191 |
if (left<scrollLeft) {
|
|
1192 |
this.div.style.left=scrollLeft+"px";
|
|
1193 |
}
|
|
1194 |
};
|
|
1195 |
|
|
1196 |
// Center the DIV object
|
|
1197 |
// --------------------------------------------------------------------
|
|
1198 |
Popup.prototype.center = function() {
|
|
1199 |
var left = DOM.getOuterWidth(this.div);
|
|
1200 |
var top = DOM.getOuterHeight(this.div);
|
|
1201 |
if (isNaN(left)) { left=0; }
|
|
1202 |
if (isNaN(top)) { top=0; }
|
|
1203 |
var clientW = Screen.getViewportWidth();
|
|
1204 |
var clientH = Screen.getViewportHeight();
|
|
1205 |
if (clientW!=null && clientH!=null) {
|
|
1206 |
top = (clientH-top)/2;
|
|
1207 |
left = (clientW-left)/2;
|
|
1208 |
}
|
|
1209 |
top += Screen.getScrollTop();
|
|
1210 |
left += Screen.getScrollLeft();
|
|
1211 |
|
|
1212 |
this.div.style.top = top+this.offsetTop+"px";
|
|
1213 |
this.div.style.left = left+this.offsetLeft+"px";
|
|
1214 |
};
|
|
1215 |
|