diff options
Diffstat (limited to 'httemplate/elements')
39 files changed, 5193 insertions, 0 deletions
diff --git a/httemplate/elements/calendar-en.js b/httemplate/elements/calendar-en.js new file mode 100644 index 000000000..e9d6a222e --- /dev/null +++ b/httemplate/elements/calendar-en.js @@ -0,0 +1,123 @@ +// ** I18N + +// Calendar EN language +// Author: Mihai Bazon, <mishoo@infoiasi.ro> +// Encoding: any +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + "Sunday"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("Sun", + "Mon", + "Tue", + "Wed", + "Thu", + "Fri", + "Sat", + "Sun"); + +// full month names +Calendar._MN = new Array +("January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December"); + +// short month names +Calendar._SMN = new Array +("Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "About the calendar"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2003\n" + // don't translate this this ;-) +"For latest version visit: http://dynarch.com/mishoo/calendar.epl\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"Date selection:\n" + +"- Use the \xab, \xbb buttons to select year\n" + +"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" + +"- Hold mouse button on any of the above buttons for faster selection."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Time selection:\n" + +"- Click on any of the time parts to increase it\n" + +"- or Shift-click to decrease it\n" + +"- or click and drag for faster selection."; + +Calendar._TT["PREV_YEAR"] = "Prev. year (hold for menu)"; +Calendar._TT["PREV_MONTH"] = "Prev. month (hold for menu)"; +Calendar._TT["GO_TODAY"] = "Go Today"; +Calendar._TT["NEXT_MONTH"] = "Next month (hold for menu)"; +Calendar._TT["NEXT_YEAR"] = "Next year (hold for menu)"; +Calendar._TT["SEL_DATE"] = "Select date"; +Calendar._TT["DRAG_TO_MOVE"] = "Drag to move"; +Calendar._TT["PART_TODAY"] = " (today)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Display %s first"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Close"; +Calendar._TT["TODAY"] = "Today"; +Calendar._TT["TIME_PART"] = "(Shift-)Click or drag to change value"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; + +Calendar._TT["WK"] = "wk"; +Calendar._TT["TIME"] = "Time:"; diff --git a/httemplate/elements/calendar-setup.js b/httemplate/elements/calendar-setup.js new file mode 100644 index 000000000..55e22b933 --- /dev/null +++ b/httemplate/elements/calendar-setup.js @@ -0,0 +1,181 @@ +/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/ + * --------------------------------------------------------------------------- + * + * The DHTML Calendar + * + * Details and latest version at: + * http://dynarch.com/mishoo/calendar.epl + * + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html + * + * This file defines helper functions for setting up the calendar. They are + * intended to help non-programmers get a working calendar on their site + * quickly. This script should not be seen as part of the calendar. It just + * shows you what one can do with the calendar, while in the same time + * providing a quick and simple method for setting it up. If you need + * exhaustive customization of the calendar creation process feel free to + * modify this code to suit your needs (this is recommended and much better + * than modifying calendar.js itself). + */ + +// $Id: calendar-setup.js,v 1.4 2004-09-22 11:04:41 ivan Exp $ + +/** + * This function "patches" an input field (or other element) to use a calendar + * widget for date selection. + * + * The "params" is a single object that can have the following properties: + * + * prop. name | description + * ------------------------------------------------------------------------------------------------- + * inputField | the ID of an input field to store the date + * displayArea | the ID of a DIV or other element to show the date + * button | ID of a button or other element that will trigger the calendar + * eventName | event that will trigger the calendar, without the "on" prefix (default: "click") + * ifFormat | date format that will be stored in the input field + * daFormat | the date format that will be used to display the date in displayArea + * singleClick | (true/false) wether the calendar is in single click mode or not (default: true) + * firstDay | numeric: 0 to 6. "0" means display Sunday first, "1" means display Monday first, etc. + * align | alignment (default: "Br"); if you don't know what's this see the calendar documentation + * range | array with 2 elements. Default: [1900, 2999] -- the range of years available + * weekNumbers | (true/false) if it's true (default) the calendar will display week numbers + * flat | null or element ID; if not null the calendar will be a flat calendar having the parent with the given ID + * flatCallback | function that receives a JS Date object and returns an URL to point the browser to (for flat calendar) + * disableFunc | function that receives a JS Date object and should return true if that date has to be disabled in the calendar + * onSelect | function that gets called when a date is selected. You don't _have_ to supply this (the default is generally okay) + * onClose | function that gets called when the calendar is closed. [default] + * onUpdate | function that gets called after the date is updated in the input field. Receives a reference to the calendar. + * date | the date that the calendar will be initially displayed to + * showsTime | default: false; if true the calendar will include a time selector + * timeFormat | the time format; can be "12" or "24", default is "12" + * electric | if true (default) then given fields/date areas are updated for each move; otherwise they're updated only on close + * step | configures the step of the years in drop-down boxes; default: 2 + * position | configures the calendar absolute position; default: null + * cache | if "true" (but default: "false") it will reuse the same calendar object, where possible + * showOthers | if "true" (but default: "false") it will show days from other months too + * + * None of them is required, they all have default values. However, if you + * pass none of "inputField", "displayArea" or "button" you'll get a warning + * saying "nothing to setup". + */ +Calendar.setup = function (params) { + function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } }; + + param_default("inputField", null); + param_default("displayArea", null); + param_default("button", null); + param_default("eventName", "click"); + param_default("ifFormat", "%Y/%m/%d"); + param_default("daFormat", "%Y/%m/%d"); + param_default("singleClick", true); + param_default("disableFunc", null); + param_default("dateStatusFunc", params["disableFunc"]); // takes precedence if both are defined + param_default("firstDay", 0); // defaults to "Sunday" first + param_default("align", "Br"); + param_default("range", [1900, 2999]); + param_default("weekNumbers", true); + param_default("flat", null); + param_default("flatCallback", null); + param_default("onSelect", null); + param_default("onClose", null); + param_default("onUpdate", null); + param_default("date", null); + param_default("showsTime", false); + param_default("timeFormat", "24"); + param_default("electric", true); + param_default("step", 2); + param_default("position", null); + param_default("cache", false); + param_default("showOthers", false); + + var tmp = ["inputField", "displayArea", "button"]; + for (var i in tmp) { + if (typeof params[tmp[i]] == "string") { + params[tmp[i]] = document.getElementById(params[tmp[i]]); + } + } + if (!(params.flat || params.inputField || params.displayArea || params.button)) { + alert("Calendar.setup:\n Nothing to setup (no fields found). Please check your code"); + return false; + } + + function onSelect(cal) { + var p = cal.params; + var update = (cal.dateClicked || p.electric); + if (update && p.flat) { + if (typeof p.flatCallback == "function") + p.flatCallback(cal); + else + alert("No flatCallback given -- doing nothing."); + return false; + } + if (update && p.inputField) { + p.inputField.value = cal.date.print(p.ifFormat); + if (typeof p.inputField.onchange == "function") + p.inputField.onchange(); + } + if (update && p.displayArea) + p.displayArea.innerHTML = cal.date.print(p.daFormat); + if (update && p.singleClick && cal.dateClicked) + cal.callCloseHandler(); + if (update && typeof p.onUpdate == "function") + p.onUpdate(cal); + }; + + if (params.flat != null) { + if (typeof params.flat == "string") + params.flat = document.getElementById(params.flat); + if (!params.flat) { + alert("Calendar.setup:\n Flat specified but can't find parent."); + return false; + } + var cal = new Calendar(params.firstDay, params.date, params.onSelect || onSelect); + cal.showsTime = params.showsTime; + cal.time24 = (params.timeFormat == "24"); + cal.params = params; + cal.weekNumbers = params.weekNumbers; + cal.setRange(params.range[0], params.range[1]); + cal.setDateStatusHandler(params.dateStatusFunc); + cal.create(params.flat); + cal.show(); + return false; + } + + var triggerEl = params.button || params.displayArea || params.inputField; + triggerEl["on" + params.eventName] = function() { + var dateEl = params.inputField || params.displayArea; + var dateFmt = params.inputField ? params.ifFormat : params.daFormat; + var mustCreate = false; + var cal = window.calendar; + if (!(cal && params.cache)) { + window.calendar = cal = new Calendar(params.firstDay, + params.date, + params.onSelect || onSelect, + params.onClose || function(cal) { cal.hide(); }); + cal.showsTime = params.showsTime; + cal.time24 = (params.timeFormat == "24"); + cal.weekNumbers = params.weekNumbers; + mustCreate = true; + } else { + if (params.date) + cal.setDate(params.date); + cal.hide(); + } + cal.showsOtherMonths = params.showOthers; + cal.yearStep = params.step; + cal.setRange(params.range[0], params.range[1]); + cal.params = params; + cal.setDateStatusHandler(params.dateStatusFunc); + cal.setDateFormat(dateFmt); + if (mustCreate) + cal.create(); + cal.parseDate(dateEl.value || dateEl.innerHTML); + cal.refresh(); + if (!params.position) + cal.showAtElement(params.button || params.displayArea || params.inputField, params.align); + else + cal.showAt(params.position[0], params.position[1]); + return false; + }; +}; diff --git a/httemplate/elements/calendar-win2k-2.css b/httemplate/elements/calendar-win2k-2.css new file mode 100644 index 000000000..6001cfaa4 --- /dev/null +++ b/httemplate/elements/calendar-win2k-2.css @@ -0,0 +1,270 @@ +/* The main calendar widget. DIV containing a table. */ + +.calendar { + position: relative; + display: none; + border-top: 2px solid #fff; + border-right: 2px solid #000; + border-bottom: 2px solid #000; + border-left: 2px solid #fff; + font-size: 11px; + color: #000; + cursor: default; + background: #d4c8d0; + font-family: tahoma,verdana,sans-serif; +} + +.calendar table { + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; + font-size: 11px; + color: #000; + cursor: default; + background: #d4c8d0; + font-family: tahoma,verdana,sans-serif; +} + +/* Header part -- contains navigation buttons and day names. */ + +.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ + text-align: center; + padding: 1px; + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; +} + +.calendar .nav { + background: transparent url(menuarrow.gif) no-repeat 100% 100%; +} + +.calendar thead .title { /* This holds the current "month, year" */ + font-weight: bold; + padding: 1px; + border: 1px solid #000; + background: #847880; + color: #fff; + text-align: center; +} + +.calendar thead .headrow { /* Row <TR> containing navigation buttons */ +} + +.calendar thead .daynames { /* Row <TR> containing the day names */ +} + +.calendar thead .name { /* Cells <TD> containing the day names */ + border-bottom: 1px solid #000; + padding: 2px; + text-align: center; + background: #f4e8f0; +} + +.calendar thead .weekend { /* How a weekend day name shows in header */ + color: #f00; +} + +.calendar thead .hilite { /* How do the buttons in header appear when hover */ + border-top: 2px solid #fff; + border-right: 2px solid #000; + border-bottom: 2px solid #000; + border-left: 2px solid #fff; + padding: 0px; + background-color: #e4d8e0; +} + +.calendar thead .active { /* Active (pressed) buttons in header */ + padding: 2px 0px 0px 2px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; + background-color: #c4b8c0; +} + +/* The body part -- contains all the days in month. */ + +.calendar tbody .day { /* Cells <TD> containing month days dates */ + width: 2em; + text-align: right; + padding: 2px 4px 2px 2px; +} +.calendar tbody .day.othermonth { + font-size: 80%; + color: #aaa; +} +.calendar tbody .day.othermonth.oweekend { + color: #faa; +} + +.calendar table .wn { + padding: 2px 3px 2px 2px; + border-right: 1px solid #000; + background: #f4e8f0; +} + +.calendar tbody .rowhilite td { + background: #e4d8e0; +} + +.calendar tbody .rowhilite td.wn { + background: #d4c8d0; +} + +.calendar tbody td.hilite { /* Hovered cells <TD> */ + padding: 1px 3px 1px 1px; + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; +} + +.calendar tbody td.active { /* Active (pressed) cells <TD> */ + padding: 2px 2px 0px 2px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; +} + +.calendar tbody td.selected { /* Cell showing selected date */ + font-weight: bold; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; + padding: 2px 2px 0px 2px; + background: #e4d8e0; +} + +.calendar tbody td.weekend { /* Cells showing weekend days */ + color: #f00; +} + +.calendar tbody td.today { /* Cell showing today date */ + font-weight: bold; + color: #00f; +} + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ + visibility: hidden; +} + +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ + display: none; +} + +/* The footer part -- status bar and "Close" button */ + +.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */ +} + +.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */ + background: #f4e8f0; + padding: 1px; + border: 1px solid #000; + background: #847880; + color: #fff; + text-align: center; +} + +.calendar tfoot .hilite { /* Hover style for buttons in footer */ + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; + padding: 1px; + background: #e4d8e0; +} + +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */ + padding: 2px 0px 0px 2px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; +} + +/* Combo boxes (menus that display months/years for direct selection) */ + +.calendar .combo { + position: absolute; + display: none; + width: 4em; + top: 0px; + left: 0px; + cursor: default; + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; + background: #e4d8e0; + font-size: 90%; + padding: 1px; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { + text-align: center; + padding: 1px; +} + +.calendar .combo .label-IEfix { + width: 4em; +} + +.calendar .combo .active { + background: #d4c8d0; + padding: 0px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; +} + +.calendar .combo .hilite { + background: #408; + color: #fea; +} + +.calendar td.time { + border-top: 1px solid #000; + padding: 1px 0px; + text-align: center; + background-color: #f4f0e8; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #766; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/httemplate/elements/calendar.js b/httemplate/elements/calendar.js new file mode 100644 index 000000000..ec18d80ce --- /dev/null +++ b/httemplate/elements/calendar.js @@ -0,0 +1,1715 @@ +/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/ + * ------------------------------------------------------------------ + * + * The DHTML Calendar, version 0.9.6 "Keep cool but don't freeze" + * + * Details and latest version at: + * http://dynarch.com/mishoo/calendar.epl + * + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html + */ + +// $Id: calendar.js,v 1.4 2004-09-22 11:04:41 ivan Exp $ + +/** The Calendar object constructor. */ +Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) { + // member variables + this.activeDiv = null; + this.currentDateEl = null; + this.getDateStatus = null; + this.timeout = null; + this.onSelected = onSelected || null; + this.onClose = onClose || null; + this.dragging = false; + this.hidden = false; + this.minYear = 1970; + this.maxYear = 2050; + this.dateFormat = Calendar._TT["DEF_DATE_FORMAT"]; + this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"]; + this.isPopup = true; + this.weekNumbers = true; + this.firstDayOfWeek = firstDayOfWeek; // 0 for Sunday, 1 for Monday, etc. + this.showsOtherMonths = false; + this.dateStr = dateStr; + this.ar_days = null; + this.showsTime = false; + this.time24 = true; + this.yearStep = 2; + // HTML elements + this.table = null; + this.element = null; + this.tbody = null; + this.firstdayname = null; + // Combo boxes + this.monthsCombo = null; + this.yearsCombo = null; + this.hilitedMonth = null; + this.activeMonth = null; + this.hilitedYear = null; + this.activeYear = null; + // Information + this.dateClicked = false; + + // one-time initializations + if (typeof Calendar._SDN == "undefined") { + // table of short day names + if (typeof Calendar._SDN_len == "undefined") + Calendar._SDN_len = 3; + var ar = new Array(); + for (var i = 8; i > 0;) { + ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len); + } + Calendar._SDN = ar; + // table of short month names + if (typeof Calendar._SMN_len == "undefined") + Calendar._SMN_len = 3; + ar = new Array(); + for (var i = 12; i > 0;) { + ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len); + } + Calendar._SMN = ar; + } +}; + +// ** constants + +/// "static", needed for event handlers. +Calendar._C = null; + +/// detect a special case of "web browser" +Calendar.is_ie = ( /msie/i.test(navigator.userAgent) && + !/opera/i.test(navigator.userAgent) ); + +Calendar.is_ie5 = ( Calendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) ); + +/// detect Opera browser +Calendar.is_opera = /opera/i.test(navigator.userAgent); + +/// detect KHTML-based browsers +Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent); + +// BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate +// library, at some point. + +Calendar.getAbsolutePos = function(el) { + var SL = 0, ST = 0; + var is_div = /^div$/i.test(el.tagName); + if (is_div && el.scrollLeft) + SL = el.scrollLeft; + if (is_div && el.scrollTop) + ST = el.scrollTop; + var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST }; + if (el.offsetParent) { + var tmp = this.getAbsolutePos(el.offsetParent); + r.x += tmp.x; + r.y += tmp.y; + } + return r; +}; + +Calendar.isRelated = function (el, evt) { + var related = evt.relatedTarget; + if (!related) { + var type = evt.type; + if (type == "mouseover") { + related = evt.fromElement; + } else if (type == "mouseout") { + related = evt.toElement; + } + } + while (related) { + if (related == el) { + return true; + } + related = related.parentNode; + } + return false; +}; + +Calendar.removeClass = function(el, className) { + if (!(el && el.className)) { + return; + } + var cls = el.className.split(" "); + var ar = new Array(); + for (var i = cls.length; i > 0;) { + if (cls[--i] != className) { + ar[ar.length] = cls[i]; + } + } + el.className = ar.join(" "); +}; + +Calendar.addClass = function(el, className) { + Calendar.removeClass(el, className); + el.className += " " + className; +}; + +Calendar.getElement = function(ev) { + if (Calendar.is_ie) { + return window.event.srcElement; + } else { + return ev.currentTarget; + } +}; + +Calendar.getTargetElement = function(ev) { + if (Calendar.is_ie) { + return window.event.srcElement; + } else { + return ev.target; + } +}; + +Calendar.stopEvent = function(ev) { + ev || (ev = window.event); + if (Calendar.is_ie) { + ev.cancelBubble = true; + ev.returnValue = false; + } else { + ev.preventDefault(); + ev.stopPropagation(); + } + return false; +}; + +Calendar.addEvent = function(el, evname, func) { + if (el.attachEvent) { // IE + el.attachEvent("on" + evname, func); + } else if (el.addEventListener) { // Gecko / W3C + el.addEventListener(evname, func, true); + } else { + el["on" + evname] = func; + } +}; + +Calendar.removeEvent = function(el, evname, func) { + if (el.detachEvent) { // IE + el.detachEvent("on" + evname, func); + } else if (el.removeEventListener) { // Gecko / W3C + el.removeEventListener(evname, func, true); + } else { + el["on" + evname] = null; + } +}; + +Calendar.createElement = function(type, parent) { + var el = null; + if (document.createElementNS) { + // use the XHTML namespace; IE won't normally get here unless + // _they_ "fix" the DOM2 implementation. + el = document.createElementNS("http://www.w3.org/1999/xhtml", type); + } else { + el = document.createElement(type); + } + if (typeof parent != "undefined") { + parent.appendChild(el); + } + return el; +}; + +// END: UTILITY FUNCTIONS + +// BEGIN: CALENDAR STATIC FUNCTIONS + +/** Internal -- adds a set of events to make some element behave like a button. */ +Calendar._add_evs = function(el) { + with (Calendar) { + addEvent(el, "mouseover", dayMouseOver); + addEvent(el, "mousedown", dayMouseDown); + addEvent(el, "mouseout", dayMouseOut); + if (is_ie) { + addEvent(el, "dblclick", dayMouseDblClick); + el.setAttribute("unselectable", true); + } + } +}; + +Calendar.findMonth = function(el) { + if (typeof el.month != "undefined") { + return el; + } else if (typeof el.parentNode.month != "undefined") { + return el.parentNode; + } + return null; +}; + +Calendar.findYear = function(el) { + if (typeof el.year != "undefined") { + return el; + } else if (typeof el.parentNode.year != "undefined") { + return el.parentNode; + } + return null; +}; + +Calendar.showMonthsCombo = function () { + var cal = Calendar._C; + if (!cal) { + return false; + } + var cal = cal; + var cd = cal.activeDiv; + var mc = cal.monthsCombo; + if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + if (cal.activeMonth) { + Calendar.removeClass(cal.activeMonth, "active"); + } + var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()]; + Calendar.addClass(mon, "active"); + cal.activeMonth = mon; + var s = mc.style; + s.display = "block"; + if (cd.navtype < 0) + s.left = cd.offsetLeft + "px"; + else { + var mcw = mc.offsetWidth; + if (typeof mcw == "undefined") + // Konqueror brain-dead techniques + mcw = 50; + s.left = (cd.offsetLeft + cd.offsetWidth - mcw) + "px"; + } + s.top = (cd.offsetTop + cd.offsetHeight) + "px"; +}; + +Calendar.showYearsCombo = function (fwd) { + var cal = Calendar._C; + if (!cal) { + return false; + } + var cal = cal; + var cd = cal.activeDiv; + var yc = cal.yearsCombo; + if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + if (cal.activeYear) { + Calendar.removeClass(cal.activeYear, "active"); + } + cal.activeYear = null; + var Y = cal.date.getFullYear() + (fwd ? 1 : -1); + var yr = yc.firstChild; + var show = false; + for (var i = 12; i > 0; --i) { + if (Y >= cal.minYear && Y <= cal.maxYear) { + yr.firstChild.data = Y; + yr.year = Y; + yr.style.display = "block"; + show = true; + } else { + yr.style.display = "none"; + } + yr = yr.nextSibling; + Y += fwd ? cal.yearStep : -cal.yearStep; + } + if (show) { + var s = yc.style; + s.display = "block"; + if (cd.navtype < 0) + s.left = cd.offsetLeft + "px"; + else { + var ycw = yc.offsetWidth; + if (typeof ycw == "undefined") + // Konqueror brain-dead techniques + ycw = 50; + s.left = (cd.offsetLeft + cd.offsetWidth - ycw) + "px"; + } + s.top = (cd.offsetTop + cd.offsetHeight) + "px"; + } +}; + +// event handlers + +Calendar.tableMouseUp = function(ev) { + var cal = Calendar._C; + if (!cal) { + return false; + } + if (cal.timeout) { + clearTimeout(cal.timeout); + } + var el = cal.activeDiv; + if (!el) { + return false; + } + var target = Calendar.getTargetElement(ev); + ev || (ev = window.event); + Calendar.removeClass(el, "active"); + if (target == el || target.parentNode == el) { + Calendar.cellClick(el, ev); + } + var mon = Calendar.findMonth(target); + var date = null; + if (mon) { + date = new Date(cal.date); + if (mon.month != date.getMonth()) { + date.setMonth(mon.month); + cal.setDate(date); + cal.dateClicked = false; + cal.callHandler(); + } + } else { + var year = Calendar.findYear(target); + if (year) { + date = new Date(cal.date); + if (year.year != date.getFullYear()) { + date.setFullYear(year.year); + cal.setDate(date); + cal.dateClicked = false; + cal.callHandler(); + } + } + } + with (Calendar) { + removeEvent(document, "mouseup", tableMouseUp); + removeEvent(document, "mouseover", tableMouseOver); + removeEvent(document, "mousemove", tableMouseOver); + cal._hideCombos(); + _C = null; + return stopEvent(ev); + } +}; + +Calendar.tableMouseOver = function (ev) { + var cal = Calendar._C; + if (!cal) { + return; + } + var el = cal.activeDiv; + var target = Calendar.getTargetElement(ev); + if (target == el || target.parentNode == el) { + Calendar.addClass(el, "hilite active"); + Calendar.addClass(el.parentNode, "rowhilite"); + } else { + if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2))) + Calendar.removeClass(el, "active"); + Calendar.removeClass(el, "hilite"); + Calendar.removeClass(el.parentNode, "rowhilite"); + } + ev || (ev = window.event); + if (el.navtype == 50 && target != el) { + var pos = Calendar.getAbsolutePos(el); + var w = el.offsetWidth; + var x = ev.clientX; + var dx; + var decrease = true; + if (x > pos.x + w) { + dx = x - pos.x - w; + decrease = false; + } else + dx = pos.x - x; + + if (dx < 0) dx = 0; + var range = el._range; + var current = el._current; + var count = Math.floor(dx / 10) % range.length; + for (var i = range.length; --i >= 0;) + if (range[i] == current) + break; + while (count-- > 0) + if (decrease) { + if (--i < 0) + i = range.length - 1; + } else if ( ++i >= range.length ) + i = 0; + var newval = range[i]; + el.firstChild.data = newval; + + cal.onUpdateTime(); + } + var mon = Calendar.findMonth(target); + if (mon) { + if (mon.month != cal.date.getMonth()) { + if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + Calendar.addClass(mon, "hilite"); + cal.hilitedMonth = mon; + } else if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + } else { + if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + var year = Calendar.findYear(target); + if (year) { + if (year.year != cal.date.getFullYear()) { + if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + Calendar.addClass(year, "hilite"); + cal.hilitedYear = year; + } else if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + } else if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + } + return Calendar.stopEvent(ev); +}; + +Calendar.tableMouseDown = function (ev) { + if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) { + return Calendar.stopEvent(ev); + } +}; + +Calendar.calDragIt = function (ev) { + var cal = Calendar._C; + if (!(cal && cal.dragging)) { + return false; + } + var posX; + var posY; + if (Calendar.is_ie) { + posY = window.event.clientY + document.body.scrollTop; + posX = window.event.clientX + document.body.scrollLeft; + } else { + posX = ev.pageX; + posY = ev.pageY; + } + cal.hideShowCovered(); + var st = cal.element.style; + st.left = (posX - cal.xOffs) + "px"; + st.top = (posY - cal.yOffs) + "px"; + return Calendar.stopEvent(ev); +}; + +Calendar.calDragEnd = function (ev) { + var cal = Calendar._C; + if (!cal) { + return false; + } + cal.dragging = false; + with (Calendar) { + removeEvent(document, "mousemove", calDragIt); + removeEvent(document, "mouseup", calDragEnd); + tableMouseUp(ev); + } + cal.hideShowCovered(); +}; + +Calendar.dayMouseDown = function(ev) { + var el = Calendar.getElement(ev); + if (el.disabled) { + return false; + } + var cal = el.calendar; + cal.activeDiv = el; + Calendar._C = cal; + if (el.navtype != 300) with (Calendar) { + if (el.navtype == 50) { + el._current = el.firstChild.data; + addEvent(document, "mousemove", tableMouseOver); + } else + addEvent(document, Calendar.is_ie5 ? "mousemove" : "mouseover", tableMouseOver); + addClass(el, "hilite active"); + addEvent(document, "mouseup", tableMouseUp); + } else if (cal.isPopup) { + cal._dragStart(ev); + } + if (el.navtype == -1 || el.navtype == 1) { + if (cal.timeout) clearTimeout(cal.timeout); + cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250); + } else if (el.navtype == -2 || el.navtype == 2) { + if (cal.timeout) clearTimeout(cal.timeout); + cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250); + } else { + cal.timeout = null; + } + return Calendar.stopEvent(ev); +}; + +Calendar.dayMouseDblClick = function(ev) { + Calendar.cellClick(Calendar.getElement(ev), ev || window.event); + if (Calendar.is_ie) { + document.selection.empty(); + } +}; + +Calendar.dayMouseOver = function(ev) { + var el = Calendar.getElement(ev); + if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) { + return false; + } + if (el.ttip) { + if (el.ttip.substr(0, 1) == "_") { + el.ttip = el.caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1); + } + el.calendar.tooltips.firstChild.data = el.ttip; + } + if (el.navtype != 300) { + Calendar.addClass(el, "hilite"); + if (el.caldate) { + Calendar.addClass(el.parentNode, "rowhilite"); + } + } + return Calendar.stopEvent(ev); +}; + +Calendar.dayMouseOut = function(ev) { + with (Calendar) { + var el = getElement(ev); + if (isRelated(el, ev) || _C || el.disabled) { + return false; + } + removeClass(el, "hilite"); + if (el.caldate) { + removeClass(el.parentNode, "rowhilite"); + } + el.calendar.tooltips.firstChild.data = _TT["SEL_DATE"]; + return stopEvent(ev); + } +}; + +/** + * A generic "click" handler :) handles all types of buttons defined in this + * calendar. + */ +Calendar.cellClick = function(el, ev) { + var cal = el.calendar; + var closing = false; + var newdate = false; + var date = null; + if (typeof el.navtype == "undefined") { + Calendar.removeClass(cal.currentDateEl, "selected"); + Calendar.addClass(el, "selected"); + closing = (cal.currentDateEl == el); + if (!closing) { + cal.currentDateEl = el; + } + cal.date = new Date(el.caldate); + date = cal.date; + newdate = true; + // a date was clicked + if (!(cal.dateClicked = !el.otherMonth)) + cal._init(cal.firstDayOfWeek, date); + } else { + if (el.navtype == 200) { + Calendar.removeClass(el, "hilite"); + cal.callCloseHandler(); + return; + } + date = (el.navtype == 0) ? new Date() : new Date(cal.date); + // unless "today" was clicked, we assume no date was clicked so + // the selected handler will know not to close the calenar when + // in single-click mode. + // cal.dateClicked = (el.navtype == 0); + cal.dateClicked = false; + var year = date.getFullYear(); + var mon = date.getMonth(); + function setMonth(m) { + var day = date.getDate(); + var max = date.getMonthDays(m); + if (day > max) { + date.setDate(max); + } + date.setMonth(m); + }; + switch (el.navtype) { + case 400: + Calendar.removeClass(el, "hilite"); + var text = Calendar._TT["ABOUT"]; + if (typeof text != "undefined") { + text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : ""; + } else { + // FIXME: this should be removed as soon as lang files get updated! + text = "Help and about box text is not translated into this language.\n" + + "If you know this language and you feel generous please update\n" + + "the corresponding file in \"lang\" subdir to match calendar-en.js\n" + + "and send it back to <mishoo@infoiasi.ro> to get it into the distribution ;-)\n\n" + + "Thank you!\n" + + "http://dynarch.com/mishoo/calendar.epl\n"; + } + alert(text); + return; + case -2: + if (year > cal.minYear) { + date.setFullYear(year - 1); + } + break; + case -1: + if (mon > 0) { + setMonth(mon - 1); + } else if (year-- > cal.minYear) { + date.setFullYear(year); + setMonth(11); + } + break; + case 1: + if (mon < 11) { + setMonth(mon + 1); + } else if (year < cal.maxYear) { + date.setFullYear(year + 1); + setMonth(0); + } + break; + case 2: + if (year < cal.maxYear) { + date.setFullYear(year + 1); + } + break; + case 100: + cal.setFirstDayOfWeek(el.fdow); + return; + case 50: + var range = el._range; + var current = el.firstChild.data; + for (var i = range.length; --i >= 0;) + if (range[i] == current) + break; + if (ev && ev.shiftKey) { + if (--i < 0) + i = range.length - 1; + } else if ( ++i >= range.length ) + i = 0; + var newval = range[i]; + el.firstChild.data = newval; + cal.onUpdateTime(); + return; + case 0: + // TODAY will bring us here + if ((typeof cal.getDateStatus == "function") && cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) { + // remember, "date" was previously set to new + // Date() if TODAY was clicked; thus, it + // contains today date. + return false; + } + break; + } + if (!date.equalsTo(cal.date)) { + cal.setDate(date); + newdate = true; + } + } + if (newdate) { + cal.callHandler(); + } + if (closing) { + Calendar.removeClass(el, "hilite"); + cal.callCloseHandler(); + } +}; + +// END: CALENDAR STATIC FUNCTIONS + +// BEGIN: CALENDAR OBJECT FUNCTIONS + +/** + * This function creates the calendar inside the given parent. If _par is + * null than it creates a popup calendar inside the BODY element. If _par is + * an element, be it BODY, then it creates a non-popup calendar (still + * hidden). Some properties need to be set before calling this function. + */ +Calendar.prototype.create = function (_par) { + var parent = null; + if (! _par) { + // default parent is the document body, in which case we create + // a popup calendar. + parent = document.getElementsByTagName("body")[0]; + this.isPopup = true; + } else { + parent = _par; + this.isPopup = false; + } + this.date = this.dateStr ? new Date(this.dateStr) : new Date(); + + var table = Calendar.createElement("table"); + this.table = table; + table.cellSpacing = 0; + table.cellPadding = 0; + table.calendar = this; + Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown); + + var div = Calendar.createElement("div"); + this.element = div; + div.className = "calendar"; + if (this.isPopup) { + div.style.position = "absolute"; + div.style.display = "none"; + } + div.appendChild(table); + + var thead = Calendar.createElement("thead", table); + var cell = null; + var row = null; + + var cal = this; + var hh = function (text, cs, navtype) { + cell = Calendar.createElement("td", row); + cell.colSpan = cs; + cell.className = "button"; + if (navtype != 0 && Math.abs(navtype) <= 2) + cell.className += " nav"; + Calendar._add_evs(cell); + cell.calendar = cal; + cell.navtype = navtype; + if (text.substr(0, 1) != "&") { + cell.appendChild(document.createTextNode(text)); + } + else { + // FIXME: dirty hack for entities + cell.innerHTML = text; + } + return cell; + }; + + row = Calendar.createElement("tr", thead); + var title_length = 6; + (this.isPopup) && --title_length; + (this.weekNumbers) && ++title_length; + + hh("?", 1, 400).ttip = Calendar._TT["INFO"]; + this.title = hh("", title_length, 300); + this.title.className = "title"; + if (this.isPopup) { + this.title.ttip = Calendar._TT["DRAG_TO_MOVE"]; + this.title.style.cursor = "move"; + hh("×", 1, 200).ttip = Calendar._TT["CLOSE"]; + } + + row = Calendar.createElement("tr", thead); + row.className = "headrow"; + + this._nav_py = hh("«", 1, -2); + this._nav_py.ttip = Calendar._TT["PREV_YEAR"]; + + this._nav_pm = hh("‹", 1, -1); + this._nav_pm.ttip = Calendar._TT["PREV_MONTH"]; + + this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 4 : 3, 0); + this._nav_now.ttip = Calendar._TT["GO_TODAY"]; + + this._nav_nm = hh("›", 1, 1); + this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"]; + + this._nav_ny = hh("»", 1, 2); + this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"]; + + // day names + row = Calendar.createElement("tr", thead); + row.className = "daynames"; + if (this.weekNumbers) { + cell = Calendar.createElement("td", row); + cell.className = "name wn"; + cell.appendChild(document.createTextNode(Calendar._TT["WK"])); + } + for (var i = 7; i > 0; --i) { + cell = Calendar.createElement("td", row); + cell.appendChild(document.createTextNode("")); + if (!i) { + cell.navtype = 100; + cell.calendar = this; + Calendar._add_evs(cell); + } + } + this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild; + this._displayWeekdays(); + + var tbody = Calendar.createElement("tbody", table); + this.tbody = tbody; + + for (i = 6; i > 0; --i) { + row = Calendar.createElement("tr", tbody); + if (this.weekNumbers) { + cell = Calendar.createElement("td", row); + cell.appendChild(document.createTextNode("")); + } + for (var j = 7; j > 0; --j) { + cell = Calendar.createElement("td", row); + cell.appendChild(document.createTextNode("")); + cell.calendar = this; + Calendar._add_evs(cell); + } + } + + if (this.showsTime) { + row = Calendar.createElement("tr", tbody); + row.className = "time"; + + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = 2; + cell.innerHTML = Calendar._TT["TIME"] || " "; + + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = this.weekNumbers ? 4 : 3; + + (function(){ + function makeTimePart(className, init, range_start, range_end) { + var part = Calendar.createElement("span", cell); + part.className = className; + part.appendChild(document.createTextNode(init)); + part.calendar = cal; + part.ttip = Calendar._TT["TIME_PART"]; + part.navtype = 50; + part._range = []; + if (typeof range_start != "number") + part._range = range_start; + else { + for (var i = range_start; i <= range_end; ++i) { + var txt; + if (i < 10 && range_end >= 10) txt = '0' + i; + else txt = '' + i; + part._range[part._range.length] = txt; + } + } + Calendar._add_evs(part); + return part; + }; + var hrs = cal.date.getHours(); + var mins = cal.date.getMinutes(); + var t12 = !cal.time24; + var pm = (hrs > 12); + if (t12 && pm) hrs -= 12; + var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23); + var span = Calendar.createElement("span", cell); + span.appendChild(document.createTextNode(":")); + span.className = "colon"; + var M = makeTimePart("minute", mins, 0, 59); + var AP = null; + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = 2; + if (t12) + AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]); + else + cell.innerHTML = " "; + + cal.onSetTime = function() { + var hrs = this.date.getHours(); + var mins = this.date.getMinutes(); + var pm = (hrs > 12); + if (pm && t12) hrs -= 12; + H.firstChild.data = (hrs < 10) ? ("0" + hrs) : hrs; + M.firstChild.data = (mins < 10) ? ("0" + mins) : mins; + if (t12) + AP.firstChild.data = pm ? "pm" : "am"; + }; + + cal.onUpdateTime = function() { + var date = this.date; + var h = parseInt(H.firstChild.data, 10); + if (t12) { + if (/pm/i.test(AP.firstChild.data) && h < 12) + h += 12; + else if (/am/i.test(AP.firstChild.data) && h == 12) + h = 0; + } + var d = date.getDate(); + var m = date.getMonth(); + var y = date.getFullYear(); + date.setHours(h); + date.setMinutes(parseInt(M.firstChild.data, 10)); + date.setFullYear(y); + date.setMonth(m); + date.setDate(d); + this.dateClicked = false; + this.callHandler(); + }; + })(); + } else { + this.onSetTime = this.onUpdateTime = function() {}; + } + + var tfoot = Calendar.createElement("tfoot", table); + + row = Calendar.createElement("tr", tfoot); + row.className = "footrow"; + + cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300); + cell.className = "ttip"; + if (this.isPopup) { + cell.ttip = Calendar._TT["DRAG_TO_MOVE"]; + cell.style.cursor = "move"; + } + this.tooltips = cell; + + div = Calendar.createElement("div", this.element); + this.monthsCombo = div; + div.className = "combo"; + for (i = 0; i < Calendar._MN.length; ++i) { + var mn = Calendar.createElement("div"); + mn.className = Calendar.is_ie ? "label-IEfix" : "label"; + mn.month = i; + mn.appendChild(document.createTextNode(Calendar._SMN[i])); + div.appendChild(mn); + } + + div = Calendar.createElement("div", this.element); + this.yearsCombo = div; + div.className = "combo"; + for (i = 12; i > 0; --i) { + var yr = Calendar.createElement("div"); + yr.className = Calendar.is_ie ? "label-IEfix" : "label"; + yr.appendChild(document.createTextNode("")); + div.appendChild(yr); + } + + this._init(this.firstDayOfWeek, this.date); + parent.appendChild(this.element); +}; + +/** keyboard navigation, only for popup calendars */ +Calendar._keyEvent = function(ev) { + if (!window.calendar) { + return false; + } + (Calendar.is_ie) && (ev = window.event); + var cal = window.calendar; + var act = (Calendar.is_ie || ev.type == "keypress"); + if (ev.ctrlKey) { + switch (ev.keyCode) { + case 37: // KEY left + act && Calendar.cellClick(cal._nav_pm); + break; + case 38: // KEY up + act && Calendar.cellClick(cal._nav_py); + break; + case 39: // KEY right + act && Calendar.cellClick(cal._nav_nm); + break; + case 40: // KEY down + act && Calendar.cellClick(cal._nav_ny); + break; + default: + return false; + } + } else switch (ev.keyCode) { + case 32: // KEY space (now) + Calendar.cellClick(cal._nav_now); + break; + case 27: // KEY esc + act && cal.callCloseHandler(); + break; + case 37: // KEY left + case 38: // KEY up + case 39: // KEY right + case 40: // KEY down + if (act) { + var date = cal.date.getDate() - 1; + var el = cal.currentDateEl; + var ne = null; + var prev = (ev.keyCode == 37) || (ev.keyCode == 38); + switch (ev.keyCode) { + case 37: // KEY left + (--date >= 0) && (ne = cal.ar_days[date]); + break; + case 38: // KEY up + date -= 7; + (date >= 0) && (ne = cal.ar_days[date]); + break; + case 39: // KEY right + (++date < cal.ar_days.length) && (ne = cal.ar_days[date]); + break; + case 40: // KEY down + date += 7; + (date < cal.ar_days.length) && (ne = cal.ar_days[date]); + break; + } + if (!ne) { + if (prev) { + Calendar.cellClick(cal._nav_pm); + } else { + Calendar.cellClick(cal._nav_nm); + } + date = (prev) ? cal.date.getMonthDays() : 1; + el = cal.currentDateEl; + ne = cal.ar_days[date - 1]; + } + Calendar.removeClass(el, "selected"); + Calendar.addClass(ne, "selected"); + cal.date = new Date(ne.caldate); + cal.callHandler(); + cal.currentDateEl = ne; + } + break; + case 13: // KEY enter + if (act) { + cal.callHandler(); + cal.hide(); + } + break; + default: + return false; + } + return Calendar.stopEvent(ev); +}; + +/** + * (RE)Initializes the calendar to the given date and firstDayOfWeek + */ +Calendar.prototype._init = function (firstDayOfWeek, date) { + var today = new Date(); + this.table.style.visibility = "hidden"; + var year = date.getFullYear(); + if (year < this.minYear) { + year = this.minYear; + date.setFullYear(year); + } else if (year > this.maxYear) { + year = this.maxYear; + date.setFullYear(year); + } + this.firstDayOfWeek = firstDayOfWeek; + this.date = new Date(date); + var month = date.getMonth(); + var mday = date.getDate(); + var no_days = date.getMonthDays(); + + // calendar voodoo for computing the first day that would actually be + // displayed in the calendar, even if it's from the previous month. + // WARNING: this is magic. ;-) + date.setDate(1); + var day1 = (date.getDay() - this.firstDayOfWeek) % 7; + if (day1 < 0) + day1 += 7; + date.setDate(-day1); + date.setDate(date.getDate() + 1); + + var row = this.tbody.firstChild; + var MN = Calendar._SMN[month]; + var ar_days = new Array(); + var weekend = Calendar._TT["WEEKEND"]; + for (var i = 0; i < 6; ++i, row = row.nextSibling) { + var cell = row.firstChild; + if (this.weekNumbers) { + cell.className = "day wn"; + cell.firstChild.data = date.getWeekNumber(); + cell = cell.nextSibling; + } + row.className = "daysrow"; + var hasdays = false; + for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(date.getDate() + 1)) { + var iday = date.getDate(); + var wday = date.getDay(); + cell.className = "day"; + var current_month = (date.getMonth() == month); + if (!current_month) { + if (this.showsOtherMonths) { + cell.className += " othermonth"; + cell.otherMonth = true; + } else { + cell.className = "emptycell"; + cell.innerHTML = " "; + cell.disabled = true; + continue; + } + } else { + cell.otherMonth = false; + hasdays = true; + } + cell.disabled = false; + cell.firstChild.data = iday; + if (typeof this.getDateStatus == "function") { + var status = this.getDateStatus(date, year, month, iday); + if (status === true) { + cell.className += " disabled"; + cell.disabled = true; + } else { + if (/disabled/i.test(status)) + cell.disabled = true; + cell.className += " " + status; + } + } + if (!cell.disabled) { + ar_days[ar_days.length] = cell; + cell.caldate = new Date(date); + cell.ttip = "_"; + if (current_month && iday == mday) { + cell.className += " selected"; + this.currentDateEl = cell; + } + if (date.getFullYear() == today.getFullYear() && + date.getMonth() == today.getMonth() && + iday == today.getDate()) { + cell.className += " today"; + cell.ttip += Calendar._TT["PART_TODAY"]; + } + if (weekend.indexOf(wday.toString()) != -1) { + cell.className += cell.otherMonth ? " oweekend" : " weekend"; + } + } + } + if (!(hasdays || this.showsOtherMonths)) + row.className = "emptyrow"; + } + this.ar_days = ar_days; + this.title.firstChild.data = Calendar._MN[month] + ", " + year; + this.onSetTime(); + this.table.style.visibility = "visible"; + // PROFILE + // this.tooltips.firstChild.data = "Generated in " + ((new Date()) - today) + " ms"; +}; + +/** + * Calls _init function above for going to a certain date (but only if the + * date is different than the currently selected one). + */ +Calendar.prototype.setDate = function (date) { + if (!date.equalsTo(this.date)) { + this._init(this.firstDayOfWeek, date); + } +}; + +/** + * Refreshes the calendar. Useful if the "disabledHandler" function is + * dynamic, meaning that the list of disabled date can change at runtime. + * Just * call this function if you think that the list of disabled dates + * should * change. + */ +Calendar.prototype.refresh = function () { + this._init(this.firstDayOfWeek, this.date); +}; + +/** Modifies the "firstDayOfWeek" parameter (pass 0 for Synday, 1 for Monday, etc.). */ +Calendar.prototype.setFirstDayOfWeek = function (firstDayOfWeek) { + this._init(firstDayOfWeek, this.date); + this._displayWeekdays(); +}; + +/** + * Allows customization of what dates are enabled. The "unaryFunction" + * parameter must be a function object that receives the date (as a JS Date + * object) and returns a boolean value. If the returned value is true then + * the passed date will be marked as disabled. + */ +Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) { + this.getDateStatus = unaryFunction; +}; + +/** Customization of allowed year range for the calendar. */ +Calendar.prototype.setRange = function (a, z) { + this.minYear = a; + this.maxYear = z; +}; + +/** Calls the first user handler (selectedHandler). */ +Calendar.prototype.callHandler = function () { + if (this.onSelected) { + this.onSelected(this, this.date.print(this.dateFormat)); + } +}; + +/** Calls the second user handler (closeHandler). */ +Calendar.prototype.callCloseHandler = function () { + if (this.onClose) { + this.onClose(this); + } + this.hideShowCovered(); +}; + +/** Removes the calendar object from the DOM tree and destroys it. */ +Calendar.prototype.destroy = function () { + var el = this.element.parentNode; + el.removeChild(this.element); + Calendar._C = null; + window.calendar = null; +}; + +/** + * Moves the calendar element to a different section in the DOM tree (changes + * its parent). + */ +Calendar.prototype.reparent = function (new_parent) { + var el = this.element; + el.parentNode.removeChild(el); + new_parent.appendChild(el); +}; + +// This gets called when the user presses a mouse button anywhere in the +// document, if the calendar is shown. If the click was outside the open +// calendar this function closes it. +Calendar._checkCalendar = function(ev) { + if (!window.calendar) { + return false; + } + var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev); + for (; el != null && el != calendar.element; el = el.parentNode); + if (el == null) { + // calls closeHandler which should hide the calendar. + window.calendar.callCloseHandler(); + return Calendar.stopEvent(ev); + } +}; + +/** Shows the calendar. */ +Calendar.prototype.show = function () { + var rows = this.table.getElementsByTagName("tr"); + for (var i = rows.length; i > 0;) { + var row = rows[--i]; + Calendar.removeClass(row, "rowhilite"); + var cells = row.getElementsByTagName("td"); + for (var j = cells.length; j > 0;) { + var cell = cells[--j]; + Calendar.removeClass(cell, "hilite"); + Calendar.removeClass(cell, "active"); + } + } + this.element.style.display = "block"; + this.hidden = false; + if (this.isPopup) { + window.calendar = this; + Calendar.addEvent(document, "keydown", Calendar._keyEvent); + Calendar.addEvent(document, "keypress", Calendar._keyEvent); + Calendar.addEvent(document, "mousedown", Calendar._checkCalendar); + } + this.hideShowCovered(); +}; + +/** + * Hides the calendar. Also removes any "hilite" from the class of any TD + * element. + */ +Calendar.prototype.hide = function () { + if (this.isPopup) { + Calendar.removeEvent(document, "keydown", Calendar._keyEvent); + Calendar.removeEvent(document, "keypress", Calendar._keyEvent); + Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar); + } + this.element.style.display = "none"; + this.hidden = true; + this.hideShowCovered(); +}; + +/** + * Shows the calendar at a given absolute position (beware that, depending on + * the calendar element style -- position property -- this might be relative + * to the parent's containing rectangle). + */ +Calendar.prototype.showAt = function (x, y) { + var s = this.element.style; + s.left = x + "px"; + s.top = y + "px"; + this.show(); +}; + +/** Shows the calendar near a given element. */ +Calendar.prototype.showAtElement = function (el, opts) { + var self = this; + var p = Calendar.getAbsolutePos(el); + if (!opts || typeof opts != "string") { + this.showAt(p.x, p.y + el.offsetHeight); + return true; + } + function fixPosition(box) { + if (box.x < 0) + box.x = 0; + if (box.y < 0) + box.y = 0; + var cp = document.createElement("div"); + var s = cp.style; + s.position = "absolute"; + s.right = s.bottom = s.width = s.height = "0px"; + document.body.appendChild(cp); + var br = Calendar.getAbsolutePos(cp); + document.body.removeChild(cp); + if (Calendar.is_ie) { + br.y += document.body.scrollTop; + br.x += document.body.scrollLeft; + } else { + br.y += window.scrollY; + br.x += window.scrollX; + } + var tmp = box.x + box.width - br.x; + if (tmp > 0) box.x -= tmp; + tmp = box.y + box.height - br.y; + if (tmp > 0) box.y -= tmp; + }; + this.element.style.display = "block"; + Calendar.continuation_for_the_fucking_khtml_browser = function() { + var w = self.element.offsetWidth; + var h = self.element.offsetHeight; + self.element.style.display = "none"; + var valign = opts.substr(0, 1); + var halign = "l"; + if (opts.length > 1) { + halign = opts.substr(1, 1); + } + // vertical alignment + switch (valign) { + case "T": p.y -= h; break; + case "B": p.y += el.offsetHeight; break; + case "C": p.y += (el.offsetHeight - h) / 2; break; + case "t": p.y += el.offsetHeight - h; break; + case "b": break; // already there + } + // horizontal alignment + switch (halign) { + case "L": p.x -= w; break; + case "R": p.x += el.offsetWidth; break; + case "C": p.x += (el.offsetWidth - w) / 2; break; + case "r": p.x += el.offsetWidth - w; break; + case "l": break; // already there + } + p.width = w; + p.height = h + 40; + self.monthsCombo.style.display = "none"; + fixPosition(p); + self.showAt(p.x, p.y); + }; + if (Calendar.is_khtml) + setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10); + else + Calendar.continuation_for_the_fucking_khtml_browser(); +}; + +/** Customizes the date format. */ +Calendar.prototype.setDateFormat = function (str) { + this.dateFormat = str; +}; + +/** Customizes the tooltip date format. */ +Calendar.prototype.setTtDateFormat = function (str) { + this.ttDateFormat = str; +}; + +/** + * Tries to identify the date represented in a string. If successful it also + * calls this.setDate which moves the calendar to the given date. + */ +Calendar.prototype.parseDate = function (str, fmt) { + var y = 0; + var m = -1; + var d = 0; + var a = str.split(/\W+/); + if (!fmt) { + fmt = this.dateFormat; + } + var b = fmt.match(/%./g); + var i = 0, j = 0; + var hr = 0; + var min = 0; + for (i = 0; i < a.length; ++i) { + if (!a[i]) + continue; + switch (b[i]) { + case "%d": + case "%e": + d = parseInt(a[i], 10); + break; + + case "%m": + m = parseInt(a[i], 10) - 1; + break; + + case "%Y": + case "%y": + y = parseInt(a[i], 10); + (y < 100) && (y += (y > 29) ? 1900 : 2000); + break; + + case "%b": + case "%B": + for (j = 0; j < 12; ++j) { + if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; } + } + break; + + case "%H": + case "%I": + case "%k": + case "%l": + hr = parseInt(a[i], 10); + break; + + case "%P": + case "%p": + if (/pm/i.test(a[i]) && hr < 12) + hr += 12; + break; + + case "%M": + min = parseInt(a[i], 10); + break; + } + } + if (y != 0 && m != -1 && d != 0) { + this.setDate(new Date(y, m, d, hr, min, 0)); + return; + } + y = 0; m = -1; d = 0; + for (i = 0; i < a.length; ++i) { + if (a[i].search(/[a-zA-Z]+/) != -1) { + var t = -1; + for (j = 0; j < 12; ++j) { + if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; } + } + if (t != -1) { + if (m != -1) { + d = m+1; + } + m = t; + } + } else if (parseInt(a[i], 10) <= 12 && m == -1) { + m = a[i]-1; + } else if (parseInt(a[i], 10) > 31 && y == 0) { + y = parseInt(a[i], 10); + (y < 100) && (y += (y > 29) ? 1900 : 2000); + } else if (d == 0) { + d = a[i]; + } + } + if (y == 0) { + var today = new Date(); + y = today.getFullYear(); + } + if (m != -1 && d != 0) { + this.setDate(new Date(y, m, d, hr, min, 0)); + } +}; + +Calendar.prototype.hideShowCovered = function () { + var self = this; + Calendar.continuation_for_the_fucking_khtml_browser = function() { + function getVisib(obj){ + var value = obj.style.visibility; + if (!value) { + if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C + if (!Calendar.is_khtml) + value = document.defaultView. + getComputedStyle(obj, "").getPropertyValue("visibility"); + else + value = ''; + } else if (obj.currentStyle) { // IE + value = obj.currentStyle.visibility; + } else + value = ''; + } + return value; + }; + + var tags = new Array("applet", "iframe", "select"); + var el = self.element; + + var p = Calendar.getAbsolutePos(el); + var EX1 = p.x; + var EX2 = el.offsetWidth + EX1; + var EY1 = p.y; + var EY2 = el.offsetHeight + EY1; + + for (var k = tags.length; k > 0; ) { + var ar = document.getElementsByTagName(tags[--k]); + var cc = null; + + for (var i = ar.length; i > 0;) { + cc = ar[--i]; + + p = Calendar.getAbsolutePos(cc); + var CX1 = p.x; + var CX2 = cc.offsetWidth + CX1; + var CY1 = p.y; + var CY2 = cc.offsetHeight + CY1; + + if (self.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) { + if (!cc.__msh_save_visibility) { + cc.__msh_save_visibility = getVisib(cc); + } + cc.style.visibility = cc.__msh_save_visibility; + } else { + if (!cc.__msh_save_visibility) { + cc.__msh_save_visibility = getVisib(cc); + } + cc.style.visibility = "hidden"; + } + } + } + }; + if (Calendar.is_khtml) + setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10); + else + Calendar.continuation_for_the_fucking_khtml_browser(); +}; + +/** Internal function; it displays the bar with the names of the weekday. */ +Calendar.prototype._displayWeekdays = function () { + var fdow = this.firstDayOfWeek; + var cell = this.firstdayname; + var weekend = Calendar._TT["WEEKEND"]; + for (var i = 0; i < 7; ++i) { + cell.className = "day name"; + var realday = (i + fdow) % 7; + if (i) { + cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]); + cell.navtype = 100; + cell.calendar = this; + cell.fdow = realday; + Calendar._add_evs(cell); + } + if (weekend.indexOf(realday.toString()) != -1) { + Calendar.addClass(cell, "weekend"); + } + cell.firstChild.data = Calendar._SDN[(i + fdow) % 7]; + cell = cell.nextSibling; + } +}; + +/** Internal function. Hides all combo boxes that might be displayed. */ +Calendar.prototype._hideCombos = function () { + this.monthsCombo.style.display = "none"; + this.yearsCombo.style.display = "none"; +}; + +/** Internal function. Starts dragging the element. */ +Calendar.prototype._dragStart = function (ev) { + if (this.dragging) { + return; + } + this.dragging = true; + var posX; + var posY; + if (Calendar.is_ie) { + posY = window.event.clientY + document.body.scrollTop; + posX = window.event.clientX + document.body.scrollLeft; + } else { + posY = ev.clientY + window.scrollY; + posX = ev.clientX + window.scrollX; + } + var st = this.element.style; + this.xOffs = posX - parseInt(st.left); + this.yOffs = posY - parseInt(st.top); + with (Calendar) { + addEvent(document, "mousemove", calDragIt); + addEvent(document, "mouseup", calDragEnd); + } +}; + +// BEGIN: DATE OBJECT PATCHES + +/** Adds the number of days array to the Date object. */ +Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31); + +/** Constants used for time computations */ +Date.SECOND = 1000 /* milliseconds */; +Date.MINUTE = 60 * Date.SECOND; +Date.HOUR = 60 * Date.MINUTE; +Date.DAY = 24 * Date.HOUR; +Date.WEEK = 7 * Date.DAY; + +/** Returns the number of days in the current month */ +Date.prototype.getMonthDays = function(month) { + var year = this.getFullYear(); + if (typeof month == "undefined") { + month = this.getMonth(); + } + if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) { + return 29; + } else { + return Date._MD[month]; + } +}; + +/** Returns the number of day in the year. */ +Date.prototype.getDayOfYear = function() { + var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0); + var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0); + var time = now - then; + return Math.floor(time / Date.DAY); +}; + +/** Returns the number of the week in year, as defined in ISO 8601. */ +Date.prototype.getWeekNumber = function() { + var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0); + var DoW = d.getDay(); + d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu + var ms = d.valueOf(); // GMT + d.setMonth(0); + d.setDate(4); // Thu in Week 1 + return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1; +}; + +/** Checks dates equality (ignores time) */ +Date.prototype.equalsTo = function(date) { + return ((this.getFullYear() == date.getFullYear()) && + (this.getMonth() == date.getMonth()) && + (this.getDate() == date.getDate()) && + (this.getHours() == date.getHours()) && + (this.getMinutes() == date.getMinutes())); +}; + +/** Prints the date in a string according to the given format. */ +Date.prototype.print = function (str) { + var m = this.getMonth(); + var d = this.getDate(); + var y = this.getFullYear(); + var wn = this.getWeekNumber(); + var w = this.getDay(); + var s = {}; + var hr = this.getHours(); + var pm = (hr >= 12); + var ir = (pm) ? (hr - 12) : hr; + var dy = this.getDayOfYear(); + if (ir == 0) + ir = 12; + var min = this.getMinutes(); + var sec = this.getSeconds(); + s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N] + s["%A"] = Calendar._DN[w]; // full weekday name + s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N] + s["%B"] = Calendar._MN[m]; // full month name + // FIXME: %c : preferred date and time representation for the current locale + s["%C"] = 1 + Math.floor(y / 100); // the century number + s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31) + s["%e"] = d; // the day of the month (range 1 to 31) + // FIXME: %D : american date style: %m/%d/%y + // FIXME: %E, %F, %G, %g, %h (man strftime) + s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format) + s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format) + s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366) + s["%k"] = hr; // hour, range 0 to 23 (24h format) + s["%l"] = ir; // hour, range 1 to 12 (12h format) + s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12 + s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59 + s["%n"] = "\n"; // a newline character + s["%p"] = pm ? "PM" : "AM"; + s["%P"] = pm ? "pm" : "am"; + // FIXME: %r : the time in am/pm notation %I:%M:%S %p + // FIXME: %R : the time in 24-hour notation %H:%M + s["%s"] = Math.floor(this.getTime() / 1000); + s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59 + s["%t"] = "\t"; // a tab character + // FIXME: %T : the time in 24-hour notation (%H:%M:%S) + s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn; + s["%u"] = w + 1; // the day of the week (range 1 to 7, 1 = MON) + s["%w"] = w; // the day of the week (range 0 to 6, 0 = SUN) + // FIXME: %x : preferred date representation for the current locale without the time + // FIXME: %X : preferred time representation for the current locale without the date + s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99) + s["%Y"] = y; // year with the century + s["%%"] = "%"; // a literal '%' character + + var re = /%./g; + if (!Calendar.is_ie5) + return str.replace(re, function (par) { return s[par] || par; }); + + var a = str.match(re); + for (var i = 0; i < a.length; i++) { + var tmp = s[a[i]]; + if (tmp) { + re = new RegExp(a[i], 'g'); + str = str.replace(re, tmp); + } + } + + return str; +}; + +Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear; +Date.prototype.setFullYear = function(y) { + var d = new Date(this); + d.__msh_oldSetFullYear(y); + if (d.getMonth() != this.getMonth()) + this.setDate(28); + this.__msh_oldSetFullYear(y); +}; + +// END: DATE OBJECT PATCHES + + +// global object that remembers the calendar +window.calendar = null; diff --git a/httemplate/elements/calendar_stripped.js b/httemplate/elements/calendar_stripped.js new file mode 100644 index 000000000..6a8e326af --- /dev/null +++ b/httemplate/elements/calendar_stripped.js @@ -0,0 +1,12 @@ +/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/ + * ------------------------------------------------------------------ + * + * The DHTML Calendar, version 0.9.6 "Keep cool but don't freeze" + * + * Details and latest version at: + * http://dynarch.com/mishoo/calendar.epl + * + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html + */ + Calendar=function(firstDayOfWeek,dateStr,onSelected,onClose){this.activeDiv=null;this.currentDateEl=null;this.getDateStatus=null;this.timeout=null;this.onSelected=onSelected||null;this.onClose=onClose||null;this.dragging=false;this.hidden=false;this.minYear=1970;this.maxYear=2050;this.dateFormat=Calendar._TT["DEF_DATE_FORMAT"];this.ttDateFormat=Calendar._TT["TT_DATE_FORMAT"];this.isPopup=true;this.weekNumbers=true;this.firstDayOfWeek=firstDayOfWeek;this.showsOtherMonths=false;this.dateStr=dateStr;this.ar_days=null;this.showsTime=false;this.time24=true;this.yearStep=2;this.table=null;this.element=null;this.tbody=null;this.firstdayname=null;this.monthsCombo=null;this.yearsCombo=null;this.hilitedMonth=null;this.activeMonth=null;this.hilitedYear=null;this.activeYear=null;this.dateClicked=false;if(typeof Calendar._SDN=="undefined"){if(typeof Calendar._SDN_len=="undefined")Calendar._SDN_len=3;var ar=new Array();for(var i=8;i>0;){ar[--i]=Calendar._DN[i].substr(0,Calendar._SDN_len);}Calendar._SDN=ar;if(typeof Calendar._SMN_len=="undefined")Calendar._SMN_len=3;ar=new Array();for(var i=12;i>0;){ar[--i]=Calendar._MN[i].substr(0,Calendar._SMN_len);}Calendar._SMN=ar;}};Calendar._C=null;Calendar.is_ie=(/msie/i.test(navigator.userAgent)&&!/opera/i.test(navigator.userAgent));Calendar.is_ie5=(Calendar.is_ie&&/msie 5\.0/i.test(navigator.userAgent));Calendar.is_opera=/opera/i.test(navigator.userAgent);Calendar.is_khtml=/Konqueror|Safari|KHTML/i.test(navigator.userAgent);Calendar.getAbsolutePos=function(el){var SL=0,ST=0;var is_div=/^div$/i.test(el.tagName);if(is_div&&el.scrollLeft)SL=el.scrollLeft;if(is_div&&el.scrollTop)ST=el.scrollTop;var r={x:el.offsetLeft-SL,y:el.offsetTop-ST};if(el.offsetParent){var tmp=this.getAbsolutePos(el.offsetParent);r.x+=tmp.x;r.y+=tmp.y;}return r;};Calendar.isRelated=function(el,evt){var related=evt.relatedTarget;if(!related){var type=evt.type;if(type=="mouseover"){related=evt.fromElement;}else if(type=="mouseout"){related=evt.toElement;}}while(related){if(related==el){return true;}related=related.parentNode;}return false;};Calendar.removeClass=function(el,className){if(!(el&&el.className)){return;}var cls=el.className.split(" ");var ar=new Array();for(var i=cls.length;i>0;){if(cls[--i]!=className){ar[ar.length]=cls[i];}}el.className=ar.join(" ");};Calendar.addClass=function(el,className){Calendar.removeClass(el,className);el.className+=" "+className;};Calendar.getElement=function(ev){if(Calendar.is_ie){return window.event.srcElement;}else{return ev.currentTarget;}};Calendar.getTargetElement=function(ev){if(Calendar.is_ie){return window.event.srcElement;}else{return ev.target;}};Calendar.stopEvent=function(ev){ev||(ev=window.event);if(Calendar.is_ie){ev.cancelBubble=true;ev.returnValue=false;}else{ev.preventDefault();ev.stopPropagation();}return false;};Calendar.addEvent=function(el,evname,func){if(el.attachEvent){el.attachEvent("on"+evname,func);}else if(el.addEventListener){el.addEventListener(evname,func,true);}else{el["on"+evname]=func;}};Calendar.removeEvent=function(el,evname,func){if(el.detachEvent){el.detachEvent("on"+evname,func);}else if(el.removeEventListener){el.removeEventListener(evname,func,true);}else{el["on"+evname]=null;}};Calendar.createElement=function(type,parent){var el=null;if(document.createElementNS){el=document.createElementNS("http://www.w3.org/1999/xhtml",type);}else{el=document.createElement(type);}if(typeof parent!="undefined"){parent.appendChild(el);}return el;};Calendar._add_evs=function(el){with(Calendar){addEvent(el,"mouseover",dayMouseOver);addEvent(el,"mousedown",dayMouseDown);addEvent(el,"mouseout",dayMouseOut);if(is_ie){addEvent(el,"dblclick",dayMouseDblClick);el.setAttribute("unselectable",true);}}};Calendar.findMonth=function(el){if(typeof el.month!="undefined"){return el;}else if(typeof el.parentNode.month!="undefined"){return el.parentNode;}return null;};Calendar.findYear=function(el){if(typeof el.year!="undefined"){return el;}else if(typeof el.parentNode.year!="undefined"){return el.parentNode;}return null;};Calendar.showMonthsCombo=function(){var cal=Calendar._C;if(!cal){return false;}var cal=cal;var cd=cal.activeDiv;var mc=cal.monthsCombo;if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}if(cal.activeMonth){Calendar.removeClass(cal.activeMonth,"active");}var mon=cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];Calendar.addClass(mon,"active");cal.activeMonth=mon;var s=mc.style;s.display="block";if(cd.navtype<0)s.left=cd.offsetLeft+"px";else{var mcw=mc.offsetWidth;if(typeof mcw=="undefined")mcw=50;s.left=(cd.offsetLeft+cd.offsetWidth-mcw)+"px";}s.top=(cd.offsetTop+cd.offsetHeight)+"px";};Calendar.showYearsCombo=function(fwd){var cal=Calendar._C;if(!cal){return false;}var cal=cal;var cd=cal.activeDiv;var yc=cal.yearsCombo;if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}if(cal.activeYear){Calendar.removeClass(cal.activeYear,"active");}cal.activeYear=null;var Y=cal.date.getFullYear()+(fwd?1:-1);var yr=yc.firstChild;var show=false;for(var i=12;i>0;--i){if(Y>=cal.minYear&&Y<=cal.maxYear){yr.firstChild.data=Y;yr.year=Y;yr.style.display="block";show=true;}else{yr.style.display="none";}yr=yr.nextSibling;Y+=fwd?cal.yearStep:-cal.yearStep;}if(show){var s=yc.style;s.display="block";if(cd.navtype<0)s.left=cd.offsetLeft+"px";else{var ycw=yc.offsetWidth;if(typeof ycw=="undefined")ycw=50;s.left=(cd.offsetLeft+cd.offsetWidth-ycw)+"px";}s.top=(cd.offsetTop+cd.offsetHeight)+"px";}};Calendar.tableMouseUp=function(ev){var cal=Calendar._C;if(!cal){return false;}if(cal.timeout){clearTimeout(cal.timeout);}var el=cal.activeDiv;if(!el){return false;}var target=Calendar.getTargetElement(ev);ev||(ev=window.event);Calendar.removeClass(el,"active");if(target==el||target.parentNode==el){Calendar.cellClick(el,ev);}var mon=Calendar.findMonth(target);var date=null;if(mon){date=new Date(cal.date);if(mon.month!=date.getMonth()){date.setMonth(mon.month);cal.setDate(date);cal.dateClicked=false;cal.callHandler();}}else{var year=Calendar.findYear(target);if(year){date=new Date(cal.date);if(year.year!=date.getFullYear()){date.setFullYear(year.year);cal.setDate(date);cal.dateClicked=false;cal.callHandler();}}}with(Calendar){removeEvent(document,"mouseup",tableMouseUp);removeEvent(document,"mouseover",tableMouseOver);removeEvent(document,"mousemove",tableMouseOver);cal._hideCombos();_C=null;return stopEvent(ev);}};Calendar.tableMouseOver=function(ev){var cal=Calendar._C;if(!cal){return;}var el=cal.activeDiv;var target=Calendar.getTargetElement(ev);if(target==el||target.parentNode==el){Calendar.addClass(el,"hilite active");Calendar.addClass(el.parentNode,"rowhilite");}else{if(typeof el.navtype=="undefined"||(el.navtype!=50&&(el.navtype==0||Math.abs(el.navtype)>2)))Calendar.removeClass(el,"active");Calendar.removeClass(el,"hilite");Calendar.removeClass(el.parentNode,"rowhilite");}ev||(ev=window.event);if(el.navtype==50&&target!=el){var pos=Calendar.getAbsolutePos(el);var w=el.offsetWidth;var x=ev.clientX;var dx;var decrease=true;if(x>pos.x+w){dx=x-pos.x-w;decrease=false;}else dx=pos.x-x;if(dx<0)dx=0;var range=el._range;var current=el._current;var count=Math.floor(dx/10)%range.length;for(var i=range.length;--i>=0;)if(range[i]==current)break;while(count-->0)if(decrease){if(--i<0)i=range.length-1;}else if(++i>=range.length)i=0;var newval=range[i];el.firstChild.data=newval;cal.onUpdateTime();}var mon=Calendar.findMonth(target);if(mon){if(mon.month!=cal.date.getMonth()){if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}Calendar.addClass(mon,"hilite");cal.hilitedMonth=mon;}else if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}}else{if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}var year=Calendar.findYear(target);if(year){if(year.year!=cal.date.getFullYear()){if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}Calendar.addClass(year,"hilite");cal.hilitedYear=year;}else if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}}else if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}}return Calendar.stopEvent(ev);};Calendar.tableMouseDown=function(ev){if(Calendar.getTargetElement(ev)==Calendar.getElement(ev)){return Calendar.stopEvent(ev);}};Calendar.calDragIt=function(ev){var cal=Calendar._C;if(!(cal&&cal.dragging)){return false;}var posX;var posY;if(Calendar.is_ie){posY=window.event.clientY+document.body.scrollTop;posX=window.event.clientX+document.body.scrollLeft;}else{posX=ev.pageX;posY=ev.pageY;}cal.hideShowCovered();var st=cal.element.style;st.left=(posX-cal.xOffs)+"px";st.top=(posY-cal.yOffs)+"px";return Calendar.stopEvent(ev);};Calendar.calDragEnd=function(ev){var cal=Calendar._C;if(!cal){return false;}cal.dragging=false;with(Calendar){removeEvent(document,"mousemove",calDragIt);removeEvent(document,"mouseup",calDragEnd);tableMouseUp(ev);}cal.hideShowCovered();};Calendar.dayMouseDown=function(ev){var el=Calendar.getElement(ev);if(el.disabled){return false;}var cal=el.calendar;cal.activeDiv=el;Calendar._C=cal;if(el.navtype!=300)with(Calendar){if(el.navtype==50){el._current=el.firstChild.data;addEvent(document,"mousemove",tableMouseOver);}else addEvent(document,Calendar.is_ie5?"mousemove":"mouseover",tableMouseOver);addClass(el,"hilite active");addEvent(document,"mouseup",tableMouseUp);}else if(cal.isPopup){cal._dragStart(ev);}if(el.navtype==-1||el.navtype==1){if(cal.timeout)clearTimeout(cal.timeout);cal.timeout=setTimeout("Calendar.showMonthsCombo()",250);}else if(el.navtype==-2||el.navtype==2){if(cal.timeout)clearTimeout(cal.timeout);cal.timeout=setTimeout((el.navtype>0)?"Calendar.showYearsCombo(true)":"Calendar.showYearsCombo(false)",250);}else{cal.timeout=null;}return Calendar.stopEvent(ev);};Calendar.dayMouseDblClick=function(ev){Calendar.cellClick(Calendar.getElement(ev),ev||window.event);if(Calendar.is_ie){document.selection.empty();}};Calendar.dayMouseOver=function(ev){var el=Calendar.getElement(ev);if(Calendar.isRelated(el,ev)||Calendar._C||el.disabled){return false;}if(el.ttip){if(el.ttip.substr(0,1)=="_"){el.ttip=el.caldate.print(el.calendar.ttDateFormat)+el.ttip.substr(1);}el.calendar.tooltips.firstChild.data=el.ttip;}if(el.navtype!=300){Calendar.addClass(el,"hilite");if(el.caldate){Calendar.addClass(el.parentNode,"rowhilite");}}return Calendar.stopEvent(ev);};Calendar.dayMouseOut=function(ev){with(Calendar){var el=getElement(ev);if(isRelated(el,ev)||_C||el.disabled){return false;}removeClass(el,"hilite");if(el.caldate){removeClass(el.parentNode,"rowhilite");}el.calendar.tooltips.firstChild.data=_TT["SEL_DATE"];return stopEvent(ev);}};Calendar.cellClick=function(el,ev){var cal=el.calendar;var closing=false;var newdate=false;var date=null;if(typeof el.navtype=="undefined"){Calendar.removeClass(cal.currentDateEl,"selected");Calendar.addClass(el,"selected");closing=(cal.currentDateEl==el);if(!closing){cal.currentDateEl=el;}cal.date=new Date(el.caldate);date=cal.date;newdate=true;if(!(cal.dateClicked=!el.otherMonth))cal._init(cal.firstDayOfWeek,date);}else{if(el.navtype==200){Calendar.removeClass(el,"hilite");cal.callCloseHandler();return;}date=(el.navtype==0)?new Date():new Date(cal.date);cal.dateClicked=false;var year=date.getFullYear();var mon=date.getMonth();function setMonth(m){var day=date.getDate();var max=date.getMonthDays(m);if(day>max){date.setDate(max);}date.setMonth(m);};switch(el.navtype){case 400:Calendar.removeClass(el,"hilite");var text=Calendar._TT["ABOUT"];if(typeof text!="undefined"){text+=cal.showsTime?Calendar._TT["ABOUT_TIME"]:"";}else{text="Help and about box text is not translated into this language.\n"+"If you know this language and you feel generous please update\n"+"the corresponding file in \"lang\" subdir to match calendar-en.js\n"+"and send it back to <mishoo@infoiasi.ro> to get it into the distribution ;-)\n\n"+"Thank you!\n"+"http://dynarch.com/mishoo/calendar.epl\n";}alert(text);return;case-2:if(year>cal.minYear){date.setFullYear(year-1);}break;case-1:if(mon>0){setMonth(mon-1);}else if(year-->cal.minYear){date.setFullYear(year);setMonth(11);}break;case 1:if(mon<11){setMonth(mon+1);}else if(year<cal.maxYear){date.setFullYear(year+1);setMonth(0);}break;case 2:if(year<cal.maxYear){date.setFullYear(year+1);}break;case 100:cal.setFirstDayOfWeek(el.fdow);return;case 50:var range=el._range;var current=el.firstChild.data;for(var i=range.length;--i>=0;)if(range[i]==current)break;if(ev&&ev.shiftKey){if(--i<0)i=range.length-1;}else if(++i>=range.length)i=0;var newval=range[i];el.firstChild.data=newval;cal.onUpdateTime();return;case 0:if((typeof cal.getDateStatus=="function")&&cal.getDateStatus(date,date.getFullYear(),date.getMonth(),date.getDate())){return false;}break;}if(!date.equalsTo(cal.date)){cal.setDate(date);newdate=true;}}if(newdate){cal.callHandler();}if(closing){Calendar.removeClass(el,"hilite");cal.callCloseHandler();}};Calendar.prototype.create=function(_par){var parent=null;if(!_par){parent=document.getElementsByTagName("body")[0];this.isPopup=true;}else{parent=_par;this.isPopup=false;}this.date=this.dateStr?new Date(this.dateStr):new Date();var table=Calendar.createElement("table");this.table=table;table.cellSpacing=0;table.cellPadding=0;table.calendar=this;Calendar.addEvent(table,"mousedown",Calendar.tableMouseDown);var div=Calendar.createElement("div");this.element=div;div.className="calendar";if(this.isPopup){div.style.position="absolute";div.style.display="none";}div.appendChild(table);var thead=Calendar.createElement("thead",table);var cell=null;var row=null;var cal=this;var hh=function(text,cs,navtype){cell=Calendar.createElement("td",row);cell.colSpan=cs;cell.className="button";if(navtype!=0&&Math.abs(navtype)<=2)cell.className+=" nav";Calendar._add_evs(cell);cell.calendar=cal;cell.navtype=navtype;if(text.substr(0,1)!="&"){cell.appendChild(document.createTextNode(text));}else{cell.innerHTML=text;}return cell;};row=Calendar.createElement("tr",thead);var title_length=6;(this.isPopup)&&--title_length;(this.weekNumbers)&&++title_length;hh("?",1,400).ttip=Calendar._TT["INFO"];this.title=hh("",title_length,300);this.title.className="title";if(this.isPopup){this.title.ttip=Calendar._TT["DRAG_TO_MOVE"];this.title.style.cursor="move";hh("×",1,200).ttip=Calendar._TT["CLOSE"];}row=Calendar.createElement("tr",thead);row.className="headrow";this._nav_py=hh("«",1,-2);this._nav_py.ttip=Calendar._TT["PREV_YEAR"];this._nav_pm=hh("‹",1,-1);this._nav_pm.ttip=Calendar._TT["PREV_MONTH"];this._nav_now=hh(Calendar._TT["TODAY"],this.weekNumbers?4:3,0);this._nav_now.ttip=Calendar._TT["GO_TODAY"];this._nav_nm=hh("›",1,1);this._nav_nm.ttip=Calendar._TT["NEXT_MONTH"];this._nav_ny=hh("»",1,2);this._nav_ny.ttip=Calendar._TT["NEXT_YEAR"];row=Calendar.createElement("tr",thead);row.className="daynames";if(this.weekNumbers){cell=Calendar.createElement("td",row);cell.className="name wn";cell.appendChild(document.createTextNode(Calendar._TT["WK"]));}for(var i=7;i>0;--i){cell=Calendar.createElement("td",row);cell.appendChild(document.createTextNode(""));if(!i){cell.navtype=100;cell.calendar=this;Calendar._add_evs(cell);}}this.firstdayname=(this.weekNumbers)?row.firstChild.nextSibling:row.firstChild;this._displayWeekdays();var tbody=Calendar.createElement("tbody",table);this.tbody=tbody;for(i=6;i>0;--i){row=Calendar.createElement("tr",tbody);if(this.weekNumbers){cell=Calendar.createElement("td",row);cell.appendChild(document.createTextNode(""));}for(var j=7;j>0;--j){cell=Calendar.createElement("td",row);cell.appendChild(document.createTextNode(""));cell.calendar=this;Calendar._add_evs(cell);}}if(this.showsTime){row=Calendar.createElement("tr",tbody);row.className="time";cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=2;cell.innerHTML=Calendar._TT["TIME"]||" ";cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=this.weekNumbers?4:3;(function(){function makeTimePart(className,init,range_start,range_end){var part=Calendar.createElement("span",cell);part.className=className;part.appendChild(document.createTextNode(init));part.calendar=cal;part.ttip=Calendar._TT["TIME_PART"];part.navtype=50;part._range=[];if(typeof range_start!="number")part._range=range_start;else{for(var i=range_start;i<=range_end;++i){var txt;if(i<10&&range_end>=10)txt='0'+i;else txt=''+i;part._range[part._range.length]=txt;}}Calendar._add_evs(part);return part;};var hrs=cal.date.getHours();var mins=cal.date.getMinutes();var t12=!cal.time24;var pm=(hrs>12);if(t12&&pm)hrs-=12;var H=makeTimePart("hour",hrs,t12?1:0,t12?12:23);var span=Calendar.createElement("span",cell);span.appendChild(document.createTextNode(":"));span.className="colon";var M=makeTimePart("minute",mins,0,59);var AP=null;cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=2;if(t12)AP=makeTimePart("ampm",pm?"pm":"am",["am","pm"]);else cell.innerHTML=" ";cal.onSetTime=function(){var hrs=this.date.getHours();var mins=this.date.getMinutes();var pm=(hrs>12);if(pm&&t12)hrs-=12;H.firstChild.data=(hrs<10)?("0"+hrs):hrs;M.firstChild.data=(mins<10)?("0"+mins):mins;if(t12)AP.firstChild.data=pm?"pm":"am";};cal.onUpdateTime=function(){var date=this.date;var h=parseInt(H.firstChild.data,10);if(t12){if(/pm/i.test(AP.firstChild.data)&&h<12)h+=12;else if(/am/i.test(AP.firstChild.data)&&h==12)h=0;}var d=date.getDate();var m=date.getMonth();var y=date.getFullYear();date.setHours(h);date.setMinutes(parseInt(M.firstChild.data,10));date.setFullYear(y);date.setMonth(m);date.setDate(d);this.dateClicked=false;this.callHandler();};})();}else{this.onSetTime=this.onUpdateTime=function(){};}var tfoot=Calendar.createElement("tfoot",table);row=Calendar.createElement("tr",tfoot);row.className="footrow";cell=hh(Calendar._TT["SEL_DATE"],this.weekNumbers?8:7,300);cell.className="ttip";if(this.isPopup){cell.ttip=Calendar._TT["DRAG_TO_MOVE"];cell.style.cursor="move";}this.tooltips=cell;div=Calendar.createElement("div",this.element);this.monthsCombo=div;div.className="combo";for(i=0;i<Calendar._MN.length;++i){var mn=Calendar.createElement("div");mn.className=Calendar.is_ie?"label-IEfix":"label";mn.month=i;mn.appendChild(document.createTextNode(Calendar._SMN[i]));div.appendChild(mn);}div=Calendar.createElement("div",this.element);this.yearsCombo=div;div.className="combo";for(i=12;i>0;--i){var yr=Calendar.createElement("div");yr.className=Calendar.is_ie?"label-IEfix":"label";yr.appendChild(document.createTextNode(""));div.appendChild(yr);}this._init(this.firstDayOfWeek,this.date);parent.appendChild(this.element);};Calendar._keyEvent=function(ev){if(!window.calendar){return false;}(Calendar.is_ie)&&(ev=window.event);var cal=window.calendar;var act=(Calendar.is_ie||ev.type=="keypress");if(ev.ctrlKey){switch(ev.keyCode){case 37:act&&Calendar.cellClick(cal._nav_pm);break;case 38:act&&Calendar.cellClick(cal._nav_py);break;case 39:act&&Calendar.cellClick(cal._nav_nm);break;case 40:act&&Calendar.cellClick(cal._nav_ny);break;default:return false;}}else switch(ev.keyCode){case 32:Calendar.cellClick(cal._nav_now);break;case 27:act&&cal.callCloseHandler();break;case 37:case 38:case 39:case 40:if(act){var date=cal.date.getDate()-1;var el=cal.currentDateEl;var ne=null;var prev=(ev.keyCode==37)||(ev.keyCode==38);switch(ev.keyCode){case 37:(--date>=0)&&(ne=cal.ar_days[date]);break;case 38:date-=7;(date>=0)&&(ne=cal.ar_days[date]);break;case 39:(++date<cal.ar_days.length)&&(ne=cal.ar_days[date]);break;case 40:date+=7;(date<cal.ar_days.length)&&(ne=cal.ar_days[date]);break;}if(!ne){if(prev){Calendar.cellClick(cal._nav_pm);}else{Calendar.cellClick(cal._nav_nm);}date=(prev)?cal.date.getMonthDays():1;el=cal.currentDateEl;ne=cal.ar_days[date-1];}Calendar.removeClass(el,"selected");Calendar.addClass(ne,"selected");cal.date=new Date(ne.caldate);cal.callHandler();cal.currentDateEl=ne;}break;case 13:if(act){cal.callHandler();cal.hide();}break;default:return false;}return Calendar.stopEvent(ev);};Calendar.prototype._init=function(firstDayOfWeek,date){var today=new Date();this.table.style.visibility="hidden";var year=date.getFullYear();if(year<this.minYear){year=this.minYear;date.setFullYear(year);}else if(year>this.maxYear){year=this.maxYear;date.setFullYear(year);}this.firstDayOfWeek=firstDayOfWeek;this.date=new Date(date);var month=date.getMonth();var mday=date.getDate();var no_days=date.getMonthDays();date.setDate(1);var day1=(date.getDay()-this.firstDayOfWeek)%7;if(day1<0)day1+=7;date.setDate(-day1);date.setDate(date.getDate()+1);var row=this.tbody.firstChild;var MN=Calendar._SMN[month];var ar_days=new Array();var weekend=Calendar._TT["WEEKEND"];for(var i=0;i<6;++i,row=row.nextSibling){var cell=row.firstChild;if(this.weekNumbers){cell.className="day wn";cell.firstChild.data=date.getWeekNumber();cell=cell.nextSibling;}row.className="daysrow";var hasdays=false;for(var j=0;j<7;++j,cell=cell.nextSibling,date.setDate(date.getDate()+1)){var iday=date.getDate();var wday=date.getDay();cell.className="day";var current_month=(date.getMonth()==month);if(!current_month){if(this.showsOtherMonths){cell.className+=" othermonth";cell.otherMonth=true;}else{cell.className="emptycell";cell.innerHTML=" ";cell.disabled=true;continue;}}else{cell.otherMonth=false;hasdays=true;}cell.disabled=false;cell.firstChild.data=iday;if(typeof this.getDateStatus=="function"){var status=this.getDateStatus(date,year,month,iday);if(status===true){cell.className+=" disabled";cell.disabled=true;}else{if(/disabled/i.test(status))cell.disabled=true;cell.className+=" "+status;}}if(!cell.disabled){ar_days[ar_days.length]=cell;cell.caldate=new Date(date);cell.ttip="_";if(current_month&&iday==mday){cell.className+=" selected";this.currentDateEl=cell;}if(date.getFullYear()==today.getFullYear()&&date.getMonth()==today.getMonth()&&iday==today.getDate()){cell.className+=" today";cell.ttip+=Calendar._TT["PART_TODAY"];}if(weekend.indexOf(wday.toString())!=-1){cell.className+=cell.otherMonth?" oweekend":" weekend";}}}if(!(hasdays||this.showsOtherMonths))row.className="emptyrow";}this.ar_days=ar_days;this.title.firstChild.data=Calendar._MN[month]+", "+year;this.onSetTime();this.table.style.visibility="visible";};Calendar.prototype.setDate=function(date){if(!date.equalsTo(this.date)){this._init(this.firstDayOfWeek,date);}};Calendar.prototype.refresh=function(){this._init(this.firstDayOfWeek,this.date);};Calendar.prototype.setFirstDayOfWeek=function(firstDayOfWeek){this._init(firstDayOfWeek,this.date);this._displayWeekdays();};Calendar.prototype.setDateStatusHandler=Calendar.prototype.setDisabledHandler=function(unaryFunction){this.getDateStatus=unaryFunction;};Calendar.prototype.setRange=function(a,z){this.minYear=a;this.maxYear=z;};Calendar.prototype.callHandler=function(){if(this.onSelected){this.onSelected(this,this.date.print(this.dateFormat));}};Calendar.prototype.callCloseHandler=function(){if(this.onClose){this.onClose(this);}this.hideShowCovered();};Calendar.prototype.destroy=function(){var el=this.element.parentNode;el.removeChild(this.element);Calendar._C=null;window.calendar=null;};Calendar.prototype.reparent=function(new_parent){var el=this.element;el.parentNode.removeChild(el);new_parent.appendChild(el);};Calendar._checkCalendar=function(ev){if(!window.calendar){return false;}var el=Calendar.is_ie?Calendar.getElement(ev):Calendar.getTargetElement(ev);for(;el!=null&&el!=calendar.element;el=el.parentNode);if(el==null){window.calendar.callCloseHandler();return Calendar.stopEvent(ev);}};Calendar.prototype.show=function(){var rows=this.table.getElementsByTagName("tr");for(var i=rows.length;i>0;){var row=rows[--i];Calendar.removeClass(row,"rowhilite");var cells=row.getElementsByTagName("td");for(var j=cells.length;j>0;){var cell=cells[--j];Calendar.removeClass(cell,"hilite");Calendar.removeClass(cell,"active");}}this.element.style.display="block";this.hidden=false;if(this.isPopup){window.calendar=this;Calendar.addEvent(document,"keydown",Calendar._keyEvent);Calendar.addEvent(document,"keypress",Calendar._keyEvent);Calendar.addEvent(document,"mousedown",Calendar._checkCalendar);}this.hideShowCovered();};Calendar.prototype.hide=function(){if(this.isPopup){Calendar.removeEvent(document,"keydown",Calendar._keyEvent);Calendar.removeEvent(document,"keypress",Calendar._keyEvent);Calendar.removeEvent(document,"mousedown",Calendar._checkCalendar);}this.element.style.display="none";this.hidden=true;this.hideShowCovered();};Calendar.prototype.showAt=function(x,y){var s=this.element.style;s.left=x+"px";s.top=y+"px";this.show();};Calendar.prototype.showAtElement=function(el,opts){var self=this;var p=Calendar.getAbsolutePos(el);if(!opts||typeof opts!="string"){this.showAt(p.x,p.y+el.offsetHeight);return true;}function fixPosition(box){if(box.x<0)box.x=0;if(box.y<0)box.y=0;var cp=document.createElement("div");var s=cp.style;s.position="absolute";s.right=s.bottom=s.width=s.height="0px";document.body.appendChild(cp);var br=Calendar.getAbsolutePos(cp);document.body.removeChild(cp);if(Calendar.is_ie){br.y+=document.body.scrollTop;br.x+=document.body.scrollLeft;}else{br.y+=window.scrollY;br.x+=window.scrollX;}var tmp=box.x+box.width-br.x;if(tmp>0)box.x-=tmp;tmp=box.y+box.height-br.y;if(tmp>0)box.y-=tmp;};this.element.style.display="block";Calendar.continuation_for_the_fucking_khtml_browser=function(){var w=self.element.offsetWidth;var h=self.element.offsetHeight;self.element.style.display="none";var valign=opts.substr(0,1);var halign="l";if(opts.length>1){halign=opts.substr(1,1);}switch(valign){case "T":p.y-=h;break;case "B":p.y+=el.offsetHeight;break;case "C":p.y+=(el.offsetHeight-h)/2;break;case "t":p.y+=el.offsetHeight-h;break;case "b":break;}switch(halign){case "L":p.x-=w;break;case "R":p.x+=el.offsetWidth;break;case "C":p.x+=(el.offsetWidth-w)/2;break;case "r":p.x+=el.offsetWidth-w;break;case "l":break;}p.width=w;p.height=h+40;self.monthsCombo.style.display="none";fixPosition(p);self.showAt(p.x,p.y);};if(Calendar.is_khtml)setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()",10);else Calendar.continuation_for_the_fucking_khtml_browser();};Calendar.prototype.setDateFormat=function(str){this.dateFormat=str;};Calendar.prototype.setTtDateFormat=function(str){this.ttDateFormat=str;};Calendar.prototype.parseDate=function(str,fmt){var y=0;var m=-1;var d=0;var a=str.split(/\W+/);if(!fmt){fmt=this.dateFormat;}var b=fmt.match(/%./g);var i=0,j=0;var hr=0;var min=0;for(i=0;i<a.length;++i){if(!a[i])continue;switch(b[i]){case "%d":case "%e":d=parseInt(a[i],10);break;case "%m":m=parseInt(a[i],10)-1;break;case "%Y":case "%y":y=parseInt(a[i],10);(y<100)&&(y+=(y>29)?1900:2000);break;case "%b":case "%B":for(j=0;j<12;++j){if(Calendar._MN[j].substr(0,a[i].length).toLowerCase()==a[i].toLowerCase()){m=j;break;}}break;case "%H":case "%I":case "%k":case "%l":hr=parseInt(a[i],10);break;case "%P":case "%p":if(/pm/i.test(a[i])&&hr<12)hr+=12;break;case "%M":min=parseInt(a[i],10);break;}}if(y!=0&&m!=-1&&d!=0){this.setDate(new Date(y,m,d,hr,min,0));return;}y=0;m=-1;d=0;for(i=0;i<a.length;++i){if(a[i].search(/[a-zA-Z]+/)!=-1){var t=-1;for(j=0;j<12;++j){if(Calendar._MN[j].substr(0,a[i].length).toLowerCase()==a[i].toLowerCase()){t=j;break;}}if(t!=-1){if(m!=-1){d=m+1;}m=t;}}else if(parseInt(a[i],10)<=12&&m==-1){m=a[i]-1;}else if(parseInt(a[i],10)>31&&y==0){y=parseInt(a[i],10);(y<100)&&(y+=(y>29)?1900:2000);}else if(d==0){d=a[i];}}if(y==0){var today=new Date();y=today.getFullYear();}if(m!=-1&&d!=0){this.setDate(new Date(y,m,d,hr,min,0));}};Calendar.prototype.hideShowCovered=function(){var self=this;Calendar.continuation_for_the_fucking_khtml_browser=function(){function getVisib(obj){var value=obj.style.visibility;if(!value){if(document.defaultView&&typeof(document.defaultView.getComputedStyle)=="function"){if(!Calendar.is_khtml)value=document.defaultView. getComputedStyle(obj,"").getPropertyValue("visibility");else value='';}else if(obj.currentStyle){value=obj.currentStyle.visibility;}else value='';}return value;};var tags=new Array("applet","iframe","select");var el=self.element;var p=Calendar.getAbsolutePos(el);var EX1=p.x;var EX2=el.offsetWidth+EX1;var EY1=p.y;var EY2=el.offsetHeight+EY1;for(var k=tags.length;k>0;){var ar=document.getElementsByTagName(tags[--k]);var cc=null;for(var i=ar.length;i>0;){cc=ar[--i];p=Calendar.getAbsolutePos(cc);var CX1=p.x;var CX2=cc.offsetWidth+CX1;var CY1=p.y;var CY2=cc.offsetHeight+CY1;if(self.hidden||(CX1>EX2)||(CX2<EX1)||(CY1>EY2)||(CY2<EY1)){if(!cc.__msh_save_visibility){cc.__msh_save_visibility=getVisib(cc);}cc.style.visibility=cc.__msh_save_visibility;}else{if(!cc.__msh_save_visibility){cc.__msh_save_visibility=getVisib(cc);}cc.style.visibility="hidden";}}}};if(Calendar.is_khtml)setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()",10);else Calendar.continuation_for_the_fucking_khtml_browser();};Calendar.prototype._displayWeekdays=function(){var fdow=this.firstDayOfWeek;var cell=this.firstdayname;var weekend=Calendar._TT["WEEKEND"];for(var i=0;i<7;++i){cell.className="day name";var realday=(i+fdow)%7;if(i){cell.ttip=Calendar._TT["DAY_FIRST"].replace("%s",Calendar._DN[realday]);cell.navtype=100;cell.calendar=this;cell.fdow=realday;Calendar._add_evs(cell);}if(weekend.indexOf(realday.toString())!=-1){Calendar.addClass(cell,"weekend");}cell.firstChild.data=Calendar._SDN[(i+fdow)%7];cell=cell.nextSibling;}};Calendar.prototype._hideCombos=function(){this.monthsCombo.style.display="none";this.yearsCombo.style.display="none";};Calendar.prototype._dragStart=function(ev){if(this.dragging){return;}this.dragging=true;var posX;var posY;if(Calendar.is_ie){posY=window.event.clientY+document.body.scrollTop;posX=window.event.clientX+document.body.scrollLeft;}else{posY=ev.clientY+window.scrollY;posX=ev.clientX+window.scrollX;}var st=this.element.style;this.xOffs=posX-parseInt(st.left);this.yOffs=posY-parseInt(st.top);with(Calendar){addEvent(document,"mousemove",calDragIt);addEvent(document,"mouseup",calDragEnd);}};Date._MD=new Array(31,28,31,30,31,30,31,31,30,31,30,31);Date.SECOND=1000;Date.MINUTE=60*Date.SECOND;Date.HOUR=60*Date.MINUTE;Date.DAY=24*Date.HOUR;Date.WEEK=7*Date.DAY;Date.prototype.getMonthDays=function(month){var year=this.getFullYear();if(typeof month=="undefined"){month=this.getMonth();}if(((0==(year%4))&&((0!=(year%100))||(0==(year%400))))&&month==1){return 29;}else{return Date._MD[month];}};Date.prototype.getDayOfYear=function(){var now=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var then=new Date(this.getFullYear(),0,0,0,0,0);var time=now-then;return Math.floor(time/Date.DAY);};Date.prototype.getWeekNumber=function(){var d=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var DoW=d.getDay();d.setDate(d.getDate()-(DoW+6)%7+3);var ms=d.valueOf();d.setMonth(0);d.setDate(4);return Math.round((ms-d.valueOf())/(7*864e5))+1;};Date.prototype.equalsTo=function(date){return((this.getFullYear()==date.getFullYear())&&(this.getMonth()==date.getMonth())&&(this.getDate()==date.getDate())&&(this.getHours()==date.getHours())&&(this.getMinutes()==date.getMinutes()));};Date.prototype.print=function(str){var m=this.getMonth();var d=this.getDate();var y=this.getFullYear();var wn=this.getWeekNumber();var w=this.getDay();var s={};var hr=this.getHours();var pm=(hr>=12);var ir=(pm)?(hr-12):hr;var dy=this.getDayOfYear();if(ir==0)ir=12;var min=this.getMinutes();var sec=this.getSeconds();s["%a"]=Calendar._SDN[w];s["%A"]=Calendar._DN[w];s["%b"]=Calendar._SMN[m];s["%B"]=Calendar._MN[m];s["%C"]=1+Math.floor(y/100);s["%d"]=(d<10)?("0"+d):d;s["%e"]=d;s["%H"]=(hr<10)?("0"+hr):hr;s["%I"]=(ir<10)?("0"+ir):ir;s["%j"]=(dy<100)?((dy<10)?("00"+dy):("0"+dy)):dy;s["%k"]=hr;s["%l"]=ir;s["%m"]=(m<9)?("0"+(1+m)):(1+m);s["%M"]=(min<10)?("0"+min):min;s["%n"]="\n";s["%p"]=pm?"PM":"AM";s["%P"]=pm?"pm":"am";s["%s"]=Math.floor(this.getTime()/1000);s["%S"]=(sec<10)?("0"+sec):sec;s["%t"]="\t";s["%U"]=s["%W"]=s["%V"]=(wn<10)?("0"+wn):wn;s["%u"]=w+1;s["%w"]=w;s["%y"]=(''+y).substr(2,2);s["%Y"]=y;s["%%"]="%";var re=/%./g;if(!Calendar.is_ie5)return str.replace(re,function(par){return s[par]||par;});var a=str.match(re);for(var i=0;i<a.length;i++){var tmp=s[a[i]];if(tmp){re=new RegExp(a[i],'g');str=str.replace(re,tmp);}}return str;};Date.prototype.__msh_oldSetFullYear=Date.prototype.setFullYear;Date.prototype.setFullYear=function(y){var d=new Date(this);d.__msh_oldSetFullYear(y);if(d.getMonth()!=this.getMonth())this.setDate(28);this.__msh_oldSetFullYear(y);};window.calendar=null;
\ No newline at end of file diff --git a/httemplate/elements/header.html b/httemplate/elements/header.html new file mode 100644 index 000000000..10e4e40f1 --- /dev/null +++ b/httemplate/elements/header.html @@ -0,0 +1,21 @@ +<% + my($title, $menubar) = ( shift, shift ); + my $etc = @_ ? shift : ''; #$etc is for things like onLoad= etc. + my $head = @_ ? shift : ''; #$head is for things that go in the <HEAD> section +%> + <HTML> + <HEAD> + <TITLE> + <%= $title %> + </TITLE> + <META HTTP-Equiv="Cache-Control" Content="no-cache"> + <META HTTP-Equiv="Pragma" Content="no-cache"> + <META HTTP-Equiv="Expires" Content="0"> + <%= $head %> + </HEAD> + <BODY BGCOLOR="#e8e8e8"<%= $etc %>> + <FONT SIZE=6> + <%= $title %> + </FONT> + <BR><BR> + <%= $menubar ? "$menubar<BR><BR>" : '' %> diff --git a/httemplate/elements/jsrsClient.js b/httemplate/elements/jsrsClient.js new file mode 100644 index 000000000..3a2572ccb --- /dev/null +++ b/httemplate/elements/jsrsClient.js @@ -0,0 +1,356 @@ +// +// jsrsClient.js - javascript remote scripting client include +// +// Author: Brent Ashley [jsrs@megahuge.com] +// +// make asynchronous remote calls to server without client page refresh +// +// see license.txt for copyright and license information + +/* +see history.txt for full history +2.0 26 Jul 2001 - added POST capability for IE/MOZ +2.2 10 Aug 2003 - added Opera support +2.3(beta) 10 Oct 2003 - added Konqueror support - **needs more testing** +*/ + +// callback pool needs global scope +var jsrsContextPoolSize = 0; +var jsrsContextMaxPool = 10; +var jsrsContextPool = new Array(); +var jsrsBrowser = jsrsBrowserSniff(); +var jsrsPOST = true; +var containerName; + +// constructor for context object +function jsrsContextObj( contextID ){ + + // properties + this.id = contextID; + this.busy = true; + this.callback = null; + this.container = contextCreateContainer( contextID ); + + // methods + this.GET = contextGET; + this.POST = contextPOST; + this.getPayload = contextGetPayload; + this.setVisibility = contextSetVisibility; +} + +// method functions are not privately scoped +// because Netscape's debugger chokes on private functions +function contextCreateContainer( containerName ){ + // creates hidden container to receive server data + var container; + switch( jsrsBrowser ) { + case 'NS': + container = new Layer(100); + container.name = containerName; + container.visibility = 'hidden'; + container.clip.width = 100; + container.clip.height = 100; + break; + + case 'IE': + document.body.insertAdjacentHTML( "afterBegin", '<span id="SPAN' + containerName + '"></span>' ); + var span = document.all( "SPAN" + containerName ); + var html = '<iframe name="' + containerName + '" src=""></iframe>'; + span.innerHTML = html; + span.style.display = 'none'; + container = window.frames[ containerName ]; + break; + + case 'MOZ': + var span = document.createElement('SPAN'); + span.id = "SPAN" + containerName; + document.body.appendChild( span ); + var iframe = document.createElement('IFRAME'); + iframe.name = containerName; + iframe.id = containerName; + span.appendChild( iframe ); + container = iframe; + break; + + case 'OPR': + var span = document.createElement('SPAN'); + span.id = "SPAN" + containerName; + document.body.appendChild( span ); + var iframe = document.createElement('IFRAME'); + iframe.name = containerName; + iframe.id = containerName; + span.appendChild( iframe ); + container = iframe; + break; + + case 'KONQ': + var span = document.createElement('SPAN'); + span.id = "SPAN" + containerName; + document.body.appendChild( span ); + var iframe = document.createElement('IFRAME'); + iframe.name = containerName; + iframe.id = containerName; + span.appendChild( iframe ); + container = iframe; + + // Needs to be hidden for Konqueror, otherwise it'll appear on the page + span.style.display = none; + iframe.style.display = none; + iframe.style.visibility = hidden; + iframe.height = 0; + iframe.width = 0; + + break; + } + return container; +} + +function contextPOST( rsPage, func, parms ){ + + var d = new Date(); + var unique = d.getTime() + '' + Math.floor(1000 * Math.random()); + var doc = (jsrsBrowser == "IE" ) ? this.container.document : this.container.contentDocument; + doc.open(); + doc.write('<html><body>'); + doc.write('<form name="jsrsForm" method="post" target="" '); + doc.write(' action="' + rsPage + '?U=' + unique + '">'); + doc.write('<input type="hidden" name="C" value="' + this.id + '">'); + + // func and parms are optional + if (func != null){ + doc.write('<input type="hidden" name="F" value="' + func + '">'); + + if (parms != null){ + if (typeof(parms) == "string"){ + // single parameter + doc.write( '<input type="hidden" name="P0" ' + + 'value="[' + jsrsEscapeQQ(parms) + ']">'); + } else { + // assume parms is array of strings + for( var i=0; i < parms.length; i++ ){ + doc.write( '<input type="hidden" name="P' + i + '" ' + + 'value="[' + jsrsEscapeQQ(parms[i]) + ']">'); + } + } // parm type + } // parms + } // func + + doc.write('</form></body></html>'); + doc.close(); + doc.forms['jsrsForm'].submit(); +} + +function contextGET( rsPage, func, parms ){ + + // build URL to call + var URL = rsPage; + + // always send context + URL += "?C=" + this.id; + + // func and parms are optional + if (func != null){ + URL += "&F=" + escape(func); + + if (parms != null){ + if (typeof(parms) == "string"){ + // single parameter + URL += "&P0=[" + escape(parms+'') + "]"; + } else { + // assume parms is array of strings + for( var i=0; i < parms.length; i++ ){ + URL += "&P" + i + "=[" + escape(parms[i]+'') + "]"; + } + } // parm type + } // parms + } // func + + // unique string to defeat cache + var d = new Date(); + URL += "&U=" + d.getTime(); + + // make the call + switch( jsrsBrowser ) { + case 'NS': + this.container.src = URL; + break; + case 'IE': + this.container.document.location.replace(URL); + break; + case 'MOZ': + this.container.src = ''; + this.container.src = URL; + break; + case 'OPR': + this.container.src = ''; + this.container.src = URL; + break; + case 'KONQ': + this.container.src = ''; + this.container.src = URL; + break; + } +} + +function contextGetPayload(){ + switch( jsrsBrowser ) { + case 'NS': + return this.container.document.forms['jsrs_Form'].elements['jsrs_Payload'].value; + case 'IE': + return this.container.document.forms['jsrs_Form']['jsrs_Payload'].value; + case 'MOZ': + return window.frames[this.container.name].document.forms['jsrs_Form']['jsrs_Payload'].value; + case 'OPR': + var textElement = window.frames[this.container.name].document.getElementById("jsrs_Payload"); + case 'KONQ': + var textElement = window.frames[this.container.name].document.getElementById("jsrs_Payload"); + return textElement.value; + } +} + +function contextSetVisibility( vis ){ + switch( jsrsBrowser ) { + case 'NS': + this.container.visibility = (vis)? 'show' : 'hidden'; + break; + case 'IE': + document.all("SPAN" + this.id ).style.display = (vis)? '' : 'none'; + break; + case 'MOZ': + document.getElementById("SPAN" + this.id).style.visibility = (vis)? '' : 'hidden'; + case 'OPR': + document.getElementById("SPAN" + this.id).style.visibility = (vis)? '' : 'hidden'; + this.container.width = (vis)? 250 : 0; + this.container.height = (vis)? 100 : 0; + break; + } +} + +// end of context constructor + +function jsrsGetContextID(){ + var contextObj; + for (var i = 1; i <= jsrsContextPoolSize; i++){ + contextObj = jsrsContextPool[ 'jsrs' + i ]; + if ( !contextObj.busy ){ + contextObj.busy = true; + return contextObj.id; + } + } + // if we got here, there are no existing free contexts + if ( jsrsContextPoolSize <= jsrsContextMaxPool ){ + // create new context + var contextID = "jsrs" + (jsrsContextPoolSize + 1); + jsrsContextPool[ contextID ] = new jsrsContextObj( contextID ); + jsrsContextPoolSize++; + return contextID; + } else { + alert( "jsrs Error: context pool full" ); + return null; + } +} + +function jsrsExecute( rspage, callback, func, parms, visibility ){ + // call a server routine from client code + // + // rspage - href to asp file + // callback - function to call on return + // or null if no return needed + // (passes returned string to callback) + // func - sub or function name to call + // parm - string parameter to function + // or array of string parameters if more than one + // visibility - optional boolean to make container visible for debugging + + // get context + var contextObj = jsrsContextPool[ jsrsGetContextID() ]; + contextObj.callback = callback; + + var vis = (visibility == null)? false : visibility; + contextObj.setVisibility( vis ); + + if ( jsrsPOST && ((jsrsBrowser == 'IE') || (jsrsBrowser == 'MOZ'))){ + contextObj.POST( rspage, func, parms ); + } else { + contextObj.GET( rspage, func, parms ); + } + + return contextObj.id; +} + +function jsrsLoaded( contextID ){ + // get context object and invoke callback + var contextObj = jsrsContextPool[ contextID ]; + if( contextObj.callback != null){ + contextObj.callback( jsrsUnescape( contextObj.getPayload() ), contextID ); + } + // clean up and return context to pool + contextObj.callback = null; + contextObj.busy = false; +} + +function jsrsError( contextID, str ){ + alert( unescape(str) ); + jsrsContextPool[ contextID ].busy = false +} + +function jsrsEscapeQQ( thing ){ + return thing.replace(/'"'/g, '\\"'); +} + +function jsrsUnescape( str ){ + // payload has slashes escaped with whacks + return str.replace( /\\\//g, "/" ); +} + +function jsrsBrowserSniff(){ + if (document.layers) return "NS"; + if (document.all) { + // But is it really IE? + // convert all characters to lowercase to simplify testing + var agt=navigator.userAgent.toLowerCase(); + var is_opera = (agt.indexOf("opera") != -1); + var is_konq = (agt.indexOf("konqueror") != -1); + if(is_opera) { + return "OPR"; + } else { + if(is_konq) { + return "KONQ"; + } else { + // Really is IE + return "IE"; + } + } + } + if (document.getElementById) return "MOZ"; + return "OTHER"; +} + +///////////////////////////////////////////////// +// +// user functions + +function jsrsArrayFromString( s, delim ){ + // rebuild an array returned from server as string + // optional delimiter defaults to ~ + var d = (delim == null)? '~' : delim; + return s.split(d); +} + +function jsrsDebugInfo(){ + // use for debugging by attaching to f1 (works with IE) + // with onHelp = "return jsrsDebugInfo();" in the body tag + var doc = window.open().document; + doc.open; + doc.write( 'Pool Size: ' + jsrsContextPoolSize + '<br><font face="arial" size="2"><b>' ); + for( var i in jsrsContextPool ){ + var contextObj = jsrsContextPool[i]; + doc.write( '<hr>' + contextObj.id + ' : ' + (contextObj.busy ? 'busy' : 'available') + '<br>'); + doc.write( contextObj.container.document.location.pathname + '<br>'); + doc.write( contextObj.container.document.location.search + '<br>'); + doc.write( '<table border="1"><tr><td>' + contextObj.container.document.body.innerHTML + '</td></tr></table>' ); + } + doc.write('</table>'); + doc.close(); + return false; +} diff --git a/httemplate/elements/jsrsServer.html b/httemplate/elements/jsrsServer.html new file mode 100644 index 000000000..fd6dc5465 --- /dev/null +++ b/httemplate/elements/jsrsServer.html @@ -0,0 +1,3 @@ +<% + my $server = new FS::UI::Web::JSRPC '', $cgi; +%><%= $server->process %> diff --git a/httemplate/elements/menubar.html b/httemplate/elements/menubar.html new file mode 100644 index 000000000..87a50312c --- /dev/null +++ b/httemplate/elements/menubar.html @@ -0,0 +1,8 @@ +<% + my($item, $url, @html); + while (@_) { + ($item, $url) = splice(@_,0,2); + push @html, qq!<A HREF="$url">$item</A>!; + } +%> +<%= join(' | ', @html) %> diff --git a/httemplate/elements/overlibmws.js b/httemplate/elements/overlibmws.js new file mode 100644 index 000000000..fba1105b5 --- /dev/null +++ b/httemplate/elements/overlibmws.js @@ -0,0 +1,709 @@ +/*
+ Do not remove or change this notice.
+ overlibmws.js core module - Copyright Foteos Macrides 2002-2005. All rights reserved.
+ Initial: August 18, 2002 - Last Revised: February 10, 2005
+ This module is subject to the same terms of usage as for Erik Bosrup's overLIB,
+ though only a minority of the code and API now correspond with Erik's version.
+ See the overlibmws Change History and Command Reference via:
+
+ http://www.macridesweb.com/oltest/
+
+ Published under an open source license: http://www.macridesweb.com/oltest/license.html
+ Give credit on sites that use overlibmws and submit changes so others can use them as well.
+ You can get Erik's version via: http://www.bosrup.com/web/overlib/
+*/
+
+// PRE-INIT -- Ignore these lines, configuration is below.
+var OLloaded=0,pmCnt=1,pMtr=new Array(),OLv,OLudf,OLrefXY;
+var OLpct=new Array("83%","67%","83%","100%","117%","150%","200%","267%");
+var OLbubblePI=0,OLcrossframePI=0,OLdebugPI=0,OLdraggablePI=0,OLexclusivePI=0,OLfilterPI=0;
+var OLfunctionPI=0,OLhidePI=0,OLiframePI=0,OLovertwoPI=0,OLscrollPI=0,OLshadowPI=0;
+if(typeof OLgateOK=='undefined')var OLgateOK=1;
+OLregCmds(
+ 'inarray,caparray,caption,sticky,nofollow,background,noclose,mouseoff,offdelay,right,left,'
++'center,offsetx,offsety,fgcolor,bgcolor,cgcolor,textcolor,capcolor,closecolor,width,wrap,'
++'wrapmax,height,border,base,status,autostatus,autostatuscap,snapx,snapy,fixx,fixy,relx,rely,'
++'midx,midy,ref,refc,refp,refx,refy,fgbackground,bgbackground,cgbackground,padx,pady,fullhtml,'
++'below,above,vcenter,capicon,textfont,captionfont,closefont,textsize,captionsize,closesize,'
++'timeout,delay,hauto,vauto,nojustx,nojusty,closetext,closeclick,closetitle,fgclass,bgclass,'
++'cgclass,capbelow,textpadding,textfontclass,captionpadding,captionfontclass,closefontclass,'
++'label,donothing');
+
+function OLud(v){return eval('typeof ol_'+v+'=="undefined"')?1:0;}
+
+// DEFAULT CONFIGURATION -- See overlibConfig.txt for descriptions.
+if(OLud('fgcolor'))var ol_fgcolor="#CCCCFF";
+if(OLud('bgcolor'))var ol_bgcolor="#333399";
+if(OLud('cgcolor'))var ol_cgcolor="#333399";
+if(OLud('textcolor'))var ol_textcolor="#000000";
+if(OLud('capcolor'))var ol_capcolor="#FFFFFF";
+if(OLud('closecolor'))var ol_closecolor="#EEEEFF";
+if(OLud('textfont'))var ol_textfont="Verdana,Arial,Helvetica";
+if(OLud('captionfont'))var ol_captionfont="Verdana,Arial,Helvetica";
+if(OLud('closefont'))var ol_closefont="Verdana,Arial,Helvetica";
+if(OLud('textsize'))var ol_textsize=1;
+if(OLud('captionsize'))var ol_captionsize=1;
+if(OLud('closesize'))var ol_closesize=1;
+if(OLud('fgclass'))var ol_fgclass="";
+if(OLud('bgclass'))var ol_bgclass="";
+if(OLud('cgclass'))var ol_cgclass="";
+if(OLud('textpadding'))var ol_textpadding=2;
+if(OLud('textfontclass'))var ol_textfontclass="";
+if(OLud('captionpadding'))var ol_captionpadding=2;
+if(OLud('captionfontclass'))var ol_captionfontclass="";
+if(OLud('closefontclass'))var ol_closefontclass="";
+if(OLud('close'))var ol_close="Close";
+if(OLud('closeclick'))var ol_closeclick=0;
+if(OLud('closetitle'))var ol_closetitle="Click to Close";
+if(OLud('text'))var ol_text="Default Text";
+if(OLud('cap'))var ol_cap="";
+if(OLud('capbelow'))var ol_capbelow=0;
+if(OLud('background'))var ol_background="";
+if(OLud('width'))var ol_width=200;
+if(OLud('wrap'))var ol_wrap=0;
+if(OLud('wrapmax'))var ol_wrapmax=0;
+if(OLud('height'))var ol_height= -1;
+if(OLud('border'))var ol_border=1;
+if(OLud('base'))var ol_base=0;
+if(OLud('offsetx'))var ol_offsetx=10;
+if(OLud('offsety'))var ol_offsety=10;
+if(OLud('sticky'))var ol_sticky=0;
+if(OLud('nofollow'))var ol_nofollow=0;
+if(OLud('noclose'))var ol_noclose=0;
+if(OLud('mouseoff'))var ol_mouseoff=0;
+if(OLud('offdelay'))var ol_offdelay=300;
+if(OLud('hpos'))var ol_hpos=RIGHT;
+if(OLud('vpos'))var ol_vpos=BELOW;
+if(OLud('status'))var ol_status="";
+if(OLud('autostatus'))var ol_autostatus=0;
+if(OLud('snapx'))var ol_snapx=0;
+if(OLud('snapy'))var ol_snapy=0;
+if(OLud('fixx'))var ol_fixx= -1;
+if(OLud('fixy'))var ol_fixy= -1;
+if(OLud('relx'))var ol_relx=null;
+if(OLud('rely'))var ol_rely=null;
+if(OLud('midx'))var ol_midx=null;
+if(OLud('midy'))var ol_midy=null;
+if(OLud('ref'))var ol_ref="";
+if(OLud('refc'))var ol_refc='UL';
+if(OLud('refp'))var ol_refp='UL';
+if(OLud('refx'))var ol_refx=0;
+if(OLud('refy'))var ol_refy=0;
+if(OLud('fgbackground'))var ol_fgbackground="";
+if(OLud('bgbackground'))var ol_bgbackground="";
+if(OLud('cgbackground'))var ol_cgbackground="";
+if(OLud('padxl'))var ol_padxl=1;
+if(OLud('padxr'))var ol_padxr=1;
+if(OLud('padyt'))var ol_padyt=1;
+if(OLud('padyb'))var ol_padyb=1;
+if(OLud('fullhtml'))var ol_fullhtml=0;
+if(OLud('capicon'))var ol_capicon="";
+if(OLud('frame'))var ol_frame=self;
+if(OLud('timeout'))var ol_timeout=0;
+if(OLud('delay'))var ol_delay=0;
+if(OLud('hauto'))var ol_hauto=0;
+if(OLud('vauto'))var ol_vauto=0;
+if(OLud('nojustx'))var ol_nojustx=0;
+if(OLud('nojusty'))var ol_nojusty=0;
+if(OLud('label'))var ol_label="";
+// ARRAY CONFIGURATION - See overlibConfig.txt for descriptions.
+if(OLud('texts'))var ol_texts=new Array("Text 0","Text 1");
+if(OLud('caps'))var ol_caps=new Array("Caption 0","Caption 1");
+// END CONFIGURATION -- Don't change anything below, all configuration is above.
+
+// INIT -- Runtime variables.
+var o3_text="",o3_cap="",o3_sticky=0,o3_nofollow=0,o3_background="",o3_noclose=0,o3_mouseoff=0;
+var o3_offdelay=300,o3_hpos=RIGHT,o3_offsetx=10,o3_offsety=10,o3_fgcolor="",o3_bgcolor="";
+var o3_cgcolor="",o3_textcolor="",o3_capcolor="",o3_closecolor="",o3_width=200,o3_wrap=0;
+var o3_wrapmax=0,o3_height= -1,o3_border=1,o3_base=0,o3_status="",o3_autostatus=0,o3_snapx=0;
+var o3_snapy=0,o3_fixx= -1,o3_fixy= -1,o3_relx=null,o3_rely=null,o3_midx=null,o3_midy=null;
+var o3_ref="",o3_refc='UL',o3_refp='UL',o3_refx=0,o3_refy=0,o3_fgbackground="";
+var o3_bgbackground="",o3_cgbackground="",o3_padxl=0,o3_padxr=0,o3_padyt=0,o3_padyb=0;
+var o3_fullhtml=0,o3_vpos=BELOW,o3_capicon="",o3_textfont="Verdana,Arial,Helvetica";
+var o3_captionfont="Verdana,Arial,Helvetica",o3_closefont="Verdana,Arial,Helvetica";
+var o3_textsize=1,o3_captionsize=1,o3_closesize=1,o3_frame=self,o3_timeout=0,o3_delay=0;
+var o3_hauto=0,o3_vauto=0,o3_nojustx=0,o3_nojusty=0,o3_close="Close",o3_closeclick=0;
+var o3_closetitle="",o3_fgclass="",o3_bgclass="",o3_cgclass="",o3_textpadding=2;
+var o3_textfontclass="",o3_captionpadding=2,o3_captionfontclass="",o3_closefontclass="";
+var o3_capbelow=0,o3_label="",CSSOFF=DONOTHING,CSSCLASS=DONOTHING;
+var OLx=0,OLy=0,OLshowingsticky=0,OLallowmove=0,OLremovecounter=0;
+var OLdelayid=0,OLtimerid=0,OLshowid=0,OLndt=0;
+var over=null,OLfnRef="",OLhover=0;
+var OLua=navigator.userAgent.toLowerCase();
+var OLns4=(navigator.appName=='Netscape'&&parseInt(navigator.appVersion)==4);
+var OLns6=(document.getElementById)?1:0;
+var OLie4=(document.all)?1:0;
+var OLgek=(OLv=OLua.match(/gecko\/(\d{8})/i))?parseInt(OLv[1]):0;
+var OLmac=(OLua.indexOf('mac')>=0)?1:0;
+var OLsaf=(OLua.indexOf('safari')>=0)?1:0;
+var OLkon=(OLua.indexOf('konqueror')>=0)?1:0;
+var OLkht=(OLsaf||OLkon)?1:0;
+var OLopr=(OLua.indexOf('opera')>=0)?1:0;
+var OLop7=(OLopr&&document.createTextNode)?1:0;
+if(OLopr){OLns4=OLns6=0;if(!OLop7)OLie4=0;}
+var OLieM=((OLie4&&OLmac)&&!(OLkht||OLopr))?1:0;
+var OLie5=0,OLie55=0;if(OLie4&&!OLop7){
+if((OLv=OLua.match(/msie (\d\.\d+)\.*/i))&&(OLv=parseFloat(OLv[1]))>=5.0){
+OLie5=1;OLns6=0;if(OLv>=5.5)OLie55=1;}if(OLns6)OLie4=0;}
+if(OLns4)window.onresize=function(){location.reload();}
+var OLchkMh=1,OLdw;
+if(OLns4||OLie4||OLns6)OLmh();
+else{overlib=nd=cClick=OLpageDefaults=no_overlib;}
+
+/*
+ PUBLIC FUNCTIONS
+*/
+// Loads defaults then args into runtime variables.
+function overlib(){
+if(!(OLloaded&&OLgateOK))return;
+if((OLexclusivePI)&&OLisExclusive(overlib.arguments))return true;
+if(OLchkMh)OLmh();
+if(OLndt&&!OLtimerid)OLndt=0;if(over)cClick();
+OLloadP1or2();OLload('close,closeclick,closetitle,noclose,mouseoff,offdelay,sticky,'
++'closecolor,closefont,closesize,closefontclass,frame,label');OLfnRef="";OLhover=0;
+OLsetRunTimeVar();
+OLparseTokens('o3_',overlib.arguments);
+if(!(over=OLmkLyr()))return false;
+if(OLbubblePI)OLchkForBubbleEffect();
+if(OLdebugPI)OLsetDebugCanShow();
+if(OLshadowPI)OLinitShadow();
+if(OLiframePI)OLinitIfs();
+if(OLfilterPI)OLinitFilterLyr();
+if(OLexclusivePI&&o3_exclusive&&o3_exclusivestatus!="")o3_status=o3_exclusivestatus;
+else if(o3_autostatus==2&&o3_cap!="")o3_status=o3_cap;
+else if(o3_autostatus==1&&o3_text!="")o3_status=o3_text;
+if(o3_delay==0){return OLmain();
+}else{OLdelayid=setTimeout("OLmain()",o3_delay);
+if(o3_status!=""){self.status=o3_status;return true;}
+else if(!(OLop7&&event&&event.type=='mouseover'))return false;}
+}
+
+// Clears popups if appropriate
+function nd(time){
+if(!(OLloaded&&OLgateOK))return;
+if((OLexclusivePI)&&OLisExclusive())return true;
+if(time&&over&&!o3_delay){if(OLtimerid>0)clearTimeout(OLtimerid);
+OLtimerid=(OLhover&&o3_frame==self&&!OLcursorOff())?0:
+setTimeout("cClick()",(o3_timeout=OLndt=time));
+}else{if(OLremovecounter>=1)OLshowingsticky=0;if(!OLshowingsticky){
+OLallowmove=0;if(over)OLhideObject(over);}else{OLremovecounter++;}}
+return true;
+}
+
+// Close function for stickies
+function cClick(){
+if(OLloaded&&OLgateOK){OLhover=0;if(over)OLhideObject(over);OLshowingsticky=0;}
+return false;
+}
+
+// Sets page-specific defaults.
+function OLpageDefaults(){
+OLparseTokens('ol_',OLpageDefaults.arguments);
+}
+
+// For unsupported browsers.
+function no_overlib(){return false;}
+
+/*
+ OVERLIB MAIN FUNCTION SET
+*/
+function OLmain(){
+o3_delay=0;
+if(o3_frame==self){if(o3_noclose)OLoptMOUSEOFF(0);else if(o3_mouseoff)OLoptMOUSEOFF(1);}
+OLdoLyr();
+OLallowmove=0;if(o3_timeout>0){
+if(OLtimerid>0)clearTimeout(OLtimerid);OLtimerid=setTimeout("cClick()",o3_timeout);}
+if(o3_ref){OLrefXY=OLgetRefXY(o3_ref);if(OLrefXY[0]==null){o3_ref="";o3_midx=0;o3_midy=0;}}
+OLdisp(o3_status);
+if(OLdraggablePI)OLcheckDrag();
+if(o3_status!="")return true;else if(!(OLop7&&event&&event.type=='mouseover'))return false;
+}
+
+// Loads defaults for primaries or secondaries
+function OLloadP1or2(){
+OLload('text,cap,capbelow,textpadding,captionpadding,border,base,status,autostatus,nofollow,'
++'width,wrap,wrapmax,height,hpos,vpos,offsetx,offsety,snapx,snapy,relx,rely,midx,midy,ref,'
++'refc,refp,refx,refy,fixx,fixy,nojustx,nojusty,hauto,vauto,timeout,delay,fgcolor,bgcolor,'
++'cgcolor,textcolor,capcolor,textfont,captionfont,textsize,captionsize,fgbackground,'
++'bgbackground,cgbackground,capicon,background,padxl,padxr,padyt,padyb,fullhtml,fgclass,'
++'bgclass,cgclass,textfontclass,captionfontclass');
+}
+function OLload(c){var i,m=c.split(',');for(i=0;i<m.length;i++)eval('o3_'+m[i]+'=ol_'+m[i]);}
+
+// Chooses LGF
+function OLdoLGF(){
+return (o3_background!=''||o3_fullhtml)?OLcontentBackground(o3_text,o3_background,o3_fullhtml):
+(o3_cap=="")?OLcontentSimple(o3_text):
+(o3_sticky)?OLcontentCaption(o3_text,o3_cap,o3_close):OLcontentCaption(o3_text,o3_cap,'');
+}
+
+// Makes Layer
+function OLmkLyr(id,f,z){
+id=(id||'overDiv');f=(f||o3_frame);z=(z||1000);var fd=f.document,d=OLgetRefById(id,fd);
+if(!d){if(OLns4)d=fd.layers[id]=new Layer(1024,f);else if(OLie4&&!document.getElementById){
+fd.body.insertAdjacentHTML('BeforeEnd','<div id="'+id+'"></div>');d=fd.all[id];
+}else{d=fd.createElement('div');if(d){d.id=id;fd.body.appendChild(d);}}if(!d)return null;
+if(OLns4)d.zIndex=z;else{var o=d.style;o.position='absolute';o.visibility='hidden';o.zIndex=z;}}
+return d;
+}
+
+// Creates and writes layer content
+function OLdoLyr(){
+if(o3_background==''&&!o3_fullhtml){
+if(o3_fgbackground!='')o3_fgbackground=' background="'+o3_fgbackground+'"';
+if(o3_bgbackground!='')o3_bgbackground=' background="'+o3_bgbackground+'"';
+if(o3_cgbackground!='')o3_cgbackground=' background="'+o3_cgbackground+'"';
+if(o3_fgcolor!='')o3_fgcolor=' bgcolor="'+o3_fgcolor+'"';
+if(o3_bgcolor!='')o3_bgcolor=' bgcolor="'+o3_bgcolor+'"';
+if(o3_cgcolor!='')o3_cgcolor=' bgcolor="'+o3_cgcolor+'"';
+if(o3_height>0)o3_height=' height="'+o3_height+'"';else o3_height='';}
+if(!OLns4)OLrepositionTo(over,(OLns6?20:0),0);var lyrHtml=OLdoLGF();
+if(o3_sticky){if(OLtimerid>0){clearTimeout(OLtimerid);OLtimerid=0;}
+OLshowingsticky=1;OLremovecounter=0;}
+if(o3_wrap&&!o3_fullhtml){OLlayerWrite(lyrHtml);
+o3_width=(OLns4?over.clip.width:over.offsetWidth);
+if(OLns4&&o3_wrapmax<1)o3_wrapmax=o3_frame.innerWidth-40;
+o3_wrap=0;if(o3_wrapmax>0&&o3_width>o3_wrapmax)o3_width=o3_wrapmax;lyrHtml=OLdoLGF();}
+OLlayerWrite(lyrHtml);o3_width=(OLns4?over.clip.width:over.offsetWidth);
+if(OLbubblePI)OLgenerateBubble(lyrHtml);
+}
+
+/*
+ LAYER GENERATION FUNCTIONS
+*/
+// Makes simple table without caption
+function OLcontentSimple(txt){
+var t=OLbgLGF()+OLfgLGF(txt)+OLbaseLGF();
+OLsetBackground('');return t;
+}
+
+// Makes table with caption and optional close link
+function OLcontentCaption(txt,title,close){
+var closing='',closeevent='onmouseover',caption,t;
+if(o3_closeclick==1)closeevent=(o3_closetitle?'title="'+o3_closetitle+'" ':'')+'onclick';
+if(o3_capicon!='')o3_capicon='<img src="'+o3_capicon+'" /> ';
+if(close!=''){closing='<td align="right"><a href="javascript:return '+OLfnRef+'cClick();" '
++closeevent+'="return '+OLfnRef+'cClick();"'+(o3_closefontclass?' class="'+o3_closefontclass
++'">':'>'+OLlgfUtil(0,'','span',o3_closecolor,o3_closefont,o3_closesize))+close
++(o3_closefontclass?'':OLlgfUtil(1,'','span'))+'</a></td>';}
+caption='<table'+OLwd(0)+' border="0" cellpadding="'+o3_captionpadding+'" cellspacing="0"'
++(o3_cgclass?' class="'+o3_cgclass+'"':o3_cgcolor+o3_cgbackground)+'><tr><td'+OLwd(0)
++(o3_cgclass?' class="'+o3_cgclass+'">':'>')+(o3_captionfontclass?'<div class="'
++o3_captionfontclass+'">':'<strong>'
++OLlgfUtil(0,'','div',o3_capcolor,o3_captionfont,o3_captionsize))+o3_capicon+title
++OLlgfUtil(1,'','div')+(o3_captionfontclass?'':'</strong>')+'</td>'+closing+'</tr></table>';
+t=OLbgLGF()+(o3_capbelow?OLfgLGF(txt)+caption:caption+OLfgLGF(txt))+OLbaseLGF();
+OLsetBackground('');return t;
+}
+
+// For BACKGROUND and FULLHTML commands
+function OLcontentBackground(txt, image, hasfullhtml){
+var t;if(hasfullhtml){t=txt;}else{t='<table'+OLwd(1)
++' border="0" cellpadding="0" cellspacing="0" '+'height="'+o3_height
++'"><tr><td colspan="3" height="'+o3_padyt+'"></td></tr><tr><td width="'
++o3_padxl+'"></td><td valign="top"'+OLwd(2)+'>'
++OLlgfUtil(0,o3_textfontclass,'div',o3_textcolor,o3_textfont,o3_textsize)+txt+
+OLlgfUtil(1,'','div')+'</td><td width="'+o3_padxr+'"></td></tr><tr><td colspan="3" height="'
++o3_padyb+'"></td></tr></table>';}
+OLsetBackground(image);return t;
+}
+
+// LGF utilities
+function OLbgLGF(){
+return '<table'+OLwd(1)+o3_height+' border="0" cellpadding="'+o3_border+'" cellspacing="0"'
++(o3_bgclass?' class="'+o3_bgclass+'"':o3_bgcolor+o3_bgbackground)+'><tr><td>';
+}
+function OLfgLGF(t){
+return '<table'+OLwd(0)+o3_height+' border="0" cellpadding="'+o3_textpadding
++'" cellspacing="0"'+(o3_fgclass?' class="'+o3_fgclass+'"':o3_fgcolor+o3_fgbackground)
++'><tr><td valign="top"'+(o3_fgclass?' class="'+o3_fgclass+'"':'')+'>'
++OLlgfUtil(0,o3_textfontclass,'div',o3_textcolor,o3_textfont,o3_textsize)+t
++OLlgfUtil(1,'','div')+'</td></tr></table>';
+}
+function OLlgfUtil(end,tfc,ele,col,fac,siz){
+if(end)return ('</'+(OLns4?'font':ele)+'>');else return (tfc?'<div class="'+tfc+'">':
+('<'+(OLns4?'font color="'+col+'" face="'+OLquoteMultiNameFonts(fac)+'" size="'+siz:ele
++' style="color:'+col+';font-family:'+OLquoteMultiNameFonts(fac)+';font-size:'+siz+';'
++(ele=='span'?'text-decoration:underline;':''))+'">'));
+}
+function OLquoteMultiNameFonts(f){
+var i,v,pM=f.split(',');
+for(i=0;i<pM.length;i++){v=pM[i];v=v.replace(/^\s+/,'').replace(/\s+$/,'');
+if(/\s/.test(v) && !/['"]/.test(v)){v="\'"+v+"\'";pM[i]=v;}}
+return pM.join();
+}
+function OLbaseLGF(){
+return ((o3_base>0&&!o3_wrap)?('<table width="100%" border="0" cellpadding="0" cellspacing="0"'
++(o3_bgclass?' class="'+o3_bgclass+'"':'')+'><tr><td height="'+o3_base
++'"></td></tr></table>'):'')+'</td></tr></table>';
+}
+function OLwd(a){
+return(o3_wrap?'':' width="'+(!a?'100%':(a==1?o3_width:(o3_width-o3_padxl-o3_padxr)))+'"');
+}
+
+// Loads image into the div.
+function OLsetBackground(i){
+if(i==''){if(OLns4)over.background.src=null;
+else{if(OLns6)over.style.width='';over.style.backgroundImage='none';}
+}else{if(OLns4)over.background.src=i;
+else{if(OLns6)over.style.width=o3_width+'px';over.style.backgroundImage='url('+i+')';}}
+}
+
+/*
+ HANDLING FUNCTIONS
+*/
+// Displays layer
+function OLdisp(s){
+if(OLallowmove==0){if(OLshadowPI)OLdispShadow();if(OLiframePI)OLdispIfs();OLplaceLayer();
+if(OLndt)OLshowObject(over);else OLshowid=setTimeout("OLshowObject(over)",1);
+OLallowmove=(o3_sticky||o3_nofollow)?0:1;}OLndt=0;if(s!="")self.status=s;
+}
+
+// Decides placement of layer.
+function OLplaceLayer(){
+var snp,X,Y,pgLeft,pgTop,pWd=o3_width,pHt,iWd=100,iHt=100,SB=0,LM=0,CX=0,TM=0,BM=0,CY=0;
+var o=OLfd(),nsb=(OLgek>=20010505&&!o3_frame.scrollbars.visible)?1:0;
+if(!OLkht&&o&&o.clientWidth)iWd=o.clientWidth;
+else if(o3_frame.innerWidth){SB=Math.ceil(1.4*(o3_frame.outerWidth-o3_frame.innerWidth));
+if(SB>20)SB=20;iWd=o3_frame.innerWidth;}
+pgLeft=(OLie4)?o.scrollLeft:o3_frame.pageXOffset;
+if(OLie55&&OLfilterPI&&o3_filtershadow)SB=CX=5;else
+if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowx){SB+=((o3_shadowx>0)?o3_shadowx:0);
+LM=((o3_shadowx<0)?Math.abs(o3_shadowx):0);CX=Math.abs(o3_shadowx);}
+if(o3_ref!=""||o3_fixx> -1||o3_relx!=null||o3_midx!=null){
+if(o3_ref!=""){
+X=OLrefXY[0];if(OLie55&&OLfilterPI&&o3_filtershadow){if(o3_refp=='UR'||o3_refp=='LR')X -= 5;}
+else if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowx){
+if(o3_shadowx<0&&(o3_refp=='UL'||o3_refp=='LL'))X += o3_shadowx;
+else if(o3_shadowx>0&&(o3_refp=='UR'||o3_refp=='LR'))X -= o3_shadowx;}
+}else{if(o3_midx!=null){
+X=parseInt(pgLeft+((iWd-pWd-SB-LM)/2)+o3_midx);
+}else{if(o3_relx!=null){
+if(o3_relx>=0)X=pgLeft+o3_relx+LM;else X=pgLeft+o3_relx+iWd-pWd-SB;
+}else{
+X=o3_fixx+LM;}}}
+}else{
+if(o3_hauto){
+if(o3_hpos==LEFT&&OLx-pgLeft<iWd/2&&OLx-pWd-o3_offsetx<pgLeft+LM)o3_hpos=RIGHT;else
+if(o3_hpos==RIGHT&&OLx-pgLeft>iWd/2&&OLx+pWd+o3_offsetx>pgLeft+iWd-SB)o3_hpos=LEFT;}
+X=(o3_hpos==CENTER)?parseInt(OLx-((pWd+CX)/2)+o3_offsetx):
+(o3_hpos==LEFT)?OLx-o3_offsetx-pWd:OLx+o3_offsetx;
+if(o3_snapx>1){
+snp=X % o3_snapx;
+if(o3_hpos==LEFT){X=X-(o3_snapx+snp);}else{X=X+(o3_snapx-snp);}}}
+if(!o3_nojustx&&X+pWd>pgLeft+iWd-SB)
+X=iWd+pgLeft-pWd-SB;if(!o3_nojustx&&X-LM<pgLeft)X=pgLeft+LM;
+pgTop=OLie4?o.scrollTop:o3_frame.pageYOffset;
+if(!OLkht&&!nsb&&o&&o.clientHeight)iHt=o.clientHeight;
+else if(o3_frame.innerHeight)iHt=o3_frame.innerHeight;
+if(OLbubblePI&&o3_bubble)pHt=OLbubbleHt;else pHt=OLns4?over.clip.height:over.offsetHeight;
+if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowy){TM=(o3_shadowy<0)?Math.abs(o3_shadowy):0;
+if(OLie55&&OLfilterPI&&o3_filtershadow)BM=CY=5;else
+BM=(o3_shadowy>0)?o3_shadowy:0;CY=Math.abs(o3_shadowy);}
+if(o3_ref!=""||o3_fixy> -1||o3_rely!=null||o3_midy!=null){
+if(o3_ref!=""){
+Y=OLrefXY[1];if(OLie55&&OLfilterPI&&o3_filtershadow){if(o3_refp=='LL'||o3_refp=='LR')Y -= 5;}
+else if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowy){
+if(o3_shadowy<0&&(o3_refp=='UL'||o3_refp=='UR'))Y+=o3_shadowy;else
+if(o3_shadowy>0&&(o3_refp=='LL'||o3_refp=='LR'))Y-=o3_shadowy;}
+}else{if(o3_midy!=null){
+Y=parseInt(pgTop+((iHt-pHt-CY)/2)+o3_midy);
+}else{if(o3_rely!=null){
+if(o3_rely>=0)Y=pgTop+o3_rely+TM;else Y=pgTop+o3_rely+iHt-pHt-BM;}else{
+Y=o3_fixy+TM;}}}
+}else{
+if(o3_vauto){
+if(o3_vpos==ABOVE&&OLy-pgTop<iHt/2&&OLy-pHt-o3_offsety<pgTop)o3_vpos=BELOW;else
+if(o3_vpos==BELOW&&OLy-pgTop>iHt/2&&OLy+pHt+o3_offsety+((OLns4||OLkht)?17:0)>pgTop+iHt-BM)
+o3_vpos=ABOVE;}Y=(o3_vpos==VCENTER)?parseInt(OLy-((pHt+CY)/2)+o3_offsety):
+(o3_vpos==ABOVE)?OLy-(pHt+o3_offsety+BM):OLy+o3_offsety+TM;
+if(o3_snapy>1){
+snp=Y % o3_snapy;
+if(pHt>0&&o3_vpos==ABOVE){Y=Y-(o3_snapy+snp);}else{Y=Y+(o3_snapy-snp);}}}
+if(!o3_nojusty&&Y+pHt+BM>pgTop+iHt)Y=pgTop+iHt-pHt-BM;if(!o3_nojusty&&Y-TM<pgTop)Y=pgTop+TM;
+OLrepositionTo(over,X,Y);
+if(OLshadowPI)OLrepositionShadow(X,Y);if(OLiframePI)OLrepositionIfs(X,Y);
+if(OLns6&&o3_frame.innerHeight){iHt=o3_frame.innerHeight;OLrepositionTo(over,X,Y);}
+if(OLscrollPI)OLchkScroll(X-pgLeft,Y-pgTop);
+}
+
+// Chooses body or documentElement
+function OLfd(f){
+var fd=((f)?f:o3_frame).document,fdc=fd.compatMode,fdd=fd.documentElement;
+return (!OLop7&&fdc&&fdc!='BackCompat'&&fdd&&fdd.clientWidth)?fd.documentElement:fd.body;
+}
+
+// Gets location of REFerence object
+function OLgetRefXY(r){
+var mn=r,mr=OLgetRef(mn),o,of,rXY;
+if(!mr)return [null,null];
+o=mr;rXY=[o3_refx,o3_refy];
+if(OLns4){if(typeof mr.length!='undefined'&&mr.length>1){
+o=mr[0];rXY[0]+=mr[0].x+mr[1].pageX;rXY[1]+=mr[0].y+mr[1].pageY;
+}else{if((mr.toString().indexOf('Image')!= -1)||(mr.toString().indexOf('Anchor')!= -1)){
+rXY[0]+=mr.x;rXY[1]+=mr.y;}else{rXY[0]+=mr.pageX;rXY[1]+=mr.pageY;}}
+}else{rXY[0]+=OLpageLoc(mr,'Left');rXY[1]+=OLpageLoc(mr,'Top');}
+of=OLgetRefOffsets(o);rXY[0]+=of[0];rXY[1]+=of[1];
+return rXY;
+}
+function OLgetRef(l){var r=OLgetRefById(l);return (r)?r:OLgetRefByName(l);}
+
+// Seeks REFerence by id
+function OLgetRefById(l,d){
+var r="",j;l=(l||'overDiv');d=(d||o3_frame.document);
+if(OLie4&&d.all){return d.all[l];}else if(d.getElementById){return d.getElementById(l);
+}else if(d.layers&&d.layers.length>0){if(d.layers[l])return d.layers[l];
+for(j=0;j<d.layers.length;j++){r=OLgetRefById(l,d.layers[j].document);if(r)return r;}}
+return null;
+}
+
+// Seeks REFerence by name (for img and a)
+function OLgetRefByName(l,d){
+var r=null,j;d=(d||o3_frame.document);
+if(typeof d.images[l]!='undefined'&&d.images[l]){return d.images[l];
+}else if(typeof d.anchors[l]!='undefined'&&d.anchors[l]){return d.anchors[l];
+}else if(d.layers&&d.layers.length>0){
+for(j=0;j<d.layers.length;j++){r=OLgetRefByName(l,d.layers[j].document);
+if(r&&r.length>0)return r;else if(r)return [r,d.layers[j]];}}
+return null;
+}
+
+// Gets layer vs REFerence offsets
+function OLgetRefOffsets(o){
+var mc=o3_refc.toUpperCase(),mp=o3_refp.toUpperCase(),mW=0,mH=0,pW=0,pH=0,off=[0,0];
+pW=(OLbubblePI&&o3_bubble)?o3_width:OLns4?over.clip.width:over.offsetWidth;
+pH=(OLbubblePI&&o3_bubble)?OLbubbleHt:OLns4?over.clip.height:over.offsetHeight;
+if((!OLop7)&&o.toString().indexOf('Image')!= -1){mW=o.width;mH=o.height;
+}else if((!OLop7)&&o.toString().indexOf('Anchor')!= -1){mc=o3_refc='UL';}else{
+mW=(OLns4)?o.clip.width:o.offsetWidth;mH=(OLns4)?o.clip.height:o.offsetHeight;}
+if(mc=='UL'){off=(mp=='UR')?[-pW,0]:(mp=='LL')?[0,-pH]:(mp=='LR')?[-pW,-pH]:[0,0];
+}else if(mc=='UR'){off=(mp=='UR')?[mW-pW,0]:(mp=='LL')?[mW,-pH]:(mp=='LR')?[mW-pW,-pH]:[mW,0];
+}else if(mc=='LL'){off=(mp=='UR')?[-pW,mH]:(mp=='LL')?[0,mH-pH]:(mp=='LR')?[-pW,mH-pH]:[0,mH];
+}else if(mc=='LR'){off=(mp=='UR')?[mW-pW,mH]:(mp=='LL')?[mW,mH-pH]:(mp=='LR')?[mW-pW,mH-pH]:
+[mW,mH];}
+return off;
+}
+
+// Gets x or y location of object
+function OLpageLoc(o,t){
+var l=0;while(o.offsetParent&&o.offsetParent.tagName.toLowerCase()!='html'){
+l+=o['offset'+t];o=o.offsetParent;}l+=o['offset'+t];
+return l;
+}
+
+// Moves layer
+function OLmouseMove(e){
+var e=(e||event);
+OLx=(e.pageX||e.clientX+OLfd().scrollLeft);OLy=(e.pageY||e.clientY+OLfd().scrollTop);
+if((OLallowmove&&over)&&(o3_frame==self||over==OLgetRefById())){
+OLplaceLayer();if(OLhidePI)OLhideUtil(0,1,1,0,0,0);}
+if(OLhover&&over&&o3_frame==self&&OLcursorOff())if(o3_offdelay<1)cClick();else
+{if(OLtimerid>0)clearTimeout(OLtimerid);OLtimerid=setTimeout("cClick()",o3_offdelay);}
+}
+
+// Capture mouse and chain other scripts.
+function OLmh(){
+var fN,f,j,k,s,mh=OLmouseMove,w=(OLns4&&window.onmousemove),re=/function[ ]*(\w*)\(/;
+OLdw=document;if(document.onmousemove||w){if(w)OLdw=window;f=OLdw.onmousemove.toString();
+fN=f.match(re);if(!fN||fN[1]=='anonymous'||fN[1]=='OLmouseMove'){OLchkMh=0;return;}
+if(fN[1])s=fN[1]+'(e)';else{j=f.indexOf('{');k=f.lastIndexOf('}')+1;s=f.substring(j,k);}
+s+=';OLmouseMove(e);';mh=new Function('e',s);}
+OLdw.onmousemove=mh;if(OLns4)OLdw.captureEvents(Event.MOUSEMOVE);
+}
+
+/*
+ PARSING
+*/
+function OLparseTokens(pf,ar){
+var i,v,md= -1,par=(pf!='ol_'),e=eval,p=OLpar,q=OLparQuo,t=OLtoggle;OLudf=(par&&!ar.length?1:0);
+for(i=0;i< ar.length;i++){if(md<0){if(typeof ar[i]=='number'){OLudf=(par?1:0);i--;}
+else{switch(pf){case 'ol_':ol_text=ar[i];break;default:o3_text=ar[i];}}md=0;
+}else{
+if(ar[i]==INARRAY){OLudf=0;e(pf+'text=ol_texts['+ar[++i]+']');continue;}
+if(ar[i]==CAPARRAY){e(pf+'cap=ol_caps['+ar[++i]+']');continue;}
+if(ar[i]==CAPTION){q(ar[++i],pf+'cap');continue;}
+if(Math.abs(ar[i])==STICKY){t(ar[i],pf+'sticky');continue;}
+if(Math.abs(ar[i])==NOFOLLOW){t(ar[i],pf+'nofollow');continue;}
+if(ar[i]==BACKGROUND){q(ar[++i],pf+'background');continue;}
+if(Math.abs(ar[i])==NOCLOSE){t(ar[i],pf+'noclose');continue;}
+if(Math.abs(ar[i])==MOUSEOFF){t(ar[i],pf+'mouseoff');continue;}
+if(ar[i]==OFFDELAY){p(ar[++i],pf+'offdelay');continue;}
+if(ar[i]==RIGHT||ar[i]==LEFT||ar[i]==CENTER){p(ar[i],pf+'hpos');continue;}
+if(ar[i]==OFFSETX){p(ar[++i],pf+'offsetx');continue;}
+if(ar[i]==OFFSETY){p(ar[++i],pf+'offsety');continue;}
+if(ar[i]==FGCOLOR){q(ar[++i],pf+'fgcolor');continue;}
+if(ar[i]==BGCOLOR){q(ar[++i],pf+'bgcolor');continue;}
+if(ar[i]==CGCOLOR){q(ar[++i],pf+'cgcolor');continue;}
+if(ar[i]==TEXTCOLOR){q(ar[++i],pf+'textcolor');continue;}
+if(ar[i]==CAPCOLOR){q(ar[++i],pf+'capcolor');continue;}
+if(ar[i]==CLOSECOLOR){q(ar[++i],pf+'closecolor');continue;}
+if(ar[i]==WIDTH){p(ar[++i],pf+'width');continue;}
+if(Math.abs(ar[i])==WRAP){t(ar[i],pf+'wrap');continue;}
+if(ar[i]==WRAPMAX){p(ar[++i],pf+'wrapmax');continue;}
+if(ar[i]==HEIGHT){p(ar[++i],pf+'height');continue;}
+if(ar[i]==BORDER){p(ar[++i],pf+'border');continue;}
+if(ar[i]==BASE){p(ar[++i],pf+'base');continue;}
+if(ar[i]==STATUS){q(ar[++i],pf+'status');continue;}
+if(Math.abs(ar[i])==AUTOSTATUS){v=pf+'autostatus';
+e(v+'=('+ar[i]+'<0)?('+v+'==2?2:0):('+v+'==1?0:1)');continue;}
+if(Math.abs(ar[i])==AUTOSTATUSCAP){v=pf+'autostatus';
+e(v+'=('+ar[i]+'<0)?('+v+'==1?1:0):('+v+'==2?0:2)');continue;}
+if(ar[i]==CLOSETEXT){q(ar[++i],pf+'close');continue;}
+if(ar[i]==SNAPX){p(ar[++i],pf+'snapx');continue;}
+if(ar[i]==SNAPY){p(ar[++i],pf+'snapy');continue;}
+if(ar[i]==FIXX){p(ar[++i],pf+'fixx');continue;}
+if(ar[i]==FIXY){p(ar[++i],pf+'fixy');continue;}
+if(ar[i]==RELX){p(ar[++i],pf+'relx');continue;}
+if(ar[i]==RELY){p(ar[++i],pf+'rely');continue;}
+if(ar[i]==MIDX){p(ar[++i],pf+'midx');continue;}
+if(ar[i]==MIDY){p(ar[++i],pf+'midy');continue;}
+if(ar[i]==REF){q(ar[++i],pf+'ref');continue;}
+if(ar[i]==REFC){q(ar[++i],pf+'refc');continue;}
+if(ar[i]==REFP){q(ar[++i],pf+'refp');continue;}
+if(ar[i]==REFX){p(ar[++i],pf+'refx');continue;}
+if(ar[i]==REFY){p(ar[++i],pf+'refy');continue;}
+if(ar[i]==FGBACKGROUND){q(ar[++i],pf+'fgbackground');continue;}
+if(ar[i]==BGBACKGROUND){q(ar[++i],pf+'bgbackground');continue;}
+if(ar[i]==CGBACKGROUND){q(ar[++i],pf+'cgbackground');continue;}
+if(ar[i]==PADX){p(ar[++i],pf+'padxl');p(ar[++i],pf+'padxr');continue;}
+if(ar[i]==PADY){p(ar[++i],pf+'padyt');p(ar[++i],pf+'padyb');continue;}
+if(Math.abs(ar[i])==FULLHTML){t(ar[i],pf+'fullhtml');continue;}
+if(ar[i]==BELOW||ar[i]==ABOVE||ar[i]==VCENTER){p(ar[i],pf+'vpos');continue;}
+if(ar[i]==CAPICON){q(ar[++i],pf+'capicon');continue;}
+if(ar[i]==TEXTFONT){q(ar[++i],pf+'textfont');continue;}
+if(ar[i]==CAPTIONFONT){q(ar[++i],pf+'captionfont');continue;}
+if(ar[i]==CLOSEFONT){q(ar[++i],pf+'closefont');continue;}
+if(ar[i]==TEXTSIZE){q(ar[++i],pf+'textsize');continue;}
+if(ar[i]==CAPTIONSIZE){q(ar[++i],pf+'captionsize');continue;}
+if(ar[i]==CLOSESIZE){q(ar[++i],pf+'closesize');continue;}
+if(ar[i]==TIMEOUT){p(ar[++i],pf+'timeout');continue;}
+if(ar[i]==DELAY){p(ar[++i],pf+'delay');continue;}
+if(Math.abs(ar[i])==HAUTO){t(ar[i],pf+'hauto');continue;}
+if(Math.abs(ar[i])==VAUTO){t(ar[i],pf+'vauto');continue;}
+if(Math.abs(ar[i])==NOJUSTX){t(ar[i],pf+'nojustx');continue;}
+if(Math.abs(ar[i])==NOJUSTY){t(ar[i],pf+'nojusty');continue;}
+if(Math.abs(ar[i])==CLOSECLICK){t(ar[i],pf+'closeclick');continue;}
+if(ar[i]==CLOSETITLE){q(ar[++i],pf+'closetitle');continue;}
+if(ar[i]==FGCLASS){q(ar[++i],pf+'fgclass');continue;}
+if(ar[i]==BGCLASS){q(ar[++i],pf+'bgclass');continue;}
+if(ar[i]==CGCLASS){q(ar[++i],pf+'cgclass');continue;}
+if(ar[i]==TEXTPADDING){p(ar[++i],pf+'textpadding');continue;}
+if(ar[i]==TEXTFONTCLASS){q(ar[++i],pf+'textfontclass');continue;}
+if(ar[i]==CAPTIONPADDING){p(ar[++i],pf+'captionpadding');continue;}
+if(ar[i]==CAPTIONFONTCLASS){q(ar[++i],pf+'captionfontclass');continue;}
+if(ar[i]==CLOSEFONTCLASS){q(ar[++i],pf+'closefontclass');continue;}
+if(Math.abs(ar[i])==CAPBELOW){t(ar[i],pf+'capbelow');continue;}
+if(ar[i]==LABEL){q(ar[++i],pf+'label');continue;}
+if(ar[i]==DONOTHING){continue;}
+i=OLparseCmdLine(pf,i,ar);}}
+if((OLfunctionPI)&&OLudf&&o3_function)o3_text=o3_function();
+if(pf=='o3_')OLfontSize();
+}
+function OLpar(a,v){eval(v+'='+a);}
+function OLparQuo(a,v){eval(v+"='"+OLescSglQt(a)+"'");}
+function OLescSglQt(s){return s.toString().replace(/'/g,"\\'");}
+function OLtoggle(a,v){eval(v+'=('+v+'==0&&'+a+'>=0)?1:0');}
+function OLhasDims(s){return /[%\-a-z]+$/.test(s);}
+function OLfontSize(){
+var i;if(OLhasDims(o3_textsize)){if(OLns4)o3_textsize="2";}else
+if(!OLns4){i=parseInt(o3_textsize);o3_textsize=(i>0&&i<8)?OLpct[i]:OLpct[0];}
+if(OLhasDims(o3_captionsize)){if(OLns4)o3_captionsize="2";}else
+if(!OLns4){i=parseInt(o3_captionsize);o3_captionsize=(i>0&&i<8)?OLpct[i]:OLpct[0];}
+if(OLhasDims(o3_closesize)){if(OLns4)o3_closesize="2";}else
+if(!OLns4){i=parseInt(o3_closesize);o3_closesize=(i>0&&i<8)?OLpct[i]:OLpct[0];}
+}
+
+/*
+ LAYER FUNCTIONS
+*/
+// Writes to layer
+function OLlayerWrite(t){
+t+="\n";
+if(OLns4){over.document.write(t);over.document.close();
+}else if(typeof over.innerHTML!='undefined'){if(OLieM)over.innerHTML='';over.innerHTML=t;
+}else{range=o3_frame.document.createRange();range.setStartAfter(over);
+domfrag=range.createContextualFragment(t);
+while(over.hasChildNodes()){over.removeChild(over.lastChild);}
+over.appendChild(domfrag);}
+}
+
+// Makes object visible
+function OLshowObject(o){
+OLshowid=0;o=(OLns4)?o:o.style;
+if(((OLfilterPI)&&!OLchkFilter(o))||!OLfilterPI)o.visibility="visible";
+if(OLshadowPI)OLshowShadow();if(OLiframePI)OLshowIfs();if(OLhidePI)OLhideUtil(1,1,0);
+}
+
+// Hides object
+function OLhideObject(o){
+if(OLshowid>0){clearTimeout(OLshowid);OLshowid=0;}
+if(OLtimerid>0)clearTimeout(OLtimerid);if(OLdelayid>0)clearTimeout(OLdelayid);
+OLtimerid=0;OLdelayid=0;self.status="";o3_label=ol_label;
+if(o3_frame!=self)o=OLgetRefById();
+if(o){if(o.onmouseover)o.onmouseover=null;
+if(OLscrollPI&&o==over)OLclearScroll();
+if(OLdraggablePI)OLclearDrag();
+if(OLfilterPI)OLcleanupFilter(o);if(OLshadowPI)OLhideShadow();
+var os=(OLns4)?o:o.style;os.visibility="hidden";
+if(OLhidePI&&o==over)OLhideUtil(0,0,1);if(OLiframePI)OLhideIfs(o);}
+}
+
+// Moves layer
+function OLrepositionTo(o,xL,yL){
+o=(OLns4)?o:o.style;
+o.left=(OLns4?xL:xL+'px');
+o.top=(OLns4?yL:yL+'px');
+}
+
+// Handle NOCLOSE-MOUSEOFF
+function OLoptMOUSEOFF(c){
+if(!c)o3_close="";
+over.onmouseover=function(){OLhover=1;if(OLtimerid>0){clearTimeout(OLtimerid);OLtimerid=0;}}
+}
+function OLcursorOff(){
+if(OLovertwoPI&&over==over2)return false;
+var o=(OLns4?over:over.style),pHt=OLns4?over.clip.height:over.offsetHeight;
+var left=parseInt(o.left),top=parseInt(o.top);
+var right=left+o3_width,bottom=top+((OLbubblePI&&o3_bubble)?OLbubbleHt:pHt);
+if(OLx<left||OLx>right||OLy<top||OLy>bottom)return true;
+return false;
+}
+
+/*
+ REGISTRATION
+*/
+var OLcmdLine=null,OLrunTime=null;
+function OLsetRunTimeVar(){
+if(OLrunTime&&OLrunTime.length)for(var k=0;k<OLrunTime.length;k++)OLrunTime[k]();
+}
+function OLparseCmdLine(pf,i,ar){
+if(OLcmdLine&&OLcmdLine.length){for(var k=0;k<OLcmdLine.length;k++){
+var j=OLcmdLine[k](pf,i,ar);if(j>-1){i=j;break;}}}
+return i;
+}
+function OLisFunc(f){
+var r=1;
+if(typeof f=='object'){for(var i=0;i<f.length;i++){
+if(typeof f[i]=='function')continue;r=0;break;}
+}else if(typeof f!='function')r=0;
+return r;
+}
+function OLregCmds(c){
+if(typeof c!='string')return;
+var pM=c.split(',');pMtr=pMtr.concat(pM);
+for(var i=0;i<pM.length;i++)eval(pM[i].toUpperCase()+'='+pmCnt++);
+}
+function OLregRunTimeFunc(f){
+if(OLisFunc(f)){
+if(!OLrunTime)OLrunTime=new Array();
+if(typeof f=='object')OLrunTime=OLrunTime.concat(f);
+else OLrunTime[OLrunTime.length++]=f;}
+}
+function OLregCmdLineFunc(f){
+if(OLisFunc(f)){
+if(!OLcmdLine)OLcmdLine=new Array();
+if(typeof f=='object')OLcmdLine=OLcmdLine.concat(f);
+else OLcmdLine[OLcmdLine.length++]=f;}
+}
+
+OLloaded=1;
diff --git a/httemplate/elements/overlibmws_draggable.js b/httemplate/elements/overlibmws_draggable.js new file mode 100644 index 000000000..14e4a6062 --- /dev/null +++ b/httemplate/elements/overlibmws_draggable.js @@ -0,0 +1,78 @@ +/*
+ overlibmws_draggable.js plug-in module - Copyright Foteos Macrides 2002=2005
+ For support of the DRAGGABLE feature.
+ Initial: August 24, 2002 - Last Revised: January 12, 2005
+ See the Change History and Command Reference for overlibmws via:
+
+ http://www.macridesweb.com/oltest/
+
+ Published under an open source license: http://www.macridesweb.com/oltest/license.html
+*/
+
+OLloaded=0;
+OLregCmds('draggable');
+
+// DEFAULT CONFIGURATION
+if(OLud('draggable'))var ol_draggable=0;
+// END CONFIGURATION
+
+var o3_draggable=0,o3_dragging=0,OLmMv,OLcX,OLcY,OLcbX,OLcbY;
+function OLloadDraggable(){OLload('draggable');}
+function OLparseDraggable(pf,i,ar){
+var k=i;
+if(k<ar.length){if(Math.abs(ar[k])==DRAGGABLE){OLtoggle(ar[k],pf+'draggable');return k;}}
+return -1;
+}
+
+function OLcheckDrag(){
+if(o3_draggable){if(o3_sticky&&(o3_frame==self))initDrag();else o3_draggable=0;}
+}
+function initDrag(){
+OLmMv=OLdw.onmousemove;o3_dragging=0;
+if(OLns4){document.captureEvents(Event.MOUSEDOWN|Event.CLICK);
+document.onmousedown=OLgrabEl;;document.onclick=function(e){return routeEvent(e);}}
+else{over.onmousedown=OLgrabEl;OLsetDrgCur(1);}
+}
+function OLsetDrgCur(d){if(!OLns4)over.style.cursor=(d?'move':'auto');}
+
+function OLgrabEl(e){
+var e=(e||event);
+var cKy=(OLns4?e.modifiers&Event.ALT_MASK:(!OLop7?e.altKey:e.ctrlKey));o3_dragging=1;
+if(cKy){OLsetDrgCur(0);document.onmouseup=function(){OLsetDrgCur(1);o3_dragging=0;}
+return(OLns4?routeEvent(e):true);}
+OLx=(e.pageX||e.clientX+OLfd().scrollLeft);OLy=(e.pageY||e.clientY+OLfd().scrollTop);
+if(OLie4)over.onselectstart=function(){return false;}
+if(OLns4){OLcX=OLx;OLcY=OLy;document.captureEvents(Event.MOUSEUP)}else{
+OLcX=OLx-(OLns4?over.left:parseInt(over.style.left));
+OLcY=OLy-(OLns4?over.top:parseInt(over.style.top));
+if((OLshadowPI)&&bkdrop&&o3_shadow){OLcbX=OLx-(parseInt(bkdrop.style.left));
+OLcbY=OLy-(parseInt(bkdrop.style.top));}}OLdw.onmousemove=OLmoveEl;
+document.onmouseup=function(){
+if(OLie4)over.onselectstart=null;o3_dragging=0;OLdw.onmousemove=OLmMv;}
+return(OLns4?routeEvent(e):false);
+}
+
+function OLmoveEl(e){
+var e=(e||event);
+OLx=(e.pageX||e.clientX+OLfd().scrollLeft);OLy=(e.pageY||e.clientY+OLfd().scrollTop);
+if(o3_dragging){if(OLns4){over.moveBy(OLx-OLcX,OLy-OLcY);
+if(OLshadowPI&&bkdrop&&o3_shadow)bkdrop.moveBy(OLx-OLcX,OLy-OLcY);}
+else{OLrepositionTo(over,OLx-OLcX,OLy-OLcY);
+if((OLiframePI)&&OLie55&&OLifsP1)OLrepositionTo(OLifsP1,OLx-OLcX,OLy-OLcY);
+if((OLshadowPI)&&bkdrop&&o3_shadow){OLrepositionTo(bkdrop,OLx-OLcbX,OLy-OLcbY);
+if((OLiframePI)&&OLie55&&OLifsSh)OLrepositionTo(OLifsSh,OLx-OLcbX,OLy-OLcbY);}}
+if(OLhidePI)OLhideUtil(0,1,1,0,0,0);}if(OLns4){OLcX=OLx;OLcY=OLy;}
+return false;
+}
+
+function OLclearDrag(){
+if(OLns4){document.releaseEvents(Event.MOUSEDOWN|Event.MOUSEUP|Event.CLICK);
+document.onmousedown=document.onclick=null;}else{over.onmousedown=null;OLsetDrgCur(0);}
+document.onmouseup=null;o3_dragging=0;
+}
+
+OLregRunTimeFunc(OLloadDraggable);
+OLregCmdLineFunc(OLparseDraggable);
+
+OLdraggablePI=1;
+OLloaded=1;
diff --git a/httemplate/elements/overlibmws_iframe.js b/httemplate/elements/overlibmws_iframe.js new file mode 100644 index 000000000..e3032f2ee --- /dev/null +++ b/httemplate/elements/overlibmws_iframe.js @@ -0,0 +1,93 @@ +/*
+ overlibmws_iframe.js plug-in module - Copyright Foteos Macrides 2003-2005
+ Masks system controls to prevent obscuring of popops for IE v5.5 or higher.
+ Initial: October 19, 2003 - Last Revised: May 15, 2005
+ See the Change History and Command Reference for overlibmws via:
+
+ http://www.macridesweb.com/oltest/
+
+ Published under an open source license: http://www.macridesweb.com/oltest/license.html
+*/
+
+OLloaded=0;
+
+var OLifsP1=null,OLifsSh=null,OLifsP2=null;
+
+// IFRAME SHIM SUPPORT FUNCTIONS
+function OLinitIfs(){
+if(!OLie55)return;
+if((OLovertwoPI)&&over2&&over==over2){
+var o=o3_frame.document.all['overIframeOvertwo'];
+if(!o||OLifsP2!=o){OLifsP2=null;OLgetIfsP2Ref();}return;}
+o=o3_frame.document.all['overIframe'];
+if(!o||OLifsP1!=o){OLifsP1=null;OLgetIfsRef();}
+if((OLshadowPI)&&o3_shadow){o=o3_frame.document.all['overIframeShadow'];
+if(!o||OLifsSh!=o){OLifsSh=null;OLgetIfsShRef();}}
+}
+
+function OLsetIfsRef(o,i,z){
+o.id=i;o.src='javascript:false;';o.scrolling='no';var os=o.style;
+os.position='absolute';os.top=0;os.left=0;os.width=1;os.height=1;os.visibility='hidden';
+os.zIndex=over.style.zIndex-z;os.filter='Alpha(style=0,opacity=0)';
+}
+
+function OLgetIfsRef(){
+if(OLifsP1||!OLie55)return;
+OLifsP1=o3_frame.document.createElement('iframe');
+OLsetIfsRef(OLifsP1,'overIframe',2);
+o3_frame.document.body.appendChild(OLifsP1);
+}
+
+function OLgetIfsShRef(){
+if(OLifsSh||!OLie55)return;
+OLifsSh=o3_frame.document.createElement('iframe');
+OLsetIfsRef(OLifsSh,'overIframeShadow',3);
+o3_frame.document.body.appendChild(OLifsSh);
+}
+
+function OLgetIfsP2Ref(){
+if(OLifsP2||!OLie55)return;
+OLifsP2=o3_frame.document.createElement('iframe');
+OLsetIfsRef(OLifsP2,'overIframeOvertwo',1);
+o3_frame.document.body.appendChild(OLifsP2);
+}
+
+function OLsetDispIfs(o,w,h){
+var os=o.style;
+os.width=w+'px';os.height=h+'px';os.clip='rect(0px '+w+'px '+h+'px 0px)';
+o.filters.alpha.enabled=true;
+}
+
+function OLdispIfs(){
+if(!OLie55)return;
+var wd=over.offsetWidth,ht=over.offsetHeight;
+if(OLfilterPI&&o3_filter&&o3_filtershadow){wd+=5;ht+=5;}
+if((OLovertwoPI)&&over2&&over==over2){
+if(!OLifsP2)return;
+OLsetDispIfs(OLifsP2,wd,ht);return;}
+if(!OLifsP1)return;
+OLsetDispIfs(OLifsP1,wd,ht);
+if((!OLshadowPI)||!o3_shadow||!OLifsSh)return;
+OLsetDispIfs(OLifsSh,wd,ht);
+}
+
+function OLshowIfs(){
+if(OLifsP1){OLifsP1.style.visibility="visible";
+if((OLshadowPI)&&o3_shadow&&OLifsSh)OLifsSh.style.visibility="visible";}
+}
+
+function OLhideIfs(o){
+if(!OLie55||o!=over)return;
+if(OLifsP1)OLifsP1.style.visibility="hidden";
+if((OLshadowPI)&&o3_shadow&&OLifsSh)OLifsSh.style.visibility="hidden";
+}
+
+function OLrepositionIfs(X,Y){
+if(OLie55){if((OLovertwoPI)&&over2&&over==over2){
+if(OLifsP2)OLrepositionTo(OLifsP2,X,Y);}
+else{if(OLifsP1){OLrepositionTo(OLifsP1,X,Y);if((OLshadowPI)&&o3_shadow&&OLifsSh)
+OLrepositionTo(OLifsSh,X+o3_shadowx,Y+o3_shadowy);}}}
+}
+
+OLiframePI=1;
+OLloaded=1;
diff --git a/httemplate/elements/pager.html b/httemplate/elements/pager.html new file mode 100644 index 000000000..0510d327d --- /dev/null +++ b/httemplate/elements/pager.html @@ -0,0 +1,42 @@ +<% + + my %opt = @_; + + my $pager = ''; + if ( $opt{'total'} != $opt{'num_rows'} && $opt{'maxrecords'} ) { + unless ( $opt{'offset'} == 0 ) { + $cgi->param('offset', $opt{'offset'} - $opt{'maxrecords'}); +%> + + <A HREF="<%= $cgi->self_url %>"><B><FONT SIZE="+1">Previous</FONT></B></A> + +<% + } + my $page = 0; + for ( my $poff = 0; $poff < $opt{'total'}; $poff += $opt{'maxrecords'} ) { + $page++; + if ( $opt{'offset'} == $poff ) { +%> + + <FONT SIZE="+2"><%= $page %></FONT> + +<% + } else { + $cgi->param('offset', $poff); +%> + + <A HREF="<%= $cgi->self_url %>"><%= $page %></A> + +<% + } + } + unless ( $opt{'offset'} + $opt{'maxrecords'} > $opt{'total'} ) { + $cgi->param('offset', $opt{'offset'} + $opt{'maxrecords'}); +%> + + <A HREF="<%= $cgi->self_url %>"><B><FONT SIZE="+1">Next</FONT></B></A> + +<% + } + } +%> diff --git a/httemplate/elements/progress-init.html b/httemplate/elements/progress-init.html new file mode 100644 index 000000000..7844f5678 --- /dev/null +++ b/httemplate/elements/progress-init.html @@ -0,0 +1,81 @@ +<% + my( $formname, $fields, $action, $url_or_message, $key ) = @_; + $key = '' unless defined $key; + + my $url_or_message_link; + if ( ref($url_or_message) ) { #its a message or something + $url_or_message_link = + 'message='. uri_escape( $url_or_message->{'message'} ) + } else { + $url_or_message_link = "url=$url_or_message"; + } +%> + +<%= include('/elements/xmlhttp.html', + 'method' => 'POST', + 'url' => $action, + 'subs' => [ 'start_job' ], + ) +%> +<SCRIPT TYPE="text/javascript" SRC="../elements/overlibmws.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="../elements/overlibmws_iframe.js"></SCRIPT> +<SCRIPT TYPE="text/javascript"> +function OLiframeContent(src, width, height, name) { + return ('<iframe src="'+src+'" width="'+width+'" height="'+height+'"' + +(name?' name="'+name+'" id="'+name+'"':'')+' scrolling="auto">' + +'<div>[iframe not supported]</div></iframe>'); +} + +function <%=$key%>process () { + + //alert('<%=$key%>process for form <%=$formname%>'); + + document.<%=$formname%>.submit.disabled=true; + + overlib( 'Submitting job to server...', WIDTH, 432, HEIGHT, 136, CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', CLOSECLICK, MIDX, 0, MIDY, 0 ); + + var Hash = new Array(); + var x = 0; + var fieldName; + for (var i = 0; i<document.<%=$formname%>.elements.length; i++) { + field = document.<%=$formname%>.elements[i]; + if ( <%= join(' || ', map { "(field.name.indexOf('$_') > -1)" } @$fields ) %> + ) + { + if ( field.type == 'select-multiple' ) { + //alert('select-multiple ' + field.name); + for (var j=0; j < field.options.length; j++) { + if ( field.options[j].selected ) { + //alert(field.name + ' => ' + field.options[j].value); + Hash[x++] = field.name; + Hash[x++] = field.options[j].value; + } + } + } else if ( ( field.type != 'radio' && field.type != 'checkbox' ) + || ( ( field.type == 'radio' || field.type == 'checkbox' ) + && document.<%=$formname%>.elements[i].checked + ) + ) + { + Hash[x++] = field.name; + Hash[x++] = field.value; + } + } + } + + // jsrsPOST = true; + // jsrsExecute( '<%= $action %>', <%=$key%>myCallback, 'start_job', Hash ); + + //alert('start_job( ' + Hash + ', <%=$key%>myCallback )' ); + //alert('start_job()' ); + start_job( Hash, <%=$key%>myCallback ); + +} + +function <%=$key%>myCallback( jobnum ) { + + overlib( OLiframeContent('<%=$p%>elements/progress-popup.html?jobnum=' + jobnum + ';<%=$url_or_message_link%>;formname=<%=$formname%>' , 432, 136, 'progress_popup'), CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', CLOSECLICK, MIDX, 0, MIDY, 0 ); + +} + +</SCRIPT> diff --git a/httemplate/elements/progress-popup.html b/httemplate/elements/progress-popup.html new file mode 100644 index 000000000..200f97d9b --- /dev/null +++ b/httemplate/elements/progress-popup.html @@ -0,0 +1,96 @@ +<% + my $jobnum = $cgi->param('jobnum'); + my $url = $cgi->param('url'); + my $message = $cgi->param('message'); + my $formname = scalar($cgi->param('formname')); +%> +<HTML> + <HEAD> + <TITLE></TITLE> + </HEAD> + <BODY BGCOLOR="#ccccff" onLoad="refreshStatus()"> + +<%= include('/elements/xmlhttp.html', + 'url' => $p.'elements/jsrsServer.html', + 'subs' => [ 'job_status' ], + ) +%> +<SCRIPT TYPE="text/javascript" src="../elements/qlib/control.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" src="../elements/qlib/imagelist.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" src="../elements/qlib/progress.js"></SCRIPT> +<SCRIPT TYPE="text/javascript"> +function refreshStatus () { + //jsrsExecute( '<%=$p%>elements/jsrsServer.html', updateStatus, 'job_status', '<%= $jobnum %>' ); + + job_status( '<%= $jobnum %>', updateStatus ); +} +function updateStatus( status_statustext ) { + + //var Array = status_statustext.split("\n"); + var statusArray = eval('(' + status_statustext + ')'); + var status = statusArray[0]; + var statustext = statusArray[1]; + + //if ( status == 'progress' ) { + //IE workaround, no i have no idea why + if ( status.indexOf('progress') > -1 ) { + document.getElementById("progress_percent").innerHTML = statustext + '%'; + bar1.set(statustext); + bar1.update; + //jsrsExecute( '<%=$p%>elements/jsrsServer.html', updateStatus, 'job_status', '<%= $jobnum %>' ); + job_status( '<%= $jobnum %>', updateStatus ); + } else if ( status.indexOf('complete') > -1 ) { +<% if ( $message ) { %> + document.getElementById("progress_message").innerHTML = "<%= $message %>"; + document.getElementById("progress_bar").innerHTML = ''; + document.getElementById("progress_percent").innerHTML = '<INPUT TYPE="button" VALUE="OK" onClick="parent.nd(1);">'; + document.getElementById("progress_jobnum").innerHTML = ''; + parent.document.<%=$formname%>.submit.disabled=false; +<% } elsif ( $url ) { %> + window.top.location.href = '<%= $url %>'; +<% } else { %> + alert('job done but no url or message specified'); +<% } %> + } else if ( status.indexOf('error') > -1 ) { + document.getElementById("progress_message").innerHTML = '<FONT SIZE="+1" COLOR="#FF0000">Error: ' + statustext + '</FONT>'; + document.getElementById("progress_bar").innerHTML = ''; + document.getElementById("progress_percent").innerHTML = '<INPUT TYPE="button" VALUE="OK" onClick="parent.nd(1);">'; + document.getElementById("progress_jobnum").innerHTML = ''; + parent.document.<%=$formname%>.submit.disabled=false; + } else { + alert('XXX unknown status returned from server: ' + status); + } + +} +</SCRIPT> + + <TABLE> + <TR> + <TD ALIGN="center" ID="progress_message"> + Server processing job... + </TD> + </TR><TR> + <TD ALIGN="center" ID="progress_bar"> + <SCRIPT TYPE="text/javascript"> + // Create imagelist + SEGS = new QImageList(4, 23, "../images/progressbar-empty.png", "../images/progressbar-full.png"); + // Create bars + bar1 = new QProgress(null, "bar1", SEGS, 100); + // bar1.set(0); + // bar1.update; + </SCRIPT> + </TD> + </TR><TR> + <TD ALIGN="center"> + <DIV ID="progress_percent">%</DIV> + </TD> + </TR><TR> + <TD ALIGN="center" ID="progress_jobnum"> + (progress of job #<%= $jobnum %>) + </TD> + </TR> + </TABLE> + + </BODY> +</HTML> + diff --git a/httemplate/elements/qlib/box.js b/httemplate/elements/qlib/box.js new file mode 100644 index 000000000..537aac4c8 --- /dev/null +++ b/httemplate/elements/qlib/box.js @@ -0,0 +1,29 @@ +/**
+ * QLIB 1.0 Box Control
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * http://qlib.quazzle.com
+ */
+
+function QBox(parent, name, res, x, y, width, height, body, visible, effects, opacity, zindex) {
+ this.init(parent, name);
+ if (this.res = res) {
+ this.x = x - 0;
+ this.y = y - 0;
+ this.width = width - 0;
+ this.height = (typeof(height) == "number") ? height : null;
+ this.body = body || " ";
+ var j = QBox.arguments.length;
+ this.visible = (j > 8) ? visible : true;
+ this.effects = (j > 9) ? effects : (res.effects || 0);
+ this.opacity = (j > 10) ? opacity : (res.opacity != null ? res.opacity : 100);
+ this.zindex = (j > 11) ? zindex : null;
+ this.create();
+ } else {
+ this.document.write("invalid resource");
+ }
+}
+QBox.prototype = new QBoxCtrl();
diff --git a/httemplate/elements/qlib/boxctrl.js b/httemplate/elements/qlib/boxctrl.js new file mode 100644 index 000000000..417b204e4 --- /dev/null +++ b/httemplate/elements/qlib/boxctrl.js @@ -0,0 +1,48 @@ +/**
+ * QLIB 1.0 Box Abstraction
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * http://qlib.quazzle.com
+ */
+
+function QBoxCtrl_content() {
+ with (this) {
+ if (res) {
+ this.cwidth = width - res.L - res.R - 8;
+ this.cheight = height && (height - res.T - res.B - 8);
+ var ec = '"><table border="0" cellspacing="0" cellpadding="0"><tr><td></td></tr></table></td>';
+ document.write('<table class="qbox" border="0" cellspacing="0" cellpadding="0" width="' +
+ (width - 8) + (height != null ? '" height="' + (height - 8) : '') + '"><tr><td width="' +
+ res.L + '" height="' + res.T + '"><img src="' + res.TL.src + '" border="0" width="' +
+ res.L + '" height="' + res.T + '"></td><td width="' + cwidth + '" height="' + res.T +
+ '" background="' + res.TC.src + ec + '<td width="' + res.R + '" height="' + res.T +
+ '"><img src="' + res.TR.src + '" border="0" width="' + res.R + '" height="' + res.T +
+ '"></td></tr><tr><td width="' + res.L + (cheight != null ? '" height="' + cheight : '') +
+ '" background="' + res.ML.src + ec + '<td width="' + cwidth + '" bgcolor="' + res.bgcolor +
+ (cheight != null ? '" height="' + cheight : '') + (res.bgtile ? '" background="' +
+ res.bgtile.src : '') + '" align="left" valign="top" class="body" unselectable="on">');
+ if (typeof(body) == "function") {
+ this.body();
+ } else {
+ document.write(body);
+ }
+ document.write('</td><td width="' + res.R + (cheight != null ? '" height="' + cheight : '') +
+ '" background="' + res.MR.src + ec + '</tr><tr><td width="' + res.L + '" height="' + res.B +
+ '"><img src="' + res.BL.src + '" border="0" width="' + res.L + '" height="' + res.B +
+ '"></td><td width="' + cwidth + '" height="' + res.B + '" background="' + res.BC.src + ec +
+ '<td width="' + res.R + '" height="' + res.B + '"><img src="' + res.BR.src +
+ '" border="0" width="' + res.R + '" height="' + res.B + '"></td></tr></table><br>');
+ }
+ }
+}
+
+function QBoxCtrl() {
+ this.res = false;
+ this.body = " ";
+ this.cwidth = this.cheight = 0;
+ this.content = QBoxCtrl_content;
+}
+QBoxCtrl.prototype = new QWndCtrl();
diff --git a/httemplate/elements/qlib/boxres.js b/httemplate/elements/qlib/boxres.js new file mode 100644 index 000000000..087817211 --- /dev/null +++ b/httemplate/elements/qlib/boxres.js @@ -0,0 +1,42 @@ +/**
+ * QLIB 1.0 Box Resource
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * http://qlib.quazzle.com
+ */
+
+function QBoxRes(t, r, b, l, tc, tr, mr, br, bc, bl, ml, tl, bgcolor, bgtile, effects, opacity) {
+ var args = QBoxRes.arguments.length;
+ this.T = t;
+ this.R = r;
+ this.B = b;
+ this.L = l;
+ this.TC = new Image();
+ this.TC.src = tc;
+ this.TR = new Image(r, t);
+ this.TR.src = tr;
+ this.MR = new Image();
+ this.MR.src = mr;
+ this.BR = new Image(r, b);
+ this.BR.src = br;
+ this.BC = new Image();
+ this.BC.src = bc;
+ this.BL = new Image(l, b);
+ this.BL.src = bl;
+ this.ML = new Image();
+ this.ML.src = ml;
+ this.TL = new Image(l, t);
+ this.TL.src = tl;
+ this.bgcolor = bgcolor || "#FFFFFF";
+ if (bgtile) {
+ this.bgtile = new Image();
+ this.bgtile.src = bgtile;
+ } else {
+ this.bgtile = false;
+ }
+ this.effects = (args > 13) ? effects : null;
+ this.opacity = (args > 14) ? opacity : null;
+}
diff --git a/httemplate/elements/qlib/button.js b/httemplate/elements/qlib/button.js new file mode 100644 index 000000000..05247d5f8 --- /dev/null +++ b/httemplate/elements/qlib/button.js @@ -0,0 +1,74 @@ +/**
+ * QLIB 1.0 Button Control
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * http://qlib.quazzle.com
+ */
+
+function QButton_update() {
+ with (this) {
+ image.src = ((!enabled && res.imgD) || (value ? res.imgP : res.imgN)).src;
+ }
+}
+
+function QButton_doEvent() {
+ with (this) {
+ if (enabled) {
+ if (res.style == 1) {
+ this.value = value ? 0 : 1;
+ update();
+ }
+ onClick(value, tag);
+ }
+ }
+ return false;
+}
+
+function QButton_enable(state) {
+ this.enabled = state;
+ this.update();
+}
+
+function QButton_set(value) {
+ if (this.enabled) {
+ this.value = value ? 1 : 0;
+ this.update();
+ }
+ return true;
+}
+
+function QButton(parent, name, res, tooltip) {
+ this.init(parent, name);
+ if (res) {
+ this.res = res;
+ this.tip = tooltip || "";
+ this.enabled = true;
+ this.value = 0;
+ this.set = QButton_set;
+ this.enable = QButton_enable;
+ this.update = QButton_update;
+ this.doEvent = QButton_doEvent;
+ this.onClick = QControl.event;
+ with (this) {
+ document.write('<a href="#" hidefocus="true" unselectable="on"' +
+ (tip ? ' title="' + tip + '"' : '') + ' onClick="return ' + name +
+ '.doEvent()" onMouseOver="' + (res.style == 2 ? name + '.set(1);' : '') +
+ 'window.top.status=' + name + '.tip;return true" onMouseOut="' +
+ (!res.style || (res.style == 2) ? name + '.set();' : '') + 'window.top.status=\'\'"' +
+ (!res.style ? ' onMouseDown="return ' + name + '.set(1)" onMouseUp="return ' + name + '.set()"' : '') +
+ '><img class="qbutton" name="' + id + '" src="' + res.imgN.src + '" border="0" width="' +
+ res.width + '" height="' + res.height + '"></a>');
+ this.image = document.images[id] || new Image(1, 1);
+ }
+ } else {
+ this.document.write("invalid resource");
+ }
+}
+QButton.prototype = new QControl();
+QButton.NORMAL = 0;
+QButton.CHECKBOX = 1;
+QButton.WEB = 2;
+QButton.SIGNAL = 3;
diff --git a/httemplate/elements/qlib/buttonres.js b/httemplate/elements/qlib/buttonres.js new file mode 100644 index 000000000..97f6dfccc --- /dev/null +++ b/httemplate/elements/qlib/buttonres.js @@ -0,0 +1,23 @@ +/**
+ * QLIB 1.0 Button Resource
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * http://qlib.quazzle.com
+ */
+
+function QButtonRes(style, width, height, normal, pressed, disabled) {
+ this.style = style;
+ this.width = width;
+ this.height = height;
+ this.imgN = new Image(width, height);
+ this.imgN.src = normal;
+ this.imgP = new Image(width, height);
+ this.imgP.src = pressed;
+ if (disabled) {
+ this.imgD = new Image(width, height);
+ this.imgD.src = disabled;
+ }
+}
diff --git a/httemplate/elements/qlib/control.js b/httemplate/elements/qlib/control.js new file mode 100644 index 000000000..f50206e27 --- /dev/null +++ b/httemplate/elements/qlib/control.js @@ -0,0 +1,51 @@ +/**
+ * QLIB 1.0 Base Abstract Control
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * http://qlib.quazzle.com
+ */
+
+function QControl_init(parent, name) {
+ this.parent = parent || self;
+ this.window = (parent && parent.window) || self;
+ this.document = (parent && parent.document) || self.document;
+ this.name = (parent && parent.name) ? (parent.name + "." + name) : ("self." + name);
+ this.id = "Q";
+ var h = this.hash(this.name);
+ for (var j=0; j<8; j++) {
+ this.id += QControl.HEXTABLE.charAt(h & 15);
+ h >>>= 4;
+ }
+}
+
+function QControl_hash(str) {
+ var h = 0;
+ if (str) {
+ for (var j=str.length-1; j>=0; j--) {
+ h ^= QControl.ANTABLE.indexOf(str.charAt(j)) + 1;
+ for (var i=0; i<3; i++) {
+ var m = (h = h<<7 | h>>>25) & 150994944;
+ h ^= m ? (m == 150994944 ? 1 : 0) : 1;
+ }
+ }
+ }
+ return h;
+}
+
+function QControl_nop() {
+}
+
+function QControl() {
+ this.init = QControl_init;
+ this.hash = QControl_hash;
+ this.window = self;
+ this.document = self.document;
+ this.tag = null;
+}
+QControl.ANTABLE = "w5Q2KkFts3deLIPg8Nynu_JAUBZ9YxmH1XW47oDpa6lcjMRfi0CrhbGSOTvqzEV";
+QControl.HEXTABLE = "0123456789ABCDEF";
+QControl.nop = QControl_nop;
+QControl.event = QControl_nop;
diff --git a/httemplate/elements/qlib/counter.js b/httemplate/elements/qlib/counter.js new file mode 100644 index 000000000..72aeddbdb --- /dev/null +++ b/httemplate/elements/qlib/counter.js @@ -0,0 +1,81 @@ +/**
+ * QLIB 1.0 Animated Digital Counter
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * http://qlib.quazzle.com
+ */
+
+function QCounter_update() {
+ with (this) {
+ var v = Math.max(value, 0);
+ var mod;
+ for (var j=0; j<size; j++) {
+ mod = Math.floor(v % 10);
+ images[j].src = (v >= 1) || (!j) ? res.list[mod].src : res.list[10].src;
+ v /= 10;
+ }
+ }
+}
+
+function QCounter_count(value, step) {
+ this._cntt = false;
+ this.value += step;
+ if ((step * (this.value - value)) >= 0) {
+ this.value = value - 0; // convert to number
+ } else {
+ this._cntt = setTimeout(this.name + ".count(" + value + "," + step + ")", 50);
+ }
+ this.update();
+}
+
+function QCounter_set(value) {
+ this.setval = value;
+ if (value != this.value) {
+ if (this._cntt) {
+ clearTimeout(this._cntt);
+ this._cntt = false;
+ }
+ var dv = value - this.value;
+ if (this.effect == 2) {
+ dv = dv / Math.min(10, Math.abs(dv));
+ } else if (this.effect == 3) {
+ dv = dv / Math.abs(dv);
+ }
+ this.count(value, dv);
+ }
+}
+
+function QCounter(parent, name, res, size, effect) {
+ this.init(parent, name);
+ if (res) {
+ this.res = res;
+ this.setval = this.value = 0;
+ this.size = size || 4;
+ this.effect = effect || 2;
+ this._cntt = false;
+ this.images = new Array(this.size);
+ this.set = QCounter_set;
+ this.update = QCounter_update;
+ this.count = QCounter_count;
+ with (this) {
+ document.write('<table class="qcounter" width="' + (res.width * size) + '" height="' + res.height +
+ '" border="0" cellspacing="0" cellpadding="0" unselectable="on"><tr>');
+ for (var j=(size - 1); j>=0; j--) {
+ document.write('<td width="' + res.width + '" height="' + res.height +
+ '" unselectable="on"><img name="' + id + j + '" src="' + (j ? res.list[10].src : res.list[0].src) +
+ '" border="0" width="' + res.width + '" height="' + res.height + '"></td>');
+ images[j] = document.images[id + j] || new Image(1, 1);
+ }
+ document.write('</tr></table>');
+ }
+ } else {
+ this.document.write("invalid resource");
+ }
+}
+QCounter.prototype = new QControl();
+QCounter.INSTANT = 1;
+QCounter.FAST = 2;
+QCounter.SLOW = 3;
diff --git a/httemplate/elements/qlib/imagelist.js b/httemplate/elements/qlib/imagelist.js new file mode 100644 index 000000000..9f12de053 --- /dev/null +++ b/httemplate/elements/qlib/imagelist.js @@ -0,0 +1,25 @@ +/**
+ * QLIB 1.0 ImageList Resource
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * http://qlib.quazzle.com
+ */
+
+function QImageList(width, height) {
+ var len = QImageList.arguments.length - 2;
+ if (len > 0) {
+ this.list = new Array(len);
+ this.length = len;
+ this.width = width;
+ this.height = height;
+ var im;
+ for (var j=0; j<len; j++) {
+ im = new Image(width, height);
+ im.src = QImageList.arguments[j + 2];
+ this.list[j] = im;
+ }
+ }
+}
\ No newline at end of file diff --git a/httemplate/elements/qlib/label.js b/httemplate/elements/qlib/label.js new file mode 100644 index 000000000..2d8b1e710 --- /dev/null +++ b/httemplate/elements/qlib/label.js @@ -0,0 +1,72 @@ +/**
+ * QLIB 1.0 Text Label
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * http://qlib.quazzle.com
+ */
+
+function QLabel_set_ie(value) {
+ this.label.innerText = (this.value = value) || "\xA0";
+}
+
+function QLabel_set_dom2(value) {
+ with (this.label) {
+ replaceChild(this.document.createTextNode((this.value = value) || "\xA0"), firstChild);
+ }
+}
+
+function QLabel_set_ns4(value) {
+ this.value = value || "";
+ with (this) {
+ document.open();
+ document.write('<div class="qlabel">' + (clickable ? '<a href="#" title="' + tooltip + '" onClick="return ' +
+ name + '.doEvent()" onMouseOut="window.top.status=\'\'" onMouseOver="window.top.status=' + name +
+ '.tooltip;return true">' + value + '</a>' : value) + '</div>');
+ document.close();
+ }
+}
+
+function QLabel_doEvent() {
+ this.onClick(this.value, this.tag);
+ return false;
+}
+
+function QLabel(parent, name, value, clickable, tooltip) {
+ this.init(parent, name);
+ this.value = value || "";
+ this.clickable = clickable || false;
+ this.tooltip = tooltip || "";
+ this.doEvent = QLabel_doEvent;
+ this.onClick = QControl.event;
+ with (this) {
+ if (document.getElementById || document.all) {
+ document.write(clickable ? '<div class="qlabel" unselectable="on"><a id="' + id + '" href="#" title="' +
+ tooltip + '" onClick="return ' + name + '.doEvent()" onMouseOver="window.top.status=' + name +
+ '.tooltip;return true" onMouseOut="window.top.status=\'\'" hidefocus="true" unselectable="on">' +
+ (value || ' ') + '</a></div>' : '<div id="' + id + '" class="qlabel" unselectable="on">' +
+ (value || ' ') + '</div>');
+ this.label = document.getElementById ? document.getElementById(id) :
+ (document.all.item ? document.all.item(id) : document.all[id]);
+ this.set = (label && (label.innerText ? QLabel_set_ie :
+ (label.replaceChild && QLabel_set_dom2))) || QControl.nop;
+ } else if (document.layers) {
+ var suffix = "";
+ for (var j=value.length; j<QLabel.TEXTQUOTA; j++) suffix += " ";
+ document.write('<div><ilayer id="i' + id + '"><layer id="' + id + '"><div class="qlabel">' +
+ (clickable ? '<a href="#" title="' + tooltip + '" onClick="return ' + name +
+ '.doEvent()" onMouseOver="window.top.status=' + name +
+ '.tooltip;return true" onMouseOut="window.top.status=\'\'">' + value + suffix + '</a>' :
+ value + suffix) + '</div></layer></ilayer></div>');
+ this.label = (this.label = document.layers["i" + id]) && label.document.layers[id];
+ this.document = label && label.document;
+ this.set = (label && document) ? QLabel_set_ns4 : QControl.nop;
+ } else {
+ document.write("Object is not supported");
+ }
+ }
+}
+QLabel.prototype = new QControl();
+QLabel.TEXTQUOTA = 50;
diff --git a/httemplate/elements/qlib/messagebox.js b/httemplate/elements/qlib/messagebox.js new file mode 100644 index 000000000..2e458393d --- /dev/null +++ b/httemplate/elements/qlib/messagebox.js @@ -0,0 +1,57 @@ +/**
+ * QLIB 1.0 Message Box Control
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * http://qlib.quazzle.com
+ */
+
+function QMessageBox_alert(msg) {
+ if (typeof(msg) == "string") {
+ this.label.set(this.value = msg);
+ }
+ this.center();
+ this.focus();
+ this.show(true);
+}
+
+function QMessageBox_close() {
+ with (this.parent) {
+ if (!onClose(tag)) show(false);
+ }
+}
+
+function QMessageBox_body() {
+ with (this) {
+ document.write('<table border="0" width="' + cwidth + '"><tr><td align="left" valign="top" unselectable="on">');
+ this.label = new QLabel(this, "label", value);
+ document.write('</td></tr><tr><td height="' + (bres.height + 14) + '" align="center" valign="bottom" unselectable="on">');
+ this.button = new QButton(this, "button", bres, "Close");
+ document.write('</td></tr></table>');
+ button.onClick = QMessageBox_close;
+ }
+}
+
+function QMessageBox(parent, name, box, btn, msg, effects, opacity) {
+ this.init(parent, name);
+ if ((this.res = box) && (this.bres = btn)) {
+ this.value = typeof(msg) == "string" ? msg : "";
+ this.width = Math.max(200, Math.floor(Math.sqrt(555 * this.value.length)));
+ this.height = null;
+ this.x = this.y = 0;
+ this.visible = false;
+ this.zindex = null;
+ this.body = QMessageBox_body;
+ var j = QMessageBox.arguments.length;
+ this.effects = j > 5 ? effects : (box.effects != null ? box.effects : 0);
+ this.opacity = j > 6 ? opacity : (box.opacity != null ? box.opacity : 100);
+ this.create();
+ this.alert = QMessageBox_alert;
+ this.onClose = QControl.event;
+ } else {
+ this.document.write("invalid resource");
+ }
+}
+QMessageBox.prototype = new QBoxCtrl();
diff --git a/httemplate/elements/qlib/progress.js b/httemplate/elements/qlib/progress.js new file mode 100644 index 000000000..2de077eac --- /dev/null +++ b/httemplate/elements/qlib/progress.js @@ -0,0 +1,73 @@ +/**
+ * QLIB 1.0 Progress Control
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * http://qlib.quazzle.com
+ */
+
+function QProgress_update() {
+ with (this) {
+ var i = low;
+ for (var j=0; j<size; j++) {
+ images[j].src = i < value ? imgsrc1 : imgsrc0;
+ i += delta;
+ }
+ }
+}
+
+function QProgress_set(value) {
+ this.value = value - 0;
+ this.update();
+}
+
+function QProgress_setBounds(low, high) {
+ this.low = Math.min(low, high);
+ this.high = Math.max(low, high);
+ this.delta = (this.high - this.low) / this.size;
+ this.update();
+}
+
+function QProgress(parent, name, res, size, style) {
+ this.init(parent, name);
+ if (res) {
+ this.res = res;
+ this.value = 0;
+ this.low = 0;
+ this.high = 100;
+ this.size = size || 10;
+ this.delta = 100 / this.size;
+ this.style = style || 0;
+ this.images = new Array(this.size);
+ this.imgsrc0 = res.list[0] && res.list[0].src;
+ this.imgsrc1 = res.list[1] && res.list[1].src;
+ this.set = QProgress_set;
+ this.update = QProgress_update;
+ this.setBounds = QProgress_setBounds;
+ with (this) {
+ var hor = this.style < 2;
+ var rev = this.style % 2;
+ document.write('<table class="qprogress" border="0" cellspacing="0" cellpadding="0" unselectable="on" ' +
+ (hor ? 'width="' + (size * res.width) + '" height="' + res.height + '"><tr>' : 'width="' + res.width +
+ '" height="' + (size * res.height) + '">'));
+ for (var j=0; j<size; j++) {
+ document.write((hor ? '' : '<tr>') + '<td width="' + res.width + '" height="' + res.height +
+ '" unselectable="on"><img name="' + id + (rev ? size - j - 1 : j) + '" src="' + res.list[0].src +
+ '" border="0" width="' + res.width + '" height="' + res.height + '"></td>' + (hor ? '' : '</tr>'));
+ }
+ document.write((hor ? '</tr>' : '') + '</table>');
+ for (var j=0; j<size; j++) {
+ images[j] = document.images[id + j] || new Image(1, 1);
+ }
+ }
+ } else {
+ this.document.write("invalid resource");
+ }
+}
+QProgress.prototype = new QControl();
+QProgress.NORMAL = 0;
+QProgress.REVERSE = 1;
+QProgress.FALL = 2;
+QProgress.RISE = 3;
diff --git a/httemplate/elements/qlib/sound.js b/httemplate/elements/qlib/sound.js new file mode 100644 index 000000000..3d1aaf660 --- /dev/null +++ b/httemplate/elements/qlib/sound.js @@ -0,0 +1,47 @@ +/**
+ * QLIB 1.0 Preloaded Sound
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * http://qlib.quazzle.com
+ */
+
+function QSound_play(loop) {
+ this._out.loop = loop || 0;
+ this._out.src = this._buf.src;
+}
+
+function QSound_stop() {
+ this._out.loop = 0;
+ this._out.src = "";
+}
+
+function QSound_setVolume(volume) {
+ this._out.volume = this.volume = volume;
+}
+
+function QSound(parent, name, src, volume) {
+ this.init(parent, name);
+ this.volume = volume || 0;
+ this.play = this.stop = this.setVolume = QControl.nop;
+ with (this) {
+ document.write('<bgsound id="' + id + '" src="" volume="' + volume + '">');
+ if (document.all && document.all.item) {
+ this._out = document.all.item(id);
+ if (_out && (typeof _out.src != "undefined") && (_out.volume === volume)) {
+ document.write('<bgsound id="b' + id + '" src="' + src + '" volume="-10000">');
+ this._buf = document.all.item("b" + id);
+ if (_buf) {
+ this.play = QSound_play;
+ this.stop = QSound_stop;
+ this.setVolume = QSound_setVolume;
+
+ _out.onreadystatechange = new Function("alert(0)");
+ }
+ }
+ }
+ }
+}
+QSound.prototype = new QControl();
diff --git a/httemplate/elements/qlib/sprite.js b/httemplate/elements/qlib/sprite.js new file mode 100644 index 000000000..72a68fb7c --- /dev/null +++ b/httemplate/elements/qlib/sprite.js @@ -0,0 +1,125 @@ +/**
+ * QLIB 1.0 Sprite Object
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * http://qlib.quazzle.com
+ */
+
+function QSprite_load(src) {
+ if (src) {
+ this.face = new Image(this.cwidth, this.cheight);
+ this.face.src = src;
+ this.valid = false;
+ }
+}
+
+function QSprite_show(show) {
+ if (show && !this.valid && this.face.complete) {
+ this._img.src = this.face.src;
+ this.valid = true;
+ }
+ this._show(show);
+}
+
+function QSprite_moveTo(x, y) {
+ this.stop();
+ this._move(x, y);
+}
+
+function QSprite_slideTo(x, y) {
+ this.stop();
+ if (this.visible) {
+ this.doSlide(++this._spro, x, y);
+ } else {
+ this.moveTo(x, y);
+ }
+}
+
+function QSprite_shake() {
+ this.stop();
+ if (this.visible) {
+ this.doShake(++this._spro, 0, this.x, this.y);
+ }
+}
+
+function QSprite_stop() {
+ this._spro++;
+ if (this._sprt) {
+ clearTimeout(this._sprt);
+ this._sprt = false;
+ }
+}
+
+function QSprite_doSlide(id, x, y) {
+ if (this._spro == id) {
+ this._sprt = false;
+ var dx = Math.round(x - this.x);
+ var dy = Math.round(y - this.y);
+ if (dx || dy) {
+ if (dx) dx = dx > 0 ? Math.ceil(dx/4) : Math.floor(dx/4);
+ if (dy) dy = dy > 0 ? Math.ceil(dy/4) : Math.floor(dy/4);
+ this._move(this.x + dx, this.y + dy);
+ this._sprt = setTimeout(this.name + ".doSlide(" + id + "," + x + "," + y + ")", 30);
+ } else {
+ this._move(x, y);
+ }
+ }
+}
+
+function QSprite_doShake(id, phase, x, y) {
+ if (this._spro == id) {
+ this._sprt = false;
+ if (phase < 20) {
+ var m = 3 * Math.sin(.16 * phase);
+ this._move(x + m * Math.sin(phase), y + m * Math.cos(phase));
+ this._sprt = setTimeout(this.name + ".doShake(" + id + "," + (++phase) + "," + x + "," + y + ")", 20);
+ } else {
+ this._move(x, y);
+ }
+ }
+}
+
+function QSprite_doClick() {
+ if (!this._sprt) {
+ this.onClick(this.tag);
+ }
+ return false;
+}
+
+function QSprite(parent, name, x, y, width, height, src, visible, effects, opacity, zindex) {
+ this.init(parent, name);
+ this.x = x - 0;
+ this.y = y - 0;
+ this.width = (this.cwidth = width - 0) + 8;
+ this.height = (this.cheight = height - 0) + 8;
+ var j = QSprite.arguments.length;
+ this.visible = (j > 7) ? visible : true;
+ this.effects = (j > 8) ? effects : 0;
+ this.opacity = (j > 9) ? opacity : 100;
+ this.zindex = (j > 10) ? zindex : null;
+ this.valid = !!src;
+ this.content = '<a href="#" title="" onclick="return false" onmousedown="return ' + this.name +
+ '.doClick()" onmouseover="window.top.status=\'\';return true" hidefocus="true" unselectable="on"><img name="' +
+ this.id + '" src="' + (src || '') + '" border="0" width="' + this.cwidth + '" height="' + this.cheight +
+ '" alt="" unselectable="on"></a>';
+ this.doClick = QSprite_doClick;
+ this.doSlide = QSprite_doSlide;
+ this.doShake = QSprite_doShake;
+ this.onClick = QControl.event;
+ this.create();
+ this.face = this._img = this.document.images[this.id] || new Image(1, 1);
+ this._spro = 0;
+ this._sprt = false;
+ this._show = this.show;
+ this._move = this.moveTo;
+ this.load = QSprite_load;
+ this.show = QSprite_show;
+ this.moveTo = QSprite_moveTo;
+ this.slideTo = QSprite_slideTo;
+ this.shake = QSprite_shake;
+ this.stop = QSprite_stop;
+}
+QSprite.prototype = new QWndCtrl();
diff --git a/httemplate/elements/qlib/window.js b/httemplate/elements/qlib/window.js new file mode 100644 index 000000000..6056fda9b --- /dev/null +++ b/httemplate/elements/qlib/window.js @@ -0,0 +1,25 @@ +/**
+ * QLIB 1.0 Window Control
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * http://qlib.quazzle.com
+ */
+
+function QWindow(parent, name, x, y, width, height, content, visible, effects, opacity, zindex) {
+ this.init(parent, name);
+ this.x = x - 0;
+ this.y = y - 0;
+ this.width = width - 0;
+ this.height = (typeof(height) == "number") ? height : null;
+ this.content = content;
+ var j = QWindow.arguments.length;
+ this.visible = (j > 7) ? visible : true;
+ this.effects = (j > 8) ? effects : 0;
+ this.opacity = (j > 9) ? opacity : 100;
+ this.zindex = (j > 10) ? zindex : null;
+ this.create();
+}
+QWindow.prototype = new QWndCtrl();
diff --git a/httemplate/elements/qlib/wndctrl.js b/httemplate/elements/qlib/wndctrl.js new file mode 100644 index 000000000..b3bde4e92 --- /dev/null +++ b/httemplate/elements/qlib/wndctrl.js @@ -0,0 +1,322 @@ +/**
+ * QLIB 1.0 Window Abstraction
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * http://qlib.quazzle.com
+ */
+
+function QWndCtrl_center_ie4() {
+ var b = this.document.body;
+ this.moveTo(b.scrollLeft + Math.max(0, Math.floor((b.clientWidth -
+ this.width) / 2)), b.scrollTop + 100);
+}
+
+function QWndCtrl_center_moz() {
+ this.moveTo(self.pageXOffset + Math.max(0, Math.floor((self.innerWidth -
+ this.width) / 2)), self.pageYOffset + 100);
+}
+
+function QWndCtrl_setEffects_ie4(fx) {
+ this.effects = fx;
+ with (this.wnd) {
+ filters[0].enabled = (fx & 256) != 0;
+ filters[1].enabled = (fx & 512) != 0;
+ filters[2].enabled = (fx & 1024) != 0;
+ filters[4].enabled = (fx & 2048) != 0;
+ }
+}
+
+function QWndCtrl_setEffects_moz(fx) {
+ this.effects = fx;
+}
+
+function QWndCtrl_setOpacity_ie4(op) {
+ this.opacity = Math.max(0, Math.min(100, Math.floor(op - 0)));
+ this.wnd.filters[3].opacity = this.opacity;
+ this.wnd.filters[3].enabled = (this.opacity < 100);
+}
+
+function QWndCtrl_setOpacity_moz(op) {
+ this.opacity = Math.max(0, Math.min(100, Math.floor(op - 0)));
+ this.wnd.style.MozOpacity = this.opacity + "%";
+}
+
+function QWndCtrl_setSize_css(w, h) {
+ this.wnd.style.width = (this.width = Math.floor(w - 0)) + "px";
+ this.wnd.style.height = typeof(h) == "number" ? (this.height = Math.floor(h)) + "px" : "auto";
+}
+
+function QWndCtrl_setSize_ns4(w, h) {
+ this.wnd.clip.width = this.width = Math.floor(w - 0);
+ if (typeof(h) == "number") {
+ this.wnd.clip.height = this.height = Math.floor(h);
+ }
+}
+
+function QWndCtrl_focus() {
+ this.setZIndex(QWndCtrl.TOPZINDEX++);
+}
+
+function QWndCtrl_setZIndex_css(z) {
+ this.wnd.style.zIndex = this.zindex = z || 0;
+}
+
+function QWndCtrl_setZIndex_ns4(z) {
+ this.wnd.zIndex = this.zindex = z || 0;
+}
+
+function QWndCtrl_moveTo_css(x, y) {
+ this.wnd.style.left = (this.x = Math.floor(x - 0)) + "px";
+ this.wnd.style.top = (this.y = Math.floor(y - 0)) + "px";
+}
+
+function QWndCtrl_moveTo_ns4(x, y) {
+ this.wnd.moveTo(this.x = Math.floor(x - 0), this.y = Math.floor(y - 0));
+}
+
+function QWndCtrl_fxhandler() {
+ this.fxhandler = QControl.nop;
+ this.onShow(this.visible, this.tag);
+}
+
+function QWndCtrl_show_ie4(show) {
+ if (this.visible != show) {
+ var fx = false;
+ switch (show ? this.effects & 15 : (this.effects & 240) >>> 4) {
+ case 1:
+ fx = this.wnd.filters[5];
+ break;
+ case 2:
+ (fx = this.wnd.filters[6]).transition = show ? 1 : 0;
+ break;
+ case 3:
+ (fx = this.wnd.filters[6]).transition = show ? 3 : 2;
+ break;
+ case 4:
+ (fx = this.wnd.filters[6]).transition = show ? 5 : 4;
+ break;
+ case 5:
+ (fx = this.wnd.filters[6]).transition = show ? 14 : 13;
+ break;
+ case 6:
+ (fx = this.wnd.filters[6]).transition = show ? 16 : 15;
+ break;
+ case 7:
+ (fx = this.wnd.filters[6]).transition = 12;
+ break;
+ case 8:
+ (fx = this.wnd.filters[6]).transition = 8;
+ break;
+ case 9:
+ (fx = this.wnd.filters[6]).transition = 9;
+ }
+ if (fx) {
+ fx.apply();
+ this.wnd.style.visibility = (this.visible = show) ? "visible" : "hidden";
+ this.fxhandler = QWndCtrl_fxhandler;
+ fx.play(0.3);
+ } else {
+ this.wnd.style.visibility = (this.visible = show) ? "visible" : "hidden";
+ this.onShow(show, this.tag);
+ }
+ }
+}
+
+function QWndCtrl_fade_moz(op, step) {
+ this._wndt = false;
+ if (step) {
+ op += step;
+ if ((op > 0) && (op < this.opacity)) {
+ this.wnd.style.MozOpacity = op + "%";
+ this._wndt = setTimeout(this.name + ".fade(" + op + "," + step + ")", 50);
+ } else {
+ if (op <= 0) {
+ this.wnd.style.visibility = "hidden";
+ this.visible = false;
+ }
+ this.wnd.style.MozOpacity = this.opacity + "%";
+ this.onShow(this.visible, this.tag);
+ }
+ }
+}
+
+function QWndCtrl_show_moz(show) {
+ if (this.visible != show) {
+ if (this._wndt) {
+ clearTimeout(this._wndt);
+ this._wndt = false;
+ }
+ var step = show ? ((this.effects & 15) == 1) && Math.floor(this.opacity / 5) :
+ ((this.effects & 240) == 16) && -Math.floor(this.opacity / 5);
+ if (step) {
+ if (this.visible) {
+ this.fade(this.opacity - 0, step);
+ } else {
+ this.wnd.style.MozOpacity = "0%";
+ this.wnd.style.visibility = "visible";
+ this.visible = true;
+ this.fade(0, step);
+ }
+ } else {
+ this.wnd.style.visibility = (this.visible = show) ? "visible" : "hidden";
+ this.onShow(show, this.tag);
+ }
+ }
+}
+
+function QWndCtrl_show_css(show) {
+ if (this.visible != show) {
+ this.wnd.style.visibility = (this.visible = show) ? "visible" : "hidden";
+ this.onShow(show, this.tag);
+ }
+}
+
+function QWndCtrl_show_ns4(show) {
+ if (this.visible != show) {
+ this.wnd.visibility = (this.visible = show) ? "show" : "hidden";
+ this.onShow(show, this.tag);
+ }
+}
+
+function QWndCtrl_create_dom2() {
+ with (this) {
+ this.fxhandler = QControl.nop;
+ var ie4 = document.body && document.body.filters;
+ var moz = document.body && document.body.style &&
+ typeof(document.body.style.MozOpacity) == "string";
+ document.write('<div unselectable="on" id="' + id +
+ (ie4 ? '" onfilterchange="' + name + '.fxhandler()': '') +
+ '" style="position:absolute;left:' + x + 'px;top:' + y +
+ 'px;width:' + width + (height != null ? 'px;height:' + height : '') +
+ 'px;visibility:' + (visible ? 'visible' : 'hidden') +
+ ';overflow:hidden' + (zindex ? ';z-index:' + zindex : '') +
+ (ie4 ? ';filter:Gray(enabled=' + (effects & 256 ? '1' : '0') +
+ ') Xray(enabled=' + (effects & 512 ? '1' : '0') +
+ ') Invert(enabled=' + (effects & 1024 ? '1' : '0') +
+ ') alpha(enabled=' + (opacity < 100 ? '1' : '0') + ',opacity=' + opacity +
+ ') shadow(enabled=' + (effects & 2048 ? '1' : '0') +
+ ',direction=135) BlendTrans(enabled=0) RevealTrans(enabled=0)' : '') +
+ (moz && (opacity < 100) ? ';-moz-opacity:' + opacity + '%' : '') +
+ '"><div unselectable="on" class="qwindow">');
+ if (typeof(content) == "function") {
+ this.content();
+ } else {
+ document.write(content);
+ }
+ document.write('</div></div>');
+ if (this.wnd = document.getElementById ? document.getElementById(id) :
+ (document.all.item ? document.all.item(id) : document.all[id])) {
+ if (wnd.style) {
+ ie4 = ie4 && wnd.filters;
+ moz = moz && typeof(wnd.style.MozOpacity) == "string";
+ this.moveTo = QWndCtrl_moveTo_css;
+ this.setZIndex = QWndCtrl_setZIndex_css;
+ this.focus = QWndCtrl_focus;
+ this.setSize = QWndCtrl_setSize_css;
+ this.show = ie4 ? QWndCtrl_show_ie4 : (moz ? QWndCtrl_show_moz : QWndCtrl_show_css);
+ this.fade = moz ? QWndCtrl_fade_moz : QControl.nop;
+ this.setOpacity = ie4 ? QWndCtrl_setOpacity_ie4 : (moz ? QWndCtrl_setOpacity_moz : QControl.nop);
+ this.setEffects = ie4 ? QWndCtrl_setEffects_ie4 : (moz ? QWndCtrl_setEffects_moz : QControl.nop);
+ this.center = self.innerWidth ? QWndCtrl_center_moz :
+ (document.body && document.body.clientWidth ? QWndCtrl_center_ie4 : QControl.nop);
+ }
+ }
+ }
+}
+
+function QWndCtrl_create_ns4(finalize) {
+ with (this) {
+ if (finalize) {
+ if (_wnde) {
+ parent.window.onload = _wnde;
+ parent.window.onload();
+ }
+ document.open();
+ document.write('<div class="qwindow">');
+ this.content();
+ document.write('</div>');
+ document.close();
+ } else {
+ document.write('<layer id="' + id + '" left="' + x + '" top="' + y +
+ '" width="' + width + '" visibility="' + (visible ? 'show' : 'hidden') +
+ (height != null ? '" height="' + height + '" clip="' + width + ',' + height : '') +
+ (zindex ? '" z-index="' + zindex : '') + (typeof(content) != "function" ?
+ '"><div class="qwindow">' + content + '</div></layer>' : '"> </layer>'));
+ if (this.window = this.wnd = document.layers[id]) {
+ if (this.document = wnd.document) {
+ this.show = QWndCtrl_show_ns4;
+ this.moveTo = QWndCtrl_moveTo_ns4;
+ this.setZIndex = QWndCtrl_setZIndex_ns4;
+ this.focus = QWndCtrl_focus;
+ this.center = QWndCtrl_center_moz;
+ this.setSize = QWndCtrl_setSize_ns4;
+ if (typeof(content) == "function") {
+ this._wnde = parent.window.onload;
+ parent.window.onload = new Function(name + ".create(true)");
+ }
+ }
+ }
+ }
+ }
+}
+
+function QWndCtrl_create_na() {
+ this.document.write('Object is not supported.');
+ this.wnd = null;
+}
+
+function QWndCtrl_create() {
+ with (this) {
+ this.create = (document.getElementById || document.all) ? QWndCtrl_create_dom2 :
+ (document.layers ? QWndCtrl_create_ns4 : QWndCtrl_create_na);
+ create();
+ }
+}
+
+function QWndCtrl() {
+ this.x = this.y = 0;
+ this.width = this.height = 0;
+ this.content = "";
+ this.visible = true;
+ this.effects = 0;
+ this.opacity = 100;
+ this.zindex = null;
+ this._wndt = this._wnde = false;
+ this.create = QWndCtrl_create;
+ this.show = QControl.nop;
+ this.focus = QControl.nop;
+ this.center = QControl.nop;
+ this.moveTo = QControl.nop;
+ this.setSize = QControl.nop;
+ this.setOpacity = QControl.nop;
+ this.setEffects = QControl.nop;
+ this.setZIndex = QControl.nop;
+ this.onShow = QControl.event;
+}
+QWndCtrl.prototype = new QControl();
+QWndCtrl.TOPZINDEX = 1000;
+QWndCtrl.GRAY = 256;
+QWndCtrl.XRAY = 512;
+QWndCtrl.INVERT = 1024;
+QWndCtrl.SHADOW = 2048;
+QWndCtrl.FADEIN = 1;
+QWndCtrl.FADEOUT = 16;
+QWndCtrl.BOXIN = 2;
+QWndCtrl.BOXOUT = 32;
+QWndCtrl.CIRCLEIN = 3;
+QWndCtrl.CIRCLEOUT = 48;
+QWndCtrl.WIPEIN = 4;
+QWndCtrl.WIPEOUT = 64;
+QWndCtrl.HBARNIN = 5;
+QWndCtrl.HBARNOUT = 80;
+QWndCtrl.VBARNIN = 6;
+QWndCtrl.VBARNOUT = 96;
+QWndCtrl.DISSOLVEIN = 7;
+QWndCtrl.DISSOLVEOUT = 112;
+QWndCtrl.HBLINDSIN = 8;
+QWndCtrl.HBLINDSOUT = 128;
+QWndCtrl.VBLINDSIN = 9;
+QWndCtrl.VBLINDSOUT = 144;
diff --git a/httemplate/elements/select-agent.html b/httemplate/elements/select-agent.html new file mode 100644 index 000000000..c2a5e4bde --- /dev/null +++ b/httemplate/elements/select-agent.html @@ -0,0 +1,24 @@ +<% + my( $agentnum, %opt ) = @_; + + my @agents; + if ( $opt{'agents'} ) { + @agents = @{ $opt{'agents'} }; + } else { + @agents = qsearch( 'agent', { disabled=>'' } ); + } + +%> + +<SELECT NAME="agentnum"> + + <OPTION VALUE="">all</OPTION> + + <% foreach my $agent ( sort { $a->agent cmp $b->agent } @agents ) { %> + + <OPTION VALUE="<%= $agent->agentnum %>"<%= $agentnum == $agent->agentnum ? ' SELECTED' : '' %>><%= $agent->agent %> + + <% } %> + +</SELECT> + diff --git a/httemplate/elements/select-month_year.html b/httemplate/elements/select-month_year.html new file mode 100644 index 000000000..a0ea74ddd --- /dev/null +++ b/httemplate/elements/select-month_year.html @@ -0,0 +1,50 @@ +<% + + my %opt = @_; + + my $prefix = $opt{'prefix'} || ''; + my $disabled = $opt{'disabled'} || ''; + my $empty = $opt{'empty_option'} || ''; + my $date = $opt{'selected_date'} || ''; + $date = '' if $date eq '-'; + #$date ||= '01-2000' unless $empty; + my $start_year = $opt{'start_year'}; + my $end_year = $opt{'end_year'} || '2037'; + + my( $mon, $year ) = (0, 0); + if ( $date ) { + if ( $date =~ /^(\d{4})-(\d{1,2})-\d{1,2}$/ ) { #PostgreSQL date format + ( $mon, $year ) = ( $2, $1 ); + } elsif ( $date =~ /^(\d{1,2})-(\d{1,2}-)?(\d{4}$)/ ) { + ( $mon, $year ) = ( $1, $3 ); + } else { + die "unrecognized expiration date format: $date"; + } + } + + unless ( $start_year ) { + my @t = localtime; + $start_year = $t[5] + 1900; + } + $start_year = $year if $start_year > $year && $year > 0; + +%> + +<SELECT NAME="<%= $prefix %>_month" SIZE="1" <%= $disabled%>> + +<%= $empty ? '<OPTION VALUE="">' : '' %> + +<% for ( 1 .. 12 ) { %> + <OPTION<%= $_ == $mon ? ' SELECTED' : '' %> VALUE="<%= $_ %>"><%= $_ %> +<% } %> + +</SELECT>/<SELECT NAME="<%= $prefix %>_year" SIZE="1" <%= $disabled%>> + +<%= $empty ? '<OPTION VALUE="">' : '' %> + +<% for ( $start_year .. $end_year ) { %> + <OPTION<%= $_ == $year ? ' SELECTED' : '' %> VALUE="<%= $_ %>"><%= $_ %> +<% } %> + +</SELECT> + diff --git a/httemplate/elements/select-taxclass.html b/httemplate/elements/select-taxclass.html new file mode 100644 index 000000000..e5a1abba1 --- /dev/null +++ b/httemplate/elements/select-taxclass.html @@ -0,0 +1,42 @@ +<% + my $conf = new FS::Conf; + my $selected_taxclass = scalar(@_) ? shift : ''; +%> + +<% if ( $conf->exists('enable_taxclasses') ) { %> + + <SELECT NAME="taxclass"> + + <% if ( $conf->exists('require_taxclasses') ) { %> + + <OPTION VALUE="(select)">Select tax class + + <% } else { %> + + <OPTION VALUE=""> + + <% } %> + + <% + my $sth = dbh->prepare('SELECT DISTINCT taxclass FROM cust_main_county') + or die dbh->errstr; + $sth->execute or die $sth->errstr; + my %taxclasses = map { $_->[0] => 1 } @{$sth->fetchall_arrayref}; + my @taxclasses = grep $_, keys %taxclasses; + %> + + <% foreach my $taxclass ( @taxclasses ) { %> + + <OPTION VALUE="<%= $taxclass %>"<%= $taxclass eq $selected_taxclass ? ' SELECTED' : '' %>><%= $taxclass %> + + <% } %> + + </SELECT> + +<% } else { %> + + <INPUT TYPE="hidden" NAME="taxclass" VALUE="<%= $selected_taxclass %>"> + +<% } %> + + diff --git a/httemplate/elements/small_custview.html b/httemplate/elements/small_custview.html new file mode 100644 index 000000000..e0c22e0c4 --- /dev/null +++ b/httemplate/elements/small_custview.html @@ -0,0 +1,2 @@ +<% my $conf = new FS::Conf; %> +<%= small_custview( shift, shift || scalar($conf->config('countrydefault')), @_ ) %> diff --git a/httemplate/elements/table-grid.html b/httemplate/elements/table-grid.html new file mode 100644 index 000000000..80611f511 --- /dev/null +++ b/httemplate/elements/table-grid.html @@ -0,0 +1,8 @@ +<STYLE TYPE="text/css"> +.grid table { border: solid; empty-cells: show } +.grid TH { padding-left: 3px; padding-right: 3px; border: 1px solid #dddddd; border-bottom: dashed 1px black; border-right: none } +.grid TD { padding-left: 3px; padding-right: 3px; empty-cells: show; border: 1px solid #cccccc; border-bottom: none; border-right: none } +</STYLE> + +<TABLE CLASS="grid" CELLSPACING=0 CELLPADDING=0 BORDER=1 BORDERCOLOR="#000000" STYLE="border: solid 1px black; empty-cells: show"> + diff --git a/httemplate/elements/table.html b/httemplate/elements/table.html new file mode 100644 index 000000000..3b6108719 --- /dev/null +++ b/httemplate/elements/table.html @@ -0,0 +1,8 @@ +<% + my $color = shift; + if ( $color ) { +%> + <TABLE BGCOLOR="<%= $color %>" BORDER=1 WIDTH="100%" CELLSPACING=0 CELLPADDING=2 BORDERCOLOR="#999999"> +<% } else { %> + <TABLE BORDER=1 CELLSPACING=0 CELLPADDING=2 BORDERCOLOR="#999999"> +<% } %> diff --git a/httemplate/elements/tr-input-beginning_ending.html b/httemplate/elements/tr-input-beginning_ending.html new file mode 100644 index 000000000..9fa936bca --- /dev/null +++ b/httemplate/elements/tr-input-beginning_ending.html @@ -0,0 +1,39 @@ +<LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2"> +<SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT> + + +<TR> + <TD ALIGN="right">From: </TD> + <TD><INPUT TYPE="text" NAME="beginning" ID="beginning_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="beginning_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD> +<SCRIPT TYPE="text/javascript"> + Calendar.setup({ + inputField: "beginning_text", + ifFormat: "%m/%d/%Y", + button: "beginning_button", + align: "BR" + }); +</SCRIPT> +</TR> + +<TR> + <TD ALIGN="right">To: </TD> + <TD><INPUT TYPE="text" NAME="ending" ID="ending_text" VALUE="" SIZE=11 MAXLENGTH=10> <IMG SRC="../images/calendar.png" ID="ending_button" STYLE="cursor: pointer" TITLE="Select date"><BR><i>m/d/y</i></TD> +<SCRIPT TYPE="text/javascript"> + Calendar.setup({ + inputField: "ending_text", + ifFormat: "%m/%d/%Y", + button: "ending_button", + align: "BR" + }); +</SCRIPT> +</TR> + +<TR> + <TD></TD> + <TD> + <FONT SIZE="-1">(leave one or both dates blank for an open-ended search)</FONT> + </TD> +</TR> + diff --git a/httemplate/elements/tr-select-agent.html b/httemplate/elements/tr-select-agent.html new file mode 100644 index 000000000..2227262b6 --- /dev/null +++ b/httemplate/elements/tr-select-agent.html @@ -0,0 +1,29 @@ +<% + my( $agentnum, %opt ) = @_; + + my @agents; + if ( $opt{'agents'} ) { + @agents = @{ $opt{'agents'} }; + } else { + @agents = qsearch( 'agent', { disabled=>'' } ); + } + +%> + +<% if ( scalar(@agents) == 1 ) { %> + + <INPUT TYPE="hidden" NAME="agentnum" VALUE="<%= $agents[0]->agentnum %>"> + +<% } else { %> + + <TR> + <TD ALIGN="right"><%= $opt{'label'} || 'Agent: ' %></TD> + <TD> + <%= include( '/elements/select-agent.html', $agentnum, + 'agents' => \@agents, + ) + %> + </TD> + </TR> + +<% } %> diff --git a/httemplate/elements/xmlhttp.html b/httemplate/elements/xmlhttp.html new file mode 100644 index 000000000..28130e501 --- /dev/null +++ b/httemplate/elements/xmlhttp.html @@ -0,0 +1,109 @@ +<% + my ( %opt ) = @_; + + my $url = $opt{'url'}; + my $method = exists($opt{'method'}) ? $opt{'method'} : 'GET'; + #my @subs = @{ $opt{'subs'}; + + $url .= ( ($url =~ /\?/) ? '&' : '?' ) + if $method eq 'GET'; + +%> + +<SCRIPT TYPE="text/javascript"> + + function rs_init_object() { + var A; + try { + A=new ActiveXObject("Msxml2.XMLHTTP"); + } catch (e) { + try { + A=new ActiveXObject("Microsoft.XMLHTTP"); + } catch (oc) { + A=null; + } + } + if(!A && typeof XMLHttpRequest != "undefined") + A = new XMLHttpRequest(); + if (!A) + alert("Can't create XMLHttpRequest object"); + return A; + + } + + <% foreach my $func ( @{$opt{'subs'}} ) { + + my $furl = $url; + $furl =~ s/\"/\\\\\"/; #javascript escape + + %> + + function <%=$func%>() { + // count args; build URL + var url = "<%=$furl%>"; + var a = <%=$func%>.arguments; + + var args; + var len; + var content = 'sub=<%= uri_escape($func) %>'; + if ( a && typeof a == 'object' && a[0].constructor == Array ) { + args = a[0]; + len = args.length + } else { + args = a; + len = args.length - 1; + } + for (var i = 0; i < len; i++) + content = content + "&arg=" + escape(args[i]); + content = content.replace( /[+]/g, '%2B'); // fix unescaped plus signs + + if ( '<%=$method%>' == 'GET' ) { + url = url + content; + } + + //alert('<%=$method%> ' + url); + + var xmlhttp = rs_init_object(); + xmlhttp.open("<%=$method%>", url, true); + + xmlhttp.onreadystatechange = function() { + if (xmlhttp.readyState != 4) + return; + + if (xmlhttp.status != 200) { + alert(xmlhttp.status + " status connecting to " + url); + } else { + var data = xmlhttp.responseText; + //alert('received response: ' + data); + a[a.length-1](data); + if ( data.indexOf("<b>System error</b>") > -1 ) { + var w; + if ( w = window.open("about:blank") ) { + w.document.write(data); + } else { + // popup blocking? should use an overlib popup instead + alert("Error popup disabled; try disabling popup blocking to see"); + } + } + } + } + + if ( '<%=$method%>' == 'POST' ) { + + xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + xmlhttp.send(content); + + } else { + + xmlhttp.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"); + xmlhttp.send(null); + + } + + //rs_debug("x_$func_name url = " + url); + //rs_debug("x_$func_name waiting.."); + } + + <% } %> + +</SCRIPT> |