rhmessaging commits: r3686 - mgmt/trunk/sesame/cpp/src.
by rhmessaging-commits@lists.jboss.org
Author: tedross
Date: 2009-10-30 13:59:46 -0400 (Fri, 30 Oct 2009)
New Revision: 3686
Modified:
mgmt/trunk/sesame/cpp/src/SysAgent.cpp
Log:
Periodically refresh the system-id information. This handles the case where
the hostname is changed while sesame is running.
Modified: mgmt/trunk/sesame/cpp/src/SysAgent.cpp
===================================================================
--- mgmt/trunk/sesame/cpp/src/SysAgent.cpp 2009-10-26 13:39:17 UTC (rev 3685)
+++ mgmt/trunk/sesame/cpp/src/SysAgent.cpp 2009-10-30 17:59:46 UTC (rev 3686)
@@ -57,14 +57,13 @@
uint32_t swapFree;
};
+ void setSystemId();
void getLoadAverage(LoadAverage& la);
void getMem(Mem& mem);
};
SysAgent::SysAgent(ManagementAgent* _agent, const string& uuidFile) : agent(_agent)
{
- std::string sysname, nodename, release, version, machine;
-
// obtain or establish the system-id
ifstream input(uuidFile.c_str());
if (input.good()) {
@@ -82,17 +81,7 @@
}
mgmtObject = new _qmf::Sysimage(agent, this, uuid);
- qpid::sys::SystemInfo::getSystemId (sysname,
- nodename,
- release,
- version,
- machine);
- mgmtObject->set_osName (sysname);
- mgmtObject->set_nodeName (nodename);
- mgmtObject->set_release (release);
- mgmtObject->set_version (version);
- mgmtObject->set_machine (machine);
-
+ setSystemId();
ifstream distro("/etc/redhat-release");
if (distro.good()) {
char text[256];
@@ -104,6 +93,18 @@
agent->addObject(mgmtObject, 1);
}
+void SysAgent::setSystemId()
+{
+ std::string sysname, nodename, release, version, machine;
+
+ qpid::sys::SystemInfo::getSystemId(sysname, nodename, release, version, machine);
+ mgmtObject->set_osName(sysname);
+ mgmtObject->set_nodeName(nodename);
+ mgmtObject->set_release(release);
+ mgmtObject->set_version(version);
+ mgmtObject->set_machine(machine);
+}
+
void SysAgent::getLoadAverage(LoadAverage& la)
{
ifstream input("/proc/loadavg");
@@ -160,6 +161,7 @@
mgmtObject->set_swapTotal(mem.swapTotal);
for (;;) {
+ setSystemId();
getLoadAverage(la);
getMem(mem);
mgmtObject->set_loadAverage1Min(la.load1Min);
@@ -170,6 +172,8 @@
mgmtObject->set_memFree(mem.memFree);
mgmtObject->set_swapFree(mem.swapFree);
+ mgmtObject->set_memTotal(mem.memTotal);
+ mgmtObject->set_swapTotal(mem.swapTotal);
::sleep(5);
}
}
15 years, 1 month
rhmessaging commits: r3685 - mgmt/trunk/wooly/python/wooly.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2009-10-26 09:39:17 -0400 (Mon, 26 Oct 2009)
New Revision: 3685
Modified:
mgmt/trunk/wooly/python/wooly/server.py
Log:
Trap and log exception occurring in python libraries when calculating modified since date/time
Modified: mgmt/trunk/wooly/python/wooly/server.py
===================================================================
--- mgmt/trunk/wooly/python/wooly/server.py 2009-10-23 17:49:21 UTC (rev 3684)
+++ mgmt/trunk/wooly/python/wooly/server.py 2009-10-26 13:39:17 UTC (rev 3685)
@@ -6,7 +6,10 @@
from wooly import *
from devel import DevelPage
from wsgiserver import CherryPyWSGIServer
+import logging
+log = logging.getLogger("wooly.server")
+
class WebServer(object):
http_date = "%a, %d %b %Y %H:%M:%S %Z"
http_date_gmt = "%a, %d %b %Y %H:%M:%S GMT"
@@ -71,10 +74,14 @@
modified = page.get_last_modified(session).replace(microsecond=0)
if ims:
- since = datetime(*strptime(str(ims), self.http_date)[0:6])
+ try:
+ since = datetime(*strptime(str(ims), self.http_date)[0:6])
- if modified <= since:
- return self.send_not_modified(response, headers, session)
+ if modified <= since:
+ return self.send_not_modified(response, headers, session)
+ except AttributeError:
+ log.error("Exception in If Modified Since. ims=%s" % str(ims))
+ pass
if modified:
when = modified.strftime(self.http_date_gmt)
15 years, 1 month
rhmessaging commits: r3684 - mgmt/trunk/cumin/python/cumin/grid.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2009-10-23 13:49:21 -0400 (Fri, 23 Oct 2009)
New Revision: 3684
Modified:
mgmt/trunk/cumin/python/cumin/grid/negotiator.py
mgmt/trunk/cumin/python/cumin/grid/negotiator.strings
Log:
Fix number of arguments mismatch for columns so Group quotas will show up.
Fix class name in style sheet.
Modified: mgmt/trunk/cumin/python/cumin/grid/negotiator.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/negotiator.py 2009-10-23 14:55:28 UTC (rev 3683)
+++ mgmt/trunk/cumin/python/cumin/grid/negotiator.py 2009-10-23 17:49:21 UTC (rev 3684)
@@ -223,7 +223,7 @@
return items
class ExpandColumn(ItemTableColumn):
- def render_title(self, session):
+ def render_title(self, session, *args):
return ""
def get_class_list(self, session):
@@ -236,7 +236,7 @@
return ""
class GroupColumn(ItemTableColumn):
- def render_title(self, session):
+ def render_title(self, session, *args):
return "Group"
def render_content(self, session, group):
Modified: mgmt/trunk/cumin/python/cumin/grid/negotiator.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/negotiator.strings 2009-10-23 14:55:28 UTC (rev 3683)
+++ mgmt/trunk/cumin/python/cumin/grid/negotiator.strings 2009-10-23 17:49:21 UTC (rev 3684)
@@ -16,7 +16,7 @@
left outer join negotiator_stats as c on c.id = n.stats_curr_id
{sql_where}
-[NegotiatorOverviewTab.css]
+[NegotiatorOverview.css]
div.GroupTable ul.actions {
display: inline;
}
15 years, 2 months
rhmessaging commits: r3683 - in mgmt/trunk/cumin: python/cumin/inventory and 1 other directories.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2009-10-23 10:55:28 -0400 (Fri, 23 Oct 2009)
New Revision: 3683
Modified:
mgmt/trunk/cumin/python/cumin/grid/pool.py
mgmt/trunk/cumin/python/cumin/grid/pool.strings
mgmt/trunk/cumin/python/cumin/grid/slot.py
mgmt/trunk/cumin/python/cumin/grid/slot.strings
mgmt/trunk/cumin/python/cumin/inventory/system.py
mgmt/trunk/cumin/python/cumin/inventory/system.strings
mgmt/trunk/cumin/resources/slots.swf
Log:
Added missing flash slot vis for Inventory-System-Statistics page.
Added javascript call from flash control to vis_loaded to signal that data was loaded so the control can be made visible.
Made sure popup tooltip for flash control does not draw off left side of control.
Modified: mgmt/trunk/cumin/python/cumin/grid/pool.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/pool.py 2009-10-22 16:50:27 UTC (rev 3682)
+++ mgmt/trunk/cumin/python/cumin/grid/pool.py 2009-10-23 14:55:28 UTC (rev 3683)
@@ -398,8 +398,6 @@
self.group_by = self.GroupBySwitch(app, "group_by")
self.add_child(self.group_by)
- self.activities = SlotActivities(app, "activities_legend")
- self.add_child(self.activities)
self.fullpageable = True
def render_slots_href(self, session):
Modified: mgmt/trunk/cumin/python/cumin/grid/pool.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/pool.strings 2009-10-22 16:50:27 UTC (rev 3682)
+++ mgmt/trunk/cumin/python/cumin/grid/pool.strings 2009-10-23 14:55:28 UTC (rev 3683)
@@ -36,7 +36,6 @@
{grid_stats}
</div>
<div class="col2">
- <h2>Slots</h2>
<div id="flashSlotMap">{slot_map}</div>
<div id="pngSlotMap">{slot_png}</div>
</div>
@@ -50,8 +49,14 @@
<div>{jobs_chart}</div>
<div>{submit_chart}</div>
+[PoolSlotFlashVis.css]
+div#PoolSlotFlashVis {
+ visibility: hidden;
+}
+
[PoolSlotFlashVis.html]
-<div>
+<div id="PoolSlotFlashVis">
+ <h2>Slots</h2>
<div class="StatValueChart {fullpageable}" id="{id}">
<h2>{title}</h2>
<div class="duration">{group_by}</div>
@@ -75,6 +80,11 @@
}
}
}
+ function vis_loaded(data) {
+ if (data == "1") {
+ $('PoolSlotFlashVis').style.visibility = "visible";
+ }
+ }
function vis_ready(vis) {
if (vis == "slots") {
var chart = cumin.getFlashChart("{id}");
@@ -132,9 +142,6 @@
fsm.style.display = "block";
var params = {menu: "false", scale: "noScale", allowFullscreen: "true", allowScriptAccess: "always", bgcolor: "#FFFFFF"};
- //var BackgroundGlass = document.getElementById('BackgroundGlass');
- //alert(BackgroundGlass);
-
swfobject.embedSWF("resource?name=slots.swf", "{id}_chart", "{slot_chart_width}", "{slot_chart_height}", "9.0.0", "", {vis:"slots"}, params);
swfobject.embedSWF("resource?name=slots.swf", "{id}ctrl_chart", "{slot_chart_width}", "{slot_ctrl_height}", "9.0.0", "", {vis:"ctrl"}, params);
Modified: mgmt/trunk/cumin/python/cumin/grid/slot.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/slot.py 2009-10-22 16:50:27 UTC (rev 3682)
+++ mgmt/trunk/cumin/python/cumin/grid/slot.py 2009-10-23 14:55:28 UTC (rev 3683)
@@ -257,26 +257,28 @@
root.slots = slot_count
root.vis = self.json.get(session)
root.activity_colors = self.interiors
- root.tree = self.treeify(records, range(slot_count), groups, 0)
+ leaves = True
+ if self.json.get(session) == "slots":
+ if slot_count > 1000:
+ leaves = False
+
+ root.tree = self.treeify(records, range(slot_count), groups, 0, leaves)
return "[%s]" % root.create()
- def treeify(self, records, plist, groups, level):
+ def treeify(self, records, plist, groups, level, leaves):
level_list = list()
# leaf
if level == len(groups):
- el = Element()
- el.name = "Slot"
- interiors = self.interiors.copy()
- interiors[None] = interiors["Unknown"]
- for i in sorted(plist, key=lambda x:records[x]["name"]):
- el = Element()
- el.job_id = records[i]["job_id"] and records[i]["job_id"] or ""
- el.activity = records[i]["activity"] and records[i]["activity"] or "Unknown"
- el.state = records[i]["state"] and records[i]["state"] or "Unknown"
- el.value = records[i]["name"] and records[i]["name"] or ""
- el.load_avg = records[i]["load_avg"] and round(records[i]["load_avg"], 2) or 0
- el.name = "slot"
- level_list.append(el)
+ if leaves:
+ for i in sorted(plist, key=lambda x:records[x]["name"]):
+ el = Element()
+ el.job_id = records[i]["job_id"] and records[i]["job_id"] or ""
+ el.activity = records[i]["activity"] and records[i]["activity"] or "Unknown"
+ el.state = records[i]["state"] and records[i]["state"] or "Unknown"
+ el.value = records[i]["name"] and records[i]["name"] or ""
+ el.load_avg = records[i]["load_avg"] and round(records[i]["load_avg"], 2) or 0
+ el.name = "slot"
+ level_list.append(el)
return level_list
# not a leaf
@@ -289,8 +291,9 @@
el.slots = len(level_dict[key])
el.level = level
if level < len(groups):
- el.tree = self.treeify(records, level_dict[key], groups, level + 1)
+ el.tree = self.treeify(records, level_dict[key], groups, level + 1, leaves)
level_list.append(el)
+
return level_list
def get_cached(self, session, zl):
Modified: mgmt/trunk/cumin/python/cumin/grid/slot.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/slot.strings 2009-10-22 16:50:27 UTC (rev 3682)
+++ mgmt/trunk/cumin/python/cumin/grid/slot.strings 2009-10-23 14:55:28 UTC (rev 3683)
@@ -1070,7 +1070,7 @@
[SlotMap.html]
<div id="slot_visualization" class="fullpageable">
- <h2>{title}</h2>
+ <h2>Slots</h2>
<div id="slot_controls">
<div id="zoom_text">Zoom</div><div id="zoom_levels"><div id="zoom_pos"></div></div><div style="clear:left;"><!-- --></div>
</div>
Modified: mgmt/trunk/cumin/python/cumin/inventory/system.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/inventory/system.py 2009-10-22 16:50:27 UTC (rev 3682)
+++ mgmt/trunk/cumin/python/cumin/inventory/system.py 2009-10-23 14:55:28 UTC (rev 3683)
@@ -9,6 +9,7 @@
from cumin.grid.slot import SlotFrame, SlotMap, SlotMapPage
from wooly import Session
+import main
strings = StringCatalog(__file__)
@@ -142,6 +143,9 @@
slots = SystemSlotMap(app, "system_slot_map", system)
self.add_child(slots)
+ slot_vis = SystemSlotFlashVis(app, "system_slot_flash", system)
+ self.add_child(slot_vis)
+
def render_title(self, session):
return "Statistics"
@@ -149,6 +153,55 @@
job = Identifiable("XXX")
return self.page.main.grid.pool.job.get_href(session, job, None)
+class SystemSlotMap(SlotMap):
+ def __init__(self, app, name, system):
+ super(SystemSlotMap, self).__init__(app, name)
+
+ self.system = system
+ self.slot_clip_size = 240
+
+ def do_process(self, session):
+ super(SystemSlotMap, self).do_process(session)
+
+ system = self.system.get(session)
+
+ self.slots.add_where_expr(session, "s.system = '%s'", system.nodeName)
+
+ def render_image_href(self, session):
+ system = self.system.get(session)
+
+ import main # XXX
+
+ page = main.module.system_slots_page
+ sess = Session(page)
+
+ page.system.set(sess, system)
+
+ return sess.marshal()
+
+ def get_scheduler_select(self, session):
+ system = self.system.get(session)
+ return "system='%s'" % system.nodeName
+
+class SystemSlotFlashVis(SystemSlotMap):
+ def render_slots_href(self, session):
+ system = self.system.get(session)
+
+ page = main.module.system_slots_page
+ sess = Session(page)
+
+ page.system.set(sess, system)
+ page.json.set(sess, "slots")
+ page.groups.set(sess, [])
+
+ return sess.marshal()
+
+ def render_slot_chart_width(self, session):
+ return 300
+
+ def render_slot_chart_height(self, session):
+ return 200
+
class SystemView(CuminView):
def __init__(self, app, name, system):
super(SystemView, self).__init__(app, name, system)
@@ -272,36 +325,6 @@
else:
return "Daemon"
-class SystemSlotMap(SlotMap):
- def __init__(self, app, name, system):
- super(SystemSlotMap, self).__init__(app, name)
-
- self.system = system
- self.slot_clip_size = 240
-
- def do_process(self, session):
- super(SystemSlotMap, self).do_process(session)
-
- system = self.system.get(session)
-
- self.slots.add_where_expr(session, "s.system = '%s'", system.nodeName)
-
- def render_image_href(self, session):
- system = self.system.get(session)
-
- import main # XXX
-
- page = main.module.system_slots_page
- sess = Session(page)
-
- page.system.set(sess, system)
-
- return sess.marshal()
-
- def get_scheduler_select(self, session):
- system = self.system.get(session)
- return "system='%s'" % system.nodeName
-
class SystemSlotMapPage(SlotMapPage):
def __init__(self, app, name):
self.system = SystemParameter(app, "id")
Modified: mgmt/trunk/cumin/python/cumin/inventory/system.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/inventory/system.strings 2009-10-22 16:50:27 UTC (rev 3682)
+++ mgmt/trunk/cumin/python/cumin/inventory/system.strings 2009-10-23 14:55:28 UTC (rev 3683)
@@ -54,8 +54,8 @@
<h2>Memory/Load</h2>
{stats}
<br/>
- <h2>Grid Slots</h2>
{system_slot_map}
+ {system_slot_flash}
</td>
<td>
{freemem}
@@ -78,3 +78,57 @@
[SystemServices.item_html]
<tr><th>{item_type}</th><td>{item_content}</td></tr>
+
+[SystemSlotFlashVis.css]
+div#SystemSlotFlashVis {
+ visibility: hidden;
+}
+
+[SystemSlotFlashVis.html]
+<div id="SystemSlotFlashVis">
+ <h2>Slots</h2>
+ <div class="StatValueChart" id="{id}">
+ <div id="{id}_chart"></div>
+ </div>
+</div>
+<script type="text/javascript">
+//<![CDATA[
+ function updateSystemSlotVis(id, loadType) {
+ var chart = cumin.getFlashChart(id);
+ if ((chart != null) && (typeof chart.src != "undefined")) {
+ if (typeof loadType != "undefined") {
+ if (typeof chart.reload != "undefined")
+ chart.reload(chart.src, false);
+ } else {
+ if (typeof chart.load != "undefined")
+ chart.load(chart.src, false);
+ else
+ wooly.log("load not definded for " + id);
+ }
+ }
+ }
+ function vis_loaded(data) {
+ if (data == "1") {
+ $('SystemSlotFlashVis').style.visibility = "visible";
+ }
+ }
+ function vis_ready(vis) {
+ if (vis == "slots") {
+ var chart = cumin.getFlashChart("{id}");
+ chart.src = "{slots_href}";
+ updateSystemSlotVis('{id}');
+ }
+ }
+ var flashversion = swfobject.getFlashPlayerVersion();
+ if (flashversion.major >= 9) {
+ var fsm = document.getElementById('flashSlotMap');
+ if (fsm)
+ fsm.style.display = "block";
+
+ var params = {menu: "false", scale: "noScale", allowFullscreen: "true", allowScriptAccess: "always", bgcolor: "#FFFFFF"};
+ swfobject.embedSWF("resource?name=slots.swf", "{id}_chart", "{slot_chart_width}", "{slot_chart_height}", "9.0.0", "", {vis:"slots"}, params);
+
+ wooly.addPageUpdateListener(function () { updateSystemSlotVis('{id}', "reload"); });
+ }
+//]]>
+</script>
Modified: mgmt/trunk/cumin/resources/slots.swf
===================================================================
(Binary files differ)
15 years, 2 months
rhmessaging commits: r3682 - in mgmt/trunk/cumin: python/cumin/grid and 1 other directories.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2009-10-22 12:50:27 -0400 (Thu, 22 Oct 2009)
New Revision: 3682
Modified:
mgmt/trunk/cumin/python/cumin/grid/negotiator.strings
mgmt/trunk/cumin/python/cumin/grid/pool.strings
mgmt/trunk/cumin/python/cumin/stat.strings
mgmt/trunk/cumin/resources/app.js
mgmt/trunk/cumin/resources/slots.swf
Log:
Added some error checking to the javascript for the flash charts to prevent flash methods from being called before the controls are properly initialized.
Modified: mgmt/trunk/cumin/python/cumin/grid/negotiator.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/negotiator.strings 2009-10-22 15:52:21 UTC (rev 3681)
+++ mgmt/trunk/cumin/python/cumin/grid/negotiator.strings 2009-10-22 16:50:27 UTC (rev 3682)
@@ -167,9 +167,12 @@
var chart = cumin.getFlashChart(priority_chart_id);
if (chart) {
- var obj = {'values': new_values};
- var myJson = JSON.encode(obj);
- chart.setpieslice(changedEl.id, myJson);
+ if (chart.setpieslice != "undefined") {
+ var obj = {'values': new_values};
+ var myJson = JSON.encode(obj);
+ chart.setpieslice(changedEl.id, myJson);
+ } else
+ wooly.log("setpieslice not defined for " + priority_chart_id);
}
}
}).set(initial_knob, false);
Modified: mgmt/trunk/cumin/python/cumin/grid/pool.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/pool.strings 2009-10-22 15:52:21 UTC (rev 3681)
+++ mgmt/trunk/cumin/python/cumin/grid/pool.strings 2009-10-22 16:50:27 UTC (rev 3682)
@@ -64,10 +64,15 @@
function updatePoolSlotVis(id, loadType) {
var chart = cumin.getFlashChart(id);
if ((chart != null) && (typeof chart.src != "undefined")) {
- if (typeof loadType != "undefined")
- chart.reload(chart.src, false);
- else
- chart.load(chart.src, false);
+ if (typeof loadType != "undefined") {
+ if (typeof chart.reload != "undefined")
+ chart.reload(chart.src, false);
+ } else {
+ if (typeof chart.load != "undefined")
+ chart.load(chart.src, false);
+ else
+ wooly.log("load not definded for " + id);
+ }
}
}
function vis_ready(vis) {
@@ -84,13 +89,19 @@
function vis_treemap_over(type, value) {
var chart = cumin.getFlashChart("{id}");
if (chart) {
- chart.highlight(type, value);
+ if (typeof chart.highlight != "undefined")
+ chart.highlight(type, value);
+ else
+ wooly.log("highlight not definded for " + id);
}
}
function vis_treemap_out(type, value) {
var chart = cumin.getFlashChart("{id}");
if (chart) {
- chart.lowlight(type, value);
+ if (typeof chart.lowlight != "undefined")
+ chart.lowlight(type, value);
+ else
+ wooly.log("lowlight not definded for " + id);
}
}
function slot_vis(state, a, id, href) {
@@ -119,9 +130,13 @@
var fsm = document.getElementById('flashSlotMap');
if (fsm)
fsm.style.display = "block";
+
+ var params = {menu: "false", scale: "noScale", allowFullscreen: "true", allowScriptAccess: "always", bgcolor: "#FFFFFF"};
+ //var BackgroundGlass = document.getElementById('BackgroundGlass');
+ //alert(BackgroundGlass);
- swfobject.embedSWF("resource?name=slots.swf", "{id}_chart", "{slot_chart_width}", "{slot_chart_height}", "9.0.0", "", {vis:"slots"});
- swfobject.embedSWF("resource?name=slots.swf", "{id}ctrl_chart", "{slot_chart_width}", "{slot_ctrl_height}", "9.0.0", "", {vis:"ctrl"});
+ swfobject.embedSWF("resource?name=slots.swf", "{id}_chart", "{slot_chart_width}", "{slot_chart_height}", "9.0.0", "", {vis:"slots"}, params);
+ swfobject.embedSWF("resource?name=slots.swf", "{id}ctrl_chart", "{slot_chart_width}", "{slot_ctrl_height}", "9.0.0", "", {vis:"ctrl"}, params);
wooly.addPageUpdateListener(function () { updatePoolSlotVis('{id}', "reload"); });
wooly.addPageUpdateListener(function () { updatePoolSlotVis('{id}ctrl', "reload"); });
Modified: mgmt/trunk/cumin/python/cumin/stat.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/stat.strings 2009-10-22 15:52:21 UTC (rev 3681)
+++ mgmt/trunk/cumin/python/cumin/stat.strings 2009-10-22 16:50:27 UTC (rev 3682)
@@ -233,7 +233,10 @@
setTimeout(function () {changeDuration(state, a, id, attempt+1);}, 1000);
return false;
}
- chart.geturl("got_chart_url", id, state);
+ if (typeof chart.geturl != "undefined")
+ chart.geturl("got_chart_url", id, state);
+ else
+ wooly.log("geturl not definded for " + id);
}
return false;
}
@@ -249,7 +252,10 @@
branch['duration'] = state;
url = branch.marshal();
- chart.reload(url, true);
+ if (typeof chart.reload != "undefined")
+ chart.reload(url, true);
+ else
+ wooly.log("reload not definded for " + id);
}
function gotChartPoints(text, oImg) {
Modified: mgmt/trunk/cumin/resources/app.js
===================================================================
--- mgmt/trunk/cumin/resources/app.js 2009-10-22 15:52:21 UTC (rev 3681)
+++ mgmt/trunk/cumin/resources/app.js 2009-10-22 16:50:27 UTC (rev 3682)
@@ -351,25 +351,17 @@
cumin.getFlashChart = function (id) {
var chart = $(id+"_chart");
- if (chart) {
- if (typeof chart.reload != "undefined")
- return chart;
- var pchart = $(id);
- var chart2 = pchart.getChildren(id+"_chart");
- if (navigator.appName.indexOf("Microsoft") != -1) {
- return window[id+"_chart"];
- } else {
- return document[id+"_chart"];
- }
- }
- return null;
+ return chart;
}
cumin.updateFlashChart = function (id) {
var chart = cumin.getFlashChart(id);
if (chart == null)
return false;
- chart.get_ymax(id)
+ if (typeof chart.get_ymax != "undefined")
+ chart.get_ymax(id)
+ else
+ wooly.log("get_ymax not definded for " + id);
}
/* called from .swf in response to chart.get_ymax() */
@@ -407,7 +399,10 @@
branch['vmax'] = vals_max;
href = branch.marshal();
- chart.reload(href, false);
+ if (typeof chart.reload != "undefined")
+ chart.reload(href, false);
+ else
+ wooly.log("reload not definded for " + id);
}
window.addEvent('domready',function () {
@@ -451,7 +446,10 @@
delete branch.elapsed;
href = branch.marshal();
- chart.reload(href, true);
+ if (typeof chart.reload != "undefined")
+ chart.reload(href, true);
+ else
+ wooly.log("reload not definded for " + id);
}
}
Modified: mgmt/trunk/cumin/resources/slots.swf
===================================================================
(Binary files differ)
15 years, 2 months
rhmessaging commits: r3681 - in store/trunk/java/bdbstore/src/tools/java/org/apache/qpid/server: store/berkeleydb and 1 other directories.
by rhmessaging-commits@lists.jboss.org
Author: ritchiem
Date: 2009-10-22 11:52:21 -0400 (Thu, 22 Oct 2009)
New Revision: 3681
Added:
store/trunk/java/bdbstore/src/tools/java/org/apache/qpid/server/util/
store/trunk/java/bdbstore/src/tools/java/org/apache/qpid/server/util/NullApplicationRegistry.java
Modified:
store/trunk/java/bdbstore/src/tools/java/org/apache/qpid/server/store/berkeleydb/BDBStoreUpgrade.java
Log:
Fixed a few NPE potentials and cleaned up the output of the StoreUpgrade script. Copied NAR from Apache as it has been made a Test only class.
Modified: store/trunk/java/bdbstore/src/tools/java/org/apache/qpid/server/store/berkeleydb/BDBStoreUpgrade.java
===================================================================
--- store/trunk/java/bdbstore/src/tools/java/org/apache/qpid/server/store/berkeleydb/BDBStoreUpgrade.java 2009-10-22 14:41:36 UTC (rev 3680)
+++ store/trunk/java/bdbstore/src/tools/java/org/apache/qpid/server/store/berkeleydb/BDBStoreUpgrade.java 2009-10-22 15:52:21 UTC (rev 3681)
@@ -139,18 +139,25 @@
{
if (_interactive)
{
- System.out.println("Upgrade destination: '" + toDir + "'");
+ if (toDir == null)
+ {
+ System.out.println("Upgrading in place:" + fromDir);
+ }
+ else
+ {
+ System.out.println("Upgrade destination: '" + toDir + "'");
+ }
if (userInteract("Upgrade destination exists do you wish to replace it?"))
{
if (!FileUtils.delete(_toDir, true))
{
- throw new IllegalArgumentException("Unable to remove upgrade destination '" + toDir + "'");
+ throw new IllegalArgumentException("Unable to remove upgrade destination '" + _toDir + "'");
}
}
else
{
- throw new IllegalArgumentException("Upgrade destination '" + toDir + "' already exists. ");
+ throw new IllegalArgumentException("Upgrade destination '" + _toDir + "' already exists. ");
}
}
else
@@ -159,19 +166,19 @@
{
if (!FileUtils.delete(_toDir, true))
{
- throw new IllegalArgumentException("Unable to remove upgrade destination '" + toDir + "'");
+ throw new IllegalArgumentException("Unable to remove upgrade destination '" + _toDir + "'");
}
}
else
{
- throw new IllegalArgumentException("Upgrade destination '" + toDir + "' already exists. ");
+ throw new IllegalArgumentException("Upgrade destination '" + _toDir + "' already exists. ");
}
}
}
if (!_toDir.mkdirs())
{
- throw new IllegalArgumentException("Upgrade destination '" + toDir + "' could not be created. "
+ throw new IllegalArgumentException("Upgrade destination '" + _toDir + "' could not be created. "
+ "Ensure the path is correct and that the permissions are correct.");
}
@@ -297,7 +304,7 @@
if (userInteract("Do you wish to perform a DB backup now? " +
"(Store will be backed up to '" + backup.getName() + "')"))
{
- performDBBackup(fromDir, backupDir, force);
+ performDBBackup(fromDir, backup, force);
}
else
{
@@ -682,23 +689,37 @@
boolean interactive = !_commandLine.hasOption(OPTION_QUIET_SHORT);
boolean force = _commandLine.hasOption(OPTION_FORCE_SHORT);
- for (File store : stores)
+ try{
+ for (File store : stores)
+ {
+
+ // if toDir is null then we are upgrading inplace so we don't need
+ // to provide an upgraded toDir when upgrading multiple stores.
+ if (toDir == null ||
+ // Check to see if we are upgrading a store specified in
+ // fromDir or if the directories are nested.
+ (stores.length > 0
+ && stores[0].toString().length() == fromDir.length()))
+ {
+ upgrade(store, toDir, backupDir, interactive, force);
+ }
+ else
+ {
+ // Add the extra part of path from store to the toDir
+ upgrade(store, toDir + File.separator + store.toString().substring(fromDir.length()), backupDir, interactive, force);
+ }
+ }
+ }
+ catch (RuntimeException re)
{
-
- // if toDir is null then we are upgrading inplace so we don't need
- // to provide an upgraded toDir when upgrading multiple stores.
- if (toDir == null ||
- // Check to see if we are upgrading a store specified in
- // fromDir or if the directories are nested.
- (stores.length > 0
- && stores[0].toString().length() == fromDir.length()))
+ if (!re.getMessage().equals("User aborted process"))
{
- upgrade(store, toDir, backupDir, interactive, force);
+ re.printStackTrace();
+ _logger.error("Upgrade Failed: " + re.getMessage());
}
else
{
- // Add the extra part of path from store to the toDir
- upgrade(store, toDir + File.separator + store.toString().substring(fromDir.length()), backupDir, interactive, force);
+ _logger.error("Upgrade stopped : User aborted");
}
}
@@ -748,10 +769,34 @@
{
_logger.error("Upgrade not started due to: " + iae.getMessage());
}
+ catch (DatabaseException de)
+ {
+ if (de.getMessage().endsWith("Error: Unable to load BDBStore as version 1. Store on disk contains version 2 data."))
+ {
+ System.out.println("Store '" + fromDir + "' has already been upgraded to version 2.");
+ }
+ else
+ {
+ de.printStackTrace();
+ _logger.error("Upgrade Failed: " + de.getMessage());
+ }
+ }
+ catch (RuntimeException re)
+ {
+ if (!re.getMessage().equals("User aborted process"))
+ {
+ re.printStackTrace();
+ _logger.error("Upgrade Failed: " + re.getMessage());
+ }
+ else
+ {
+ throw re;
+ }
+ }
catch (Exception e)
{
e.printStackTrace();
- _logger.error("Upgrade Failed: " + e.getMessage());
+ _logger.error("Upgrade Failed: " + e.getMessage());
}
}
Added: store/trunk/java/bdbstore/src/tools/java/org/apache/qpid/server/util/NullApplicationRegistry.java
===================================================================
--- store/trunk/java/bdbstore/src/tools/java/org/apache/qpid/server/util/NullApplicationRegistry.java (rev 0)
+++ store/trunk/java/bdbstore/src/tools/java/org/apache/qpid/server/util/NullApplicationRegistry.java 2009-10-22 15:52:21 UTC (rev 3681)
@@ -0,0 +1,117 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.util;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.logging.NullRootMessageLogger;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.BrokerActor;
+import org.apache.qpid.server.management.NoopManagedObjectRegistry;
+import org.apache.qpid.server.plugins.PluginManager;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.security.access.ACLManager;
+import org.apache.qpid.server.security.access.plugins.AllowAll;
+import org.apache.qpid.server.security.auth.database.PropertiesPrincipalDatabaseManager;
+import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Properties;
+import java.util.NoSuchElementException;
+
+public class NullApplicationRegistry extends ApplicationRegistry
+{
+ public NullApplicationRegistry() throws ConfigurationException
+ {
+ super(new ServerConfiguration(new PropertiesConfiguration()));
+ }
+
+ public void initialise(int instanceID) throws Exception
+ {
+ _logger.info("Initialising NullApplicationRegistry");
+
+ _rootMessageLogger = new NullRootMessageLogger();
+
+ //We should use a Test Actor Here not the Broker Actor
+ CurrentActor.set(new BrokerActor(_rootMessageLogger));
+
+ _configuration.setHousekeepingExpiredMessageCheckPeriod(200);
+
+ Properties users = new Properties();
+
+ users.put("guest", "guest");
+
+ _databaseManager = new PropertiesPrincipalDatabaseManager("default", users);
+
+ _accessManager = new ACLManager(_configuration.getSecurityConfiguration(), _pluginManager, AllowAll.FACTORY);
+
+ _authenticationManager = new PrincipalDatabaseAuthenticationManager(null, null);
+
+ _managedObjectRegistry = new NoopManagedObjectRegistry();
+ _virtualHostRegistry = new VirtualHostRegistry(this);
+ PropertiesConfiguration vhostProps = new PropertiesConfiguration();
+ VirtualHostConfiguration hostConfig = new VirtualHostConfiguration("test", vhostProps);
+ VirtualHost dummyHost = new VirtualHost(hostConfig);
+ _virtualHostRegistry.registerVirtualHost(dummyHost);
+ _virtualHostRegistry.setDefaultVirtualHostName("test");
+ _pluginManager = new PluginManager("");
+ _startup = new Exception("NAR");
+
+ }
+ private Exception _startup;
+ public Collection<String> getVirtualHostNames()
+ {
+ String[] hosts = {"test"};
+ return Arrays.asList(hosts);
+ }
+
+ @Override
+ public void close() throws Exception
+ {
+ CurrentActor.set(new BrokerActor(_rootMessageLogger));
+
+ try
+ {
+ super.close();
+ }
+ finally
+ {
+ try
+ {
+ CurrentActor.remove();
+ }
+ catch (NoSuchElementException npe)
+ {
+ _startup.printStackTrace();
+ _startup.printStackTrace(System.err);
+ }
+
+ }
+ }
+}
+
+
+
15 years, 2 months
rhmessaging commits: r3680 - store/trunk/cpp/lib.
by rhmessaging-commits@lists.jboss.org
Author: tedross
Date: 2009-10-22 10:41:36 -0400 (Thu, 22 Oct 2009)
New Revision: 3680
Modified:
store/trunk/cpp/lib/JournalImpl.cpp
store/trunk/cpp/lib/MessageStoreImpl.cpp
Log:
Close out the use of management objects at finalize time rather than
in the destructor. This ensures that there won't be invalid accesses
to freed heap during the destructor on broker shutdown.
Modified: store/trunk/cpp/lib/JournalImpl.cpp
===================================================================
--- store/trunk/cpp/lib/JournalImpl.cpp 2009-10-22 14:37:50 UTC (rev 3679)
+++ store/trunk/cpp/lib/JournalImpl.cpp 2009-10-22 14:41:36 UTC (rev 3680)
@@ -120,8 +120,10 @@
journalTimerPtr = 0;
}
- if (_mgmtObject != 0)
+ if (_mgmtObject != 0) {
_mgmtObject->resourceDestroy();
+ _mgmtObject = 0;
+ }
::pthread_mutex_destroy(&_getf_mutex);
log(LOG_DEBUG, "Destroyed");
@@ -491,6 +493,11 @@
{
(dynamic_cast<InactivityFireEvent*>(inactivityFireEventPtr.get()))->cancel();
jcntl::stop(block_till_aio_cmpl);
+
+ if (_mgmtObject != 0) {
+ _mgmtObject->resourceDestroy();
+ _mgmtObject = 0;
+ }
}
iores
Modified: store/trunk/cpp/lib/MessageStoreImpl.cpp
===================================================================
--- store/trunk/cpp/lib/MessageStoreImpl.cpp 2009-10-22 14:37:50 UTC (rev 3679)
+++ store/trunk/cpp/lib/MessageStoreImpl.cpp 2009-10-22 14:41:36 UTC (rev 3680)
@@ -366,6 +366,11 @@
JournalImpl* jQueue = i->second;
if (jQueue->is_ready()) jQueue->stop(true);
}
+
+ if (mgmtObject != 0) {
+ mgmtObject->resourceDestroy();
+ mgmtObject = 0;
+ }
}
void MessageStoreImpl::pushDown(const char* dirName, const char* bakDirName)
@@ -460,8 +465,10 @@
QPID_LOG(error, "Unknown error in MessageStoreImpl::~MessageStoreImpl()");
}
- if (mgmtObject != 0)
+ if (mgmtObject != 0) {
mgmtObject->resourceDestroy();
+ mgmtObject = 0;
+ }
}
void MessageStoreImpl::create(PersistableQueue& queue,
15 years, 2 months
rhmessaging commits: r3679 - in mgmt/trunk/wooly: resources and 1 other directory.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2009-10-22 10:37:50 -0400 (Thu, 22 Oct 2009)
New Revision: 3679
Modified:
mgmt/trunk/wooly/python/wooly/pages.strings
mgmt/trunk/wooly/resources/mootools.js
Log:
Combining mootools.js and mootools-more.js to prevent mootools-more.js from being loaded before mootools.js. This was causing an error and the page would render without and styles applied.
Modified: mgmt/trunk/wooly/python/wooly/pages.strings
===================================================================
--- mgmt/trunk/wooly/python/wooly/pages.strings 2009-10-22 14:27:01 UTC (rev 3678)
+++ mgmt/trunk/wooly/python/wooly/pages.strings 2009-10-22 14:37:50 UTC (rev 3679)
@@ -14,7 +14,6 @@
<!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="resource?name=ielte7.css"/><![endif]-->
<script type="text/javascript" src="resource?name=mootools.js"> </script>
- <script type="text/javascript" src="resource?name=mootools-more.js"> </script>
<script type="text/javascript" src="resource?name=wooly.js"> </script>
<script type="text/javascript" src="resource?name=app.js"> </script>
<script type="text/javascript" src="{base_name}.js"> </script>
Modified: mgmt/trunk/wooly/resources/mootools.js
===================================================================
--- mgmt/trunk/wooly/resources/mootools.js 2009-10-22 14:27:01 UTC (rev 3678)
+++ mgmt/trunk/wooly/resources/mootools.js 2009-10-22 14:37:50 UTC (rev 3679)
@@ -3902,4 +3902,3010 @@
return this;
}
+});
+
+//MooTools More, <http://mootools.net/more>. Copyright (c) 2006-2009 Aaron Newton <http://clientcide.com/>, Valerio Proietti <http://mad4milk.net> & the MooTools team <http://mootools.net/developers>, MIT Style License.
+
+MooTools.More = {
+ 'version': '1.2.3.1'
+};
+
+/*
+Script: MooTools.Lang.js
+ Provides methods for localization.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Aaron Newton
+*/
+
+(function(){
+
+ var data = {
+ language: 'en-US',
+ languages: {
+ 'en-US': {}
+ },
+ cascades: ['en-US']
+ };
+
+ var cascaded;
+
+ MooTools.lang = new Events();
+
+ $extend(MooTools.lang, {
+
+ setLanguage: function(lang){
+ if (!data.languages[lang]) return this;
+ data.language = lang;
+ this.load();
+ this.fireEvent('langChange', lang);
+ return this;
+ },
+
+ load: function() {
+ var langs = this.cascade(this.getCurrentLanguage());
+ cascaded = {};
+ $each(langs, function(set, setName){
+ cascaded[setName] = this.lambda(set);
+ }, this);
+ },
+
+ getCurrentLanguage: function(){
+ return data.language;
+ },
+
+ addLanguage: function(lang){
+ data.languages[lang] = data.languages[lang] || {};
+ return this;
+ },
+
+ cascade: function(lang){
+ var cascades = (data.languages[lang] || {}).cascades || [];
+ cascades.combine(data.cascades);
+ cascades.erase(lang).push(lang);
+ var langs = cascades.map(function(lng){
+ return data.languages[lng];
+ }, this);
+ return $merge.apply(this, langs);
+ },
+
+ lambda: function(set) {
+ (set || {}).get = function(key, args){
+ return $lambda(set[key]).apply(this, $splat(args));
+ };
+ return set;
+ },
+
+ get: function(set, key, args){
+ if (cascaded && cascaded[set]) return (key ? cascaded[set].get(key, args) : cascaded[set]);
+ },
+
+ set: function(lang, set, members){
+ this.addLanguage(lang);
+ langData = data.languages[lang];
+ if (!langData[set]) langData[set] = {};
+ $extend(langData[set], members);
+ if (lang == this.getCurrentLanguage()){
+ this.load();
+ this.fireEvent('langChange', lang);
+ }
+ return this;
+ },
+
+ list: function(){
+ return Hash.getKeys(data.languages);
+ }
+
+ });
+
+})();
+
+/*
+Script: Log.js
+ Provides basic logging functionality for plugins to implement.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Guillermo Rauch
+*/
+
+var Log = new Class({
+
+ log: function(){
+ Log.logger.call(this, arguments);
+ }
+
+});
+
+Log.logged = [];
+
+Log.logger = function(){
+ if(window.console && console.log) console.log.apply(console, arguments);
+ else Log.logged.push(arguments);
+};
+
+/*
+Script: Class.Binds.js
+ Automagically binds specified methods in a class to the instance of the class.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Aaron Newton
+*/
+
+Class.Mutators.Binds = function(binds){
+ return binds;
+};
+
+Class.Mutators.initialize = function(initialize){
+ return function(){
+ $splat(this.Binds).each(function(name){
+ var original = this[name];
+ if (original) this[name] = original.bind(this);
+ }, this);
+ return initialize.apply(this, arguments);
+ };
+};
+
+/*
+Script: Class.Occlude.js
+ Prevents a class from being applied to a DOM element twice.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Aaron Newton
+*/
+
+Class.Occlude = new Class({
+
+ occlude: function(property, element){
+ element = document.id(element || this.element);
+ var instance = element.retrieve(property || this.property);
+ if (instance && !$defined(this.occluded)){
+ this.occluded = instance;
+ } else {
+ this.occluded = false;
+ element.store(property || this.property, this);
+ }
+ return this.occluded;
+ }
+
+});
+
+/*
+Script: Date.js
+ Extends the Date native object to include methods useful in managing dates.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Aaron Newton
+ Nicholas Barthelemy - https://svn.nbarthelemy.com/date-js/
+ Harald Kirshner - mail [at] digitarald.de; http://digitarald.de
+ Scott Kyle - scott [at] appden.com; http://appden.com
+
+*/
+
+(function(){
+
+if (!Date.now) Date.now = $time;
+
+Date.Methods = {};
+
+['Date', 'Day', 'FullYear', 'Hours', 'Milliseconds', 'Minutes', 'Month', 'Seconds', 'Time', 'TimezoneOffset',
+ 'Week', 'Timezone', 'GMTOffset', 'DayOfYear', 'LastMonth', 'LastDayOfMonth', 'UTCDate', 'UTCDay', 'UTCFullYear',
+ 'AMPM', 'Ordinal', 'UTCHours', 'UTCMilliseconds', 'UTCMinutes', 'UTCMonth', 'UTCSeconds'].each(function(method){
+ Date.Methods[method.toLowerCase()] = method;
+});
+
+$each({
+ ms: 'Milliseconds',
+ year: 'FullYear',
+ min: 'Minutes',
+ mo: 'Month',
+ sec: 'Seconds',
+ hr: 'Hours'
+}, function(value, key){
+ Date.Methods[key] = value;
+});
+
+var zeroize = function(what, length){
+ return new Array(length - what.toString().length + 1).join('0') + what;
+};
+
+Date.implement({
+
+ set: function(prop, value){
+ switch ($type(prop)){
+ case 'object':
+ for (var p in prop) this.set(p, prop[p]);
+ break;
+ case 'string':
+ prop = prop.toLowerCase();
+ var m = Date.Methods;
+ if (m[prop]) this['set' + m[prop]](value);
+ }
+ return this;
+ },
+
+ get: function(prop){
+ prop = prop.toLowerCase();
+ var m = Date.Methods;
+ if (m[prop]) return this['get' + m[prop]]();
+ return null;
+ },
+
+ clone: function(){
+ return new Date(this.get('time'));
+ },
+
+ increment: function(interval, times){
+ interval = interval || 'day';
+ times = $pick(times, 1);
+
+ switch (interval){
+ case 'year':
+ return this.increment('month', times * 12);
+ case 'month':
+ var d = this.get('date');
+ this.set('date', 1).set('mo', this.get('mo') + times);
+ return this.set('date', d.min(this.get('lastdayofmonth')));
+ case 'week':
+ return this.increment('day', times * 7);
+ case 'day':
+ return this.set('date', this.get('date') + times);
+ }
+
+ if (!Date.units[interval]) throw new Error(interval + ' is not a supported interval');
+
+ return this.set('time', this.get('time') + times * Date.units[interval]());
+ },
+
+ decrement: function(interval, times){
+ return this.increment(interval, -1 * $pick(times, 1));
+ },
+
+ isLeapYear: function(){
+ return Date.isLeapYear(this.get('year'));
+ },
+
+ clearTime: function(){
+ return this.set({hr: 0, min: 0, sec: 0, ms: 0});
+ },
+
+ diff: function(d, resolution){
+ resolution = resolution || 'day';
+ if ($type(d) == 'string') d = Date.parse(d);
+
+ switch (resolution){
+ case 'year':
+ return d.get('year') - this.get('year');
+ case 'month':
+ var months = (d.get('year') - this.get('year')) * 12;
+ return months + d.get('mo') - this.get('mo');
+ default:
+ var diff = d.get('time') - this.get('time');
+ if (Date.units[resolution]() > diff.abs()) return 0;
+ return ((d.get('time') - this.get('time')) / Date.units[resolution]()).round();
+ }
+
+ return null;
+ },
+
+ getLastDayOfMonth: function(){
+ return Date.daysInMonth(this.get('mo'), this.get('year'));
+ },
+
+ getDayOfYear: function(){
+ return (Date.UTC(this.get('year'), this.get('mo'), this.get('date') + 1)
+ - Date.UTC(this.get('year'), 0, 1)) / Date.units.day();
+ },
+
+ getWeek: function(){
+ return (this.get('dayofyear') / 7).ceil();
+ },
+
+ getOrdinal: function(day){
+ return Date.getMsg('ordinal', day || this.get('date'));
+ },
+
+ getTimezone: function(){
+ return this.toString()
+ .replace(/^.*? ([A-Z]{3}).[0-9]{4}.*$/, '$1')
+ .replace(/^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, '$1$2$3');
+ },
+
+ getGMTOffset: function(){
+ var off = this.get('timezoneOffset');
+ return ((off > 0) ? '-' : '+') + zeroize((off.abs() / 60).floor(), 2) + zeroize(off % 60, 2);
+ },
+
+ setAMPM: function(ampm){
+ ampm = ampm.toUpperCase();
+ var hr = this.get('hr');
+ if (hr > 11 && ampm == 'AM') return this.decrement('hour', 12);
+ else if (hr < 12 && ampm == 'PM') return this.increment('hour', 12);
+ return this;
+ },
+
+ getAMPM: function(){
+ return (this.get('hr') < 12) ? 'AM' : 'PM';
+ },
+
+ parse: function(str){
+ this.set('time', Date.parse(str));
+ return this;
+ },
+
+ isValid: function(date) {
+ return !!(date || this).valueOf();
+ },
+
+ format: function(f){
+ if (!this.isValid()) return 'invalid date';
+ f = f || '%x %X';
+ f = formats[f.toLowerCase()] || f; // replace short-hand with actual format
+ var d = this;
+ return f.replace(/%([a-z%])/gi,
+ function($1, $2){
+ switch ($2){
+ case 'a': return Date.getMsg('days')[d.get('day')].substr(0, 3);
+ case 'A': return Date.getMsg('days')[d.get('day')];
+ case 'b': return Date.getMsg('months')[d.get('month')].substr(0, 3);
+ case 'B': return Date.getMsg('months')[d.get('month')];
+ case 'c': return d.toString();
+ case 'd': return zeroize(d.get('date'), 2);
+ case 'H': return zeroize(d.get('hr'), 2);
+ case 'I': return ((d.get('hr') % 12) || 12);
+ case 'j': return zeroize(d.get('dayofyear'), 3);
+ case 'm': return zeroize((d.get('mo') + 1), 2);
+ case 'M': return zeroize(d.get('min'), 2);
+ case 'o': return d.get('ordinal');
+ case 'p': return Date.getMsg(d.get('ampm'));
+ case 'S': return zeroize(d.get('seconds'), 2);
+ case 'U': return zeroize(d.get('week'), 2);
+ case 'w': return d.get('day');
+ case 'x': return d.format(Date.getMsg('shortDate'));
+ case 'X': return d.format(Date.getMsg('shortTime'));
+ case 'y': return d.get('year').toString().substr(2);
+ case 'Y': return d.get('year');
+ case 'T': return d.get('GMTOffset');
+ case 'Z': return d.get('Timezone');
+ }
+ return $2;
+ }
+ );
+ },
+
+ toISOString: function(){
+ return this.format('iso8601');
+ }
+
+});
+
+Date.alias('diff', 'compare');
+Date.alias('format', 'strftime');
+
+var formats = {
+ db: '%Y-%m-%d %H:%M:%S',
+ compact: '%Y%m%dT%H%M%S',
+ iso8601: '%Y-%m-%dT%H:%M:%S%T',
+ rfc822: '%a, %d %b %Y %H:%M:%S %Z',
+ 'short': '%d %b %H:%M',
+ 'long': '%B %d, %Y %H:%M'
+};
+
+var nativeParse = Date.parse;
+
+var parseWord = function(type, word, num){
+ var ret = -1;
+ var translated = Date.getMsg(type + 's');
+
+ switch ($type(word)){
+ case 'object':
+ ret = translated[word.get(type)];
+ break;
+ case 'number':
+ ret = translated[month - 1];
+ if (!ret) throw new Error('Invalid ' + type + ' index: ' + index);
+ break;
+ case 'string':
+ var match = translated.filter(function(name){
+ return this.test(name);
+ }, new RegExp('^' + word, 'i'));
+ if (!match.length) throw new Error('Invalid ' + type + ' string');
+ if (match.length > 1) throw new Error('Ambiguous ' + type);
+ ret = match[0];
+ }
+
+ return (num) ? translated.indexOf(ret) : ret;
+};
+
+
+Date.extend({
+
+ getMsg: function(key, args) {
+ return MooTools.lang.get('Date', key, args);
+ },
+
+ units: {
+ ms: $lambda(1),
+ second: $lambda(1000),
+ minute: $lambda(60000),
+ hour: $lambda(3600000),
+ day: $lambda(86400000),
+ week: $lambda(608400000),
+ month: function(month, year){
+ var d = new Date;
+ return Date.daysInMonth($pick(month, d.get('mo')), $pick(year, d.get('year'))) * 86400000;
+ },
+ year: function(year){
+ year = year || new Date().get('year');
+ return Date.isLeapYear(year) ? 31622400000 : 31536000000;
+ }
+ },
+
+ daysInMonth: function(month, year){
+ return [31, Date.isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
+ },
+
+ isLeapYear: function(year){
+ return new Date(year, 1, 29).get('date') == 29;
+ },
+
+ parse: function(from){
+ var t = $type(from);
+ if (t == 'number') return new Date(from);
+ if (t != 'string') return from;
+ from = from.clean();
+ if (!from.length) return null;
+
+ var parsed;
+ Date.parsePatterns.some(function(pattern){
+ var r = pattern.re.exec(from);
+ return (r) ? (parsed = pattern.handler(r)) : false;
+ });
+
+ return parsed || new Date(nativeParse(from));
+ },
+
+ parseDay: function(day, num){
+ return parseWord('day', day, num);
+ },
+
+ parseMonth: function(month, num){
+ return parseWord('month', month, num);
+ },
+
+ parseUTC: function(value){
+ var localDate = new Date(value);
+ var utcSeconds = Date.UTC(localDate.get('year'),
+ localDate.get('mo'),
+ localDate.get('date'),
+ localDate.get('hr'),
+ localDate.get('min'),
+ localDate.get('sec'));
+ return new Date(utcSeconds);
+ },
+
+ orderIndex: function(unit){
+ return Date.getMsg('dateOrder').indexOf(unit) + 1;
+ },
+
+ defineFormat: function(name, format){
+ formats[name] = format;
+ },
+
+ defineFormats: function(formats){
+ for (var name in formats) Date.defineFormat(name, formats[f]);
+ },
+
+ parsePatterns: [],
+
+ defineParser: function(pattern){
+ Date.parsePatterns.push( pattern.re && pattern.handler ? pattern : build(pattern) );
+ },
+
+ defineParsers: function(){
+ Array.flatten(arguments).each(Date.defineParser);
+ },
+
+ define2DigitYearStart: function(year){
+ yr_start = year % 100;
+ yr_base = year - yr_start;
+ }
+
+});
+
+var yr_base = 1900;
+var yr_start = 70;
+
+var replacers = function(key){
+ switch(key){
+ case 'x': // iso8601 covers yyyy-mm-dd, so just check if month is first
+ return (Date.orderIndex('month') == 1) ? '%m[.-/]%d([.-/]%y)?' : '%d[.-/]%m([.-/]%y)?';
+ case 'X':
+ return '%H([.:]%M)?([.:]%S([.:]%s)?)?\\s?%p?\\s?%T?';
+ case 'o':
+ return '[^\\d\\s]*';
+ }
+ return null;
+};
+
+var keys = {
+ a: /[a-z]{3,}/,
+ d: /[0-2]?[0-9]|3[01]/,
+ H: /[01]?[0-9]|2[0-3]/,
+ I: /0?[1-9]|1[0-2]/,
+ M: /[0-5]?\d/,
+ s: /\d+/,
+ p: /[ap]\.?m\.?/,
+ y: /\d{2}|\d{4}/,
+ Y: /\d{4}/,
+ T: /Z|[+-]\d{2}(?::?\d{2})?/
+};
+
+keys.B = keys.b = keys.A = keys.a;
+keys.m = keys.I;
+keys.S = keys.M;
+
+var lang;
+
+var build = function(format){
+ if (!lang) return {format: format}; // wait until language is set
+
+ var parsed = [null];
+
+ var re = (format.source || format) // allow format to be regex
+ .replace(/%([a-z])/gi,
+ function($1, $2){
+ return replacers($2) || $1;
+ }
+ ).replace(/\((?!\?)/g, '(?:') // make all groups non-capturing
+ .replace(/ (?!\?|\*)/g, ',? ') // be forgiving with spaces and commas
+ .replace(/%([a-z%])/gi,
+ function($1, $2){
+ var p = keys[$2];
+ if (!p) return $2;
+ parsed.push($2);
+ return '(' + p.source + ')';
+ }
+ );
+
+ return {
+ format: format,
+ re: new RegExp('^' + re + '$', 'i'),
+ handler: function(bits){
+ var date = new Date().clearTime();
+ for (var i = 1; i < parsed.length; i++)
+ date = handle.call(date, parsed[i], bits[i]);
+ return date;
+ }
+ };
+};
+
+var handle = function(key, value){
+ if (!value){
+ if (key == 'm' || key == 'd') value = 1;
+ else return this;
+ }
+
+ switch(key){
+ case 'a': case 'A': return this.set('day', Date.parseDay(value, true));
+ case 'b': case 'B': return this.set('mo', Date.parseMonth(value, true));
+ case 'd': return this.set('date', value);
+ case 'H': case 'I': return this.set('hr', value);
+ case 'm': return this.set('mo', value - 1);
+ case 'M': return this.set('min', value);
+ case 'p': return this.set('ampm', value.replace(/\./g, ''));
+ case 'S': return this.set('sec', value);
+ case 's': return this.set('ms', ('0.' + value) * 1000);
+ case 'w': return this.set('day', value);
+ case 'Y': return this.set('year', value);
+ case 'y':
+ value = +value;
+ if (value < 100) value += yr_base + (value < yr_start ? 100 : 0);
+ return this.set('year', value);
+ case 'T':
+ if (value == 'Z') value = '+00';
+ var offset = value.match(/([+-])(\d{2}):?(\d{2})?/);
+ offset = (offset[1] + '1') * (offset[2] * 60 + (+offset[3] || 0)) + this.getTimezoneOffset();
+ return this.set('time', (this * 1) - offset * 60000);
+ }
+
+ return this;
+};
+
+Date.defineParsers(
+ '%Y([-./]%m([-./]%d((T| )%X)?)?)?', // "1999-12-31", "1999-12-31 11:59pm", "1999-12-31 23:59:59", ISO8601
+ '%Y%m%d(T%H(%M%S?)?)?', // "19991231", "19991231T1159", compact
+ '%x( %X)?', // "12/31", "12.31.99", "12-31-1999", "12/31/2008 11:59 PM"
+ '%d%o( %b( %Y)?)?( %X)?', // "31st", "31st December", "31 Dec 1999", "31 Dec 1999 11:59pm"
+ '%b %d%o?( %Y)?( %X)?', // Same as above with month and day switched
+ '%b %Y' // "December 1999"
+);
+
+MooTools.lang.addEvent('langChange', function(language){
+ if (!MooTools.lang.get('Date')) return;
+
+ lang = language;
+ Date.parsePatterns.each(function(pattern, i){
+ if (pattern.format) Date.parsePatterns[i] = build(pattern.format);
+ });
+
+}).fireEvent('langChange', MooTools.lang.getCurrentLanguage());
+
+})();
+
+/*
+Script: Element.Forms.js
+ Extends the Element native object to include methods useful in managing inputs.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Aaron Newton
+
+*/
+
+Element.implement({
+
+ tidy: function(){
+ this.set('value', this.get('value').tidy());
+ },
+
+ getTextInRange: function(start, end){
+ return this.get('value').substring(start, end);
+ },
+
+ getSelectedText: function(){
+ if (this.setSelectionRange) return this.getTextInRange(this.getSelectionStart(), this.getSelectionEnd());
+ return document.selection.createRange().text;
+ },
+
+ getSelectedRange: function() {
+ if ($defined(this.selectionStart)) return {start: this.selectionStart, end: this.selectionEnd};
+ var pos = {start: 0, end: 0};
+ var range = this.getDocument().selection.createRange();
+ if (!range || range.parentElement() != this) return pos;
+ var dup = range.duplicate();
+ if (this.type == 'text') {
+ pos.start = 0 - dup.moveStart('character', -100000);
+ pos.end = pos.start + range.text.length;
+ } else {
+ var value = this.get('value');
+ var offset = value.length - value.match(/[\n\r]*$/)[0].length;
+ dup.moveToElementText(this);
+ dup.setEndPoint('StartToEnd', range);
+ pos.end = offset - dup.text.length;
+ dup.setEndPoint('StartToStart', range);
+ pos.start = offset - dup.text.length;
+ }
+ return pos;
+ },
+
+ getSelectionStart: function(){
+ return this.getSelectedRange().start;
+ },
+
+ getSelectionEnd: function(){
+ return this.getSelectedRange().end;
+ },
+
+ setCaretPosition: function(pos){
+ if (pos == 'end') pos = this.get('value').length;
+ this.selectRange(pos, pos);
+ return this;
+ },
+
+ getCaretPosition: function(){
+ return this.getSelectedRange().start;
+ },
+
+ selectRange: function(start, end){
+ if (this.setSelectionRange) {
+ this.focus();
+ this.setSelectionRange(start, end);
+ } else {
+ var value = this.get('value');
+ var diff = value.substr(start, end - start).replace(/\r/g, '').length;
+ start = value.substr(0, start).replace(/\r/g, '').length;
+ var range = this.createTextRange();
+ range.collapse(true);
+ range.moveEnd('character', start + diff);
+ range.moveStart('character', start);
+ range.select();
+ }
+ return this;
+ },
+
+ insertAtCursor: function(value, select){
+ var pos = this.getSelectedRange();
+ var text = this.get('value');
+ this.set('value', text.substring(0, pos.start) + value + text.substring(pos.end, text.length));
+ if ($pick(select, true)) this.selectRange(pos.start, pos.start + value.length);
+ else this.setCaretPosition(pos.start + value.length);
+ return this;
+ },
+
+ insertAroundCursor: function(options, select){
+ options = $extend({
+ before: '',
+ defaultMiddle: '',
+ after: ''
+ }, options);
+ var value = this.getSelectedText() || options.defaultMiddle;
+ var pos = this.getSelectedRange();
+ var text = this.get('value');
+ if (pos.start == pos.end){
+ this.set('value', text.substring(0, pos.start) + options.before + value + options.after + text.substring(pos.end, text.length));
+ this.selectRange(pos.start + options.before.length, pos.end + options.before.length + value.length);
+ } else {
+ var current = text.substring(pos.start, pos.end);
+ this.set('value', text.substring(0, pos.start) + options.before + current + options.after + text.substring(pos.end, text.length));
+ var selStart = pos.start + options.before.length;
+ if ($pick(select, true)) this.selectRange(selStart, selStart + current.length);
+ else this.setCaretPosition(selStart + text.length);
+ }
+ return this;
+ }
+
+});
+
+/*
+Script: Element.Measure.js
+ Extends the Element native object to include methods useful in measuring dimensions.
+
+ Element.measure / .expose methods by Daniel Steigerwald
+ License: MIT-style license.
+ Copyright: Copyright (c) 2008 Daniel Steigerwald, daniel.steigerwald.cz
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Aaron Newton
+
+*/
+
+Element.implement({
+
+ measure: function(fn){
+ var vis = function(el) {
+ return !!(!el || el.offsetHeight || el.offsetWidth);
+ };
+ if (vis(this)) return fn.apply(this);
+ var parent = this.getParent(),
+ toMeasure = [],
+ restorers = [];
+ while (!vis(parent) && parent != document.body) {
+ toMeasure.push(parent.expose());
+ parent = parent.getParent();
+ }
+ var restore = this.expose();
+ var result = fn.apply(this);
+ restore();
+ toMeasure.each(function(restore){
+ restore();
+ });
+ return result;
+ },
+
+ expose: function(){
+ if (this.getStyle('display') != 'none') return $empty;
+ var before = this.style.cssText;
+ this.setStyles({
+ display: 'block',
+ position: 'absolute',
+ visibility: 'hidden'
+ });
+ return function(){
+ this.style.cssText = before;
+ }.bind(this);
+ },
+
+ getDimensions: function(options){
+ options = $merge({computeSize: false},options);
+ var dim = {};
+ var getSize = function(el, options){
+ return (options.computeSize)?el.getComputedSize(options):el.getSize();
+ };
+ if (this.getStyle('display') == 'none'){
+ dim = this.measure(function(){
+ return getSize(this, options);
+ });
+ } else {
+ try { //safari sometimes crashes here, so catch it
+ dim = getSize(this, options);
+ }catch(e){}
+ }
+ return $chk(dim.x) ? $extend(dim, {width: dim.x, height: dim.y}) : $extend(dim, {x: dim.width, y: dim.height});
+ },
+
+ getComputedSize: function(options){
+ options = $merge({
+ styles: ['padding','border'],
+ plains: {
+ height: ['top','bottom'],
+ width: ['left','right']
+ },
+ mode: 'both'
+ }, options);
+ var size = {width: 0,height: 0};
+ switch (options.mode){
+ case 'vertical':
+ delete size.width;
+ delete options.plains.width;
+ break;
+ case 'horizontal':
+ delete size.height;
+ delete options.plains.height;
+ break;
+ }
+ var getStyles = [];
+ //this function might be useful in other places; perhaps it should be outside this function?
+ $each(options.plains, function(plain, key){
+ plain.each(function(edge){
+ options.styles.each(function(style){
+ getStyles.push((style == 'border') ? style + '-' + edge + '-' + 'width' : style + '-' + edge);
+ });
+ });
+ });
+ var styles = {};
+ getStyles.each(function(style){ styles[style] = this.getComputedStyle(style); }, this);
+ var subtracted = [];
+ $each(options.plains, function(plain, key){ //keys: width, height, plains: ['left', 'right'], ['top','bottom']
+ var capitalized = key.capitalize();
+ size['total' + capitalized] = 0;
+ size['computed' + capitalized] = 0;
+ plain.each(function(edge){ //top, left, right, bottom
+ size['computed' + edge.capitalize()] = 0;
+ getStyles.each(function(style, i){ //padding, border, etc.
+ //'padding-left'.test('left') size['totalWidth'] = size['width'] + [padding-left]
+ if (style.test(edge)){
+ styles[style] = styles[style].toInt() || 0; //styles['padding-left'] = 5;
+ size['total' + capitalized] = size['total' + capitalized] + styles[style];
+ size['computed' + edge.capitalize()] = size['computed' + edge.capitalize()] + styles[style];
+ }
+ //if width != width (so, padding-left, for instance), then subtract that from the total
+ if (style.test(edge) && key != style &&
+ (style.test('border') || style.test('padding')) && !subtracted.contains(style)){
+ subtracted.push(style);
+ size['computed' + capitalized] = size['computed' + capitalized]-styles[style];
+ }
+ });
+ });
+ });
+
+ ['Width', 'Height'].each(function(value){
+ var lower = value.toLowerCase();
+ if(!$chk(size[lower])) return;
+
+ size[lower] = size[lower] + this['offset' + value] + size['computed' + value];
+ size['total' + value] = size[lower] + size['total' + value];
+ delete size['computed' + value];
+ }, this);
+
+ return $extend(styles, size);
+ }
+
+});
+
+/*
+Script: Element.Pin.js
+ Extends the Element native object to include the pin method useful for fixed positioning for elements.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Aaron Newton
+*/
+
+(function(){
+ var supportsPositionFixed = false;
+ window.addEvent('domready', function(){
+ var test = new Element('div').setStyles({
+ position: 'fixed',
+ top: 0,
+ right: 0
+ }).inject(document.body);
+ supportsPositionFixed = (test.offsetTop === 0);
+ test.dispose();
+ });
+
+ Element.implement({
+
+ pin: function(enable){
+ if (this.getStyle('display') == 'none') return null;
+
+ var p;
+ if (enable !== false){
+ p = this.getPosition();
+ if (!this.retrieve('pinned')){
+ var pos = {
+ top: p.y - window.getScroll().y,
+ left: p.x - window.getScroll().x
+ };
+ if (supportsPositionFixed){
+ this.setStyle('position', 'fixed').setStyles(pos);
+ } else {
+ this.store('pinnedByJS', true);
+ this.setStyles({
+ position: 'absolute',
+ top: p.y,
+ left: p.x
+ });
+ this.store('scrollFixer', (function(){
+ if (this.retrieve('pinned'))
+ this.setStyles({
+ top: pos.top.toInt() + window.getScroll().y,
+ left: pos.left.toInt() + window.getScroll().x
+ });
+ }).bind(this));
+ window.addEvent('scroll', this.retrieve('scrollFixer'));
+ }
+ this.store('pinned', true);
+ }
+ } else {
+ var op;
+ if (!Browser.Engine.trident){
+ if (this.getParent().getComputedStyle('position') != 'static') op = this.getParent();
+ else op = this.getParent().getOffsetParent();
+ }
+ p = this.getPosition(op);
+ this.store('pinned', false);
+ var reposition;
+ if (supportsPositionFixed && !this.retrieve('pinnedByJS')){
+ reposition = {
+ top: p.y + window.getScroll().y,
+ left: p.x + window.getScroll().x
+ };
+ } else {
+ this.store('pinnedByJS', false);
+ window.removeEvent('scroll', this.retrieve('scrollFixer'));
+ reposition = {
+ top: p.y,
+ left: p.x
+ };
+ }
+ this.setStyles($merge(reposition, {position: 'absolute'}));
+ }
+ return this.addClass('isPinned');
+ },
+
+ unpin: function(){
+ return this.pin(false).removeClass('isPinned');
+ },
+
+ togglepin: function(){
+ this.pin(!this.retrieve('pinned'));
+ }
+
+ });
+
+})();
+
+/*
+Script: Element.Position.js
+ Extends the Element native object to include methods useful positioning elements relative to others.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Aaron Newton
+*/
+
+(function(){
+
+var original = Element.prototype.position;
+
+Element.implement({
+
+ position: function(options){
+ //call original position if the options are x/y values
+ if (options && ($defined(options.x) || $defined(options.y))) return original ? original.apply(this, arguments) : this;
+ $each(options||{}, function(v, k){ if (!$defined(v)) delete options[k]; });
+ options = $merge({
+ relativeTo: document.body,
+ position: {
+ x: 'center', //left, center, right
+ y: 'center' //top, center, bottom
+ },
+ edge: false,
+ offset: {x: 0, y: 0},
+ returnPos: false,
+ relFixedPosition: false,
+ ignoreMargins: false,
+ allowNegative: false
+ }, options);
+ //compute the offset of the parent positioned element if this element is in one
+ var parentOffset = {x: 0, y: 0};
+ var parentPositioned = false;
+ /* dollar around getOffsetParent should not be necessary, but as it does not return
+ * a mootools extended element in IE, an error occurs on the call to expose. See:
+ * http://mootools.lighthouseapp.com/projects/2706/tickets/333-element-getof... */
+ var offsetParent = this.measure(function(){
+ return document.id(this.getOffsetParent());
+ });
+ if (offsetParent && offsetParent != this.getDocument().body){
+ parentOffset = offsetParent.measure(function(){
+ return this.getPosition();
+ });
+ parentPositioned = true;
+ options.offset.x = options.offset.x - parentOffset.x;
+ options.offset.y = options.offset.y - parentOffset.y;
+ }
+ //upperRight, bottomRight, centerRight, upperLeft, bottomLeft, centerLeft
+ //topRight, topLeft, centerTop, centerBottom, center
+ var fixValue = function(option){
+ if ($type(option) != 'string') return option;
+ option = option.toLowerCase();
+ var val = {};
+ if (option.test('left')) val.x = 'left';
+ else if (option.test('right')) val.x = 'right';
+ else val.x = 'center';
+ if (option.test('upper') || option.test('top')) val.y = 'top';
+ else if (option.test('bottom')) val.y = 'bottom';
+ else val.y = 'center';
+ return val;
+ };
+ options.edge = fixValue(options.edge);
+ options.position = fixValue(options.position);
+ if (!options.edge){
+ if (options.position.x == 'center' && options.position.y == 'center') options.edge = {x:'center', y:'center'};
+ else options.edge = {x:'left', y:'top'};
+ }
+
+ this.setStyle('position', 'absolute');
+ var rel = document.id(options.relativeTo) || document.body;
+ var calc = rel == document.body ? window.getScroll() : rel.getPosition();
+ var top = calc.y;
+ var left = calc.x;
+
+ if (Browser.Engine.trident){
+ var scrolls = rel.getScrolls();
+ top += scrolls.y;
+ left += scrolls.x;
+ }
+
+ var dim = this.getDimensions({computeSize: true, styles:['padding', 'border','margin']});
+ if (options.ignoreMargins){
+ options.offset.x = options.offset.x - dim['margin-left'];
+ options.offset.y = options.offset.y - dim['margin-top'];
+ }
+ var pos = {};
+ var prefY = options.offset.y;
+ var prefX = options.offset.x;
+ var winSize = window.getSize();
+ switch(options.position.x){
+ case 'left':
+ pos.x = left + prefX;
+ break;
+ case 'right':
+ pos.x = left + prefX + rel.offsetWidth;
+ break;
+ default: //center
+ pos.x = left + ((rel == document.body ? winSize.x : rel.offsetWidth)/2) + prefX;
+ break;
+ }
+ switch(options.position.y){
+ case 'top':
+ pos.y = top + prefY;
+ break;
+ case 'bottom':
+ pos.y = top + prefY + rel.offsetHeight;
+ break;
+ default: //center
+ pos.y = top + ((rel == document.body ? winSize.y : rel.offsetHeight)/2) + prefY;
+ break;
+ }
+
+ if (options.edge){
+ var edgeOffset = {};
+
+ switch(options.edge.x){
+ case 'left':
+ edgeOffset.x = 0;
+ break;
+ case 'right':
+ edgeOffset.x = -dim.x-dim.computedRight-dim.computedLeft;
+ break;
+ default: //center
+ edgeOffset.x = -(dim.x/2);
+ break;
+ }
+ switch(options.edge.y){
+ case 'top':
+ edgeOffset.y = 0;
+ break;
+ case 'bottom':
+ edgeOffset.y = -dim.y-dim.computedTop-dim.computedBottom;
+ break;
+ default: //center
+ edgeOffset.y = -(dim.y/2);
+ break;
+ }
+ pos.x = pos.x + edgeOffset.x;
+ pos.y = pos.y + edgeOffset.y;
+ }
+ pos = {
+ left: ((pos.x >= 0 || parentPositioned || options.allowNegative) ? pos.x : 0).toInt(),
+ top: ((pos.y >= 0 || parentPositioned || options.allowNegative) ? pos.y : 0).toInt()
+ };
+ if (rel.getStyle('position') == 'fixed' || options.relFixedPosition){
+ var winScroll = window.getScroll();
+ pos.top = pos.top.toInt() + winScroll.y;
+ pos.left = pos.left.toInt() + winScroll.x;
+ }
+
+ if (options.returnPos) return pos;
+ else this.setStyles(pos);
+ return this;
+ }
+
+});
+
+})();
+
+/*
+Script: Element.Shortcuts.js
+ Extends the Element native object to include some shortcut methods.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Aaron Newton
+
+*/
+
+Element.implement({
+
+ isDisplayed: function(){
+ return this.getStyle('display') != 'none';
+ },
+
+ toggle: function(){
+ return this[this.isDisplayed() ? 'hide' : 'show']();
+ },
+
+ hide: function(){
+ var d;
+ try {
+ //IE fails here if the element is not in the dom
+ if ('none' != this.getStyle('display')) d = this.getStyle('display');
+ } catch(e){}
+
+ return this.store('originalDisplay', d || 'block').setStyle('display', 'none');
+ },
+
+ show: function(display){
+ return this.setStyle('display', display || this.retrieve('originalDisplay') || 'block');
+ },
+
+ swapClass: function(remove, add){
+ return this.removeClass(remove).addClass(add);
+ }
+
+});
+
+
+/*
+Script: FormValidator.js
+ A css-class based form validation system.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Aaron Newton
+*/
+var InputValidator = new Class({
+
+ Implements: [Options],
+
+ options: {
+ errorMsg: 'Validation failed.',
+ test: function(field){return true;}
+ },
+
+ initialize: function(className, options){
+ this.setOptions(options);
+ this.className = className;
+ },
+
+ test: function(field, props){
+ if (document.id(field)) return this.options.test(document.id(field), props||this.getProps(field));
+ else return false;
+ },
+
+ getError: function(field, props){
+ var err = this.options.errorMsg;
+ if ($type(err) == 'function') err = err(document.id(field), props||this.getProps(field));
+ return err;
+ },
+
+ getProps: function(field){
+ if (!document.id(field)) return {};
+ return field.get('validatorProps');
+ }
+
+});
+
+Element.Properties.validatorProps = {
+
+ set: function(props){
+ return this.eliminate('validatorProps').store('validatorProps', props);
+ },
+
+ get: function(props){
+ if (props) this.set(props);
+ if (this.retrieve('validatorProps')) return this.retrieve('validatorProps');
+ if (this.getProperty('validatorProps')){
+ try {
+ this.store('validatorProps', JSON.decode(this.getProperty('validatorProps')));
+ }catch(e){
+ return {};
+ }
+ } else {
+ var vals = this.get('class').split(' ').filter(function(cls){
+ return cls.test(':');
+ });
+ if (!vals.length){
+ this.store('validatorProps', {});
+ } else {
+ props = {};
+ vals.each(function(cls){
+ var split = cls.split(':');
+ if (split[1]) {
+ try {
+ props[split[0]] = JSON.decode(split[1]);
+ } catch(e) {}
+ }
+ });
+ this.store('validatorProps', props);
+ }
+ }
+ return this.retrieve('validatorProps');
+ }
+
+};
+
+var FormValidator = new Class({
+
+ Implements:[Options, Events],
+
+ Binds: ['onSubmit'],
+
+ options: {/*
+ onFormValidate: $empty(isValid, form, event),
+ onElementValidate: $empty(isValid, field, className, warn),
+ onElementPass: $empty(field),
+ onElementFail: $empty(field, validatorsFailed) */
+ fieldSelectors: 'input, select, textarea',
+ ignoreHidden: true,
+ useTitles: false,
+ evaluateOnSubmit: true,
+ evaluateFieldsOnBlur: true,
+ evaluateFieldsOnChange: true,
+ serial: true,
+ stopOnFailure: true,
+ warningPrefix: function(){
+ return FormValidator.getMsg('warningPrefix') || 'Warning: ';
+ },
+ errorPrefix: function(){
+ return FormValidator.getMsg('errorPrefix') || 'Error: ';
+ }
+ },
+
+ initialize: function(form, options){
+ this.setOptions(options);
+ this.element = document.id(form);
+ this.element.store('validator', this);
+ this.warningPrefix = $lambda(this.options.warningPrefix)();
+ this.errorPrefix = $lambda(this.options.errorPrefix)();
+ if (this.options.evaluateOnSubmit) this.element.addEvent('submit', this.onSubmit);
+ if (this.options.evaluateFieldsOnBlur || this.options.evaluateFieldsOnChange) this.watchFields(this.getFields());
+ },
+
+ toElement: function(){
+ return this.element;
+ },
+
+ getFields: function(){
+ return (this.fields = this.element.getElements(this.options.fieldSelectors));
+ },
+
+ watchFields: function(fields){
+ fields.each(function(el){
+ if (this.options.evaluateFieldsOnBlur)
+ el.addEvent('blur', this.validationMonitor.pass([el, false], this));
+ if (this.options.evaluateFieldsOnChange)
+ el.addEvent('change', this.validationMonitor.pass([el, true], this));
+ }, this);
+ },
+
+ validationMonitor: function(){
+ $clear(this.timer);
+ this.timer = this.validateField.delay(50, this, arguments);
+ },
+
+ onSubmit: function(event){
+ if (!this.validate(event) && event) event.preventDefault();
+ else this.reset();
+ },
+
+ reset: function(){
+ this.getFields().each(this.resetField, this);
+ return this;
+ },
+
+ validate: function(event){
+ var result = this.getFields().map(function(field){
+ return this.validateField(field, true);
+ }, this).every(function(v){ return v;});
+ this.fireEvent('formValidate', [result, this.element, event]);
+ if (this.options.stopOnFailure && !result && event) event.preventDefault();
+ return result;
+ },
+
+ validateField: function(field, force){
+ if (this.paused) return true;
+ field = document.id(field);
+ var passed = !field.hasClass('validation-failed');
+ var failed, warned;
+ if (this.options.serial && !force){
+ failed = this.element.getElement('.validation-failed');
+ warned = this.element.getElement('.warning');
+ }
+ if (field && (!failed || force || field.hasClass('validation-failed') || (failed && !this.options.serial))){
+ var validators = field.className.split(' ').some(function(cn){
+ return this.getValidator(cn);
+ }, this);
+ var validatorsFailed = [];
+ field.className.split(' ').each(function(className){
+ if (className && !this.test(className, field)) validatorsFailed.include(className);
+ }, this);
+ passed = validatorsFailed.length === 0;
+ if (validators && !field.hasClass('warnOnly')){
+ if (passed){
+ field.addClass('validation-passed').removeClass('validation-failed');
+ this.fireEvent('elementPass', field);
+ } else {
+ field.addClass('validation-failed').removeClass('validation-passed');
+ this.fireEvent('elementFail', [field, validatorsFailed]);
+ }
+ }
+ if (!warned){
+ var warnings = field.className.split(' ').some(function(cn){
+ if (cn.test('^warn-') || field.hasClass('warnOnly'))
+ return this.getValidator(cn.replace(/^warn-/,''));
+ else return null;
+ }, this);
+ field.removeClass('warning');
+ var warnResult = field.className.split(' ').map(function(cn){
+ if (cn.test('^warn-') || field.hasClass('warnOnly'))
+ return this.test(cn.replace(/^warn-/,''), field, true);
+ else return null;
+ }, this);
+ }
+ }
+ return passed;
+ },
+
+ test: function(className, field, warn){
+ var validator = this.getValidator(className);
+ field = document.id(field);
+ if (field.hasClass('ignoreValidation')) return true;
+ warn = $pick(warn, false);
+ if (field.hasClass('warnOnly')) warn = true;
+ var isValid = validator ? validator.test(field) : true;
+ if (validator && this.isVisible(field)) this.fireEvent('elementValidate', [isValid, field, className, warn]);
+ if (warn) return true;
+ return isValid;
+ },
+
+ isVisible : function(field){
+ if (!this.options.ignoreHidden) return true;
+ while(field != document.body){
+ if (document.id(field).getStyle('display') == 'none') return false;
+ field = field.getParent();
+ }
+ return true;
+ },
+
+ resetField: function(field){
+ field = document.id(field);
+ if (field){
+ field.className.split(' ').each(function(className){
+ if (className.test('^warn-')) className = className.replace(/^warn-/, '');
+ field.removeClass('validation-failed');
+ field.removeClass('warning');
+ field.removeClass('validation-passed');
+ }, this);
+ }
+ return this;
+ },
+
+ stop: function(){
+ this.paused = true;
+ return this;
+ },
+
+ start: function(){
+ this.paused = false;
+ return this;
+ },
+
+ ignoreField: function(field, warn){
+ field = document.id(field);
+ if (field){
+ this.enforceField(field);
+ if (warn) field.addClass('warnOnly');
+ else field.addClass('ignoreValidation');
+ }
+ return this;
+ },
+
+ enforceField: function(field){
+ field = document.id(field);
+ if (field) field.removeClass('warnOnly').removeClass('ignoreValidation');
+ return this;
+ }
+
+});
+
+FormValidator.getMsg = function(key){
+ return MooTools.lang.get('FormValidator', key);
+};
+
+FormValidator.adders = {
+
+ validators:{},
+
+ add : function(className, options){
+ this.validators[className] = new InputValidator(className, options);
+ //if this is a class (this method is used by instances of FormValidator and the FormValidator namespace)
+ //extend these validators into it
+ //this allows validators to be global and/or per instance
+ if (!this.initialize){
+ this.implement({
+ validators: this.validators
+ });
+ }
+ },
+
+ addAllThese : function(validators){
+ $A(validators).each(function(validator){
+ this.add(validator[0], validator[1]);
+ }, this);
+ },
+
+ getValidator: function(className){
+ return this.validators[className.split(':')[0]];
+ }
+
+};
+
+$extend(FormValidator, FormValidator.adders);
+
+FormValidator.implement(FormValidator.adders);
+
+FormValidator.add('IsEmpty', {
+
+ errorMsg: false,
+ test: function(element){
+ if (element.type == 'select-one' || element.type == 'select')
+ return !(element.selectedIndex >= 0 && element.options[element.selectedIndex].value != '');
+ else
+ return ((element.get('value') == null) || (element.get('value').length == 0));
+ }
+
+});
+
+FormValidator.addAllThese([
+
+ ['required', {
+ errorMsg: function(){
+ return FormValidator.getMsg('required');
+ },
+ test: function(element){
+ return !FormValidator.getValidator('IsEmpty').test(element);
+ }
+ }],
+
+ ['minLength', {
+ errorMsg: function(element, props){
+ if ($type(props.minLength))
+ return FormValidator.getMsg('minLength').substitute({minLength:props.minLength,length:element.get('value').length });
+ else return '';
+ },
+ test: function(element, props){
+ if ($type(props.minLength)) return (element.get('value').length >= $pick(props.minLength, 0));
+ else return true;
+ }
+ }],
+
+ ['maxLength', {
+ errorMsg: function(element, props){
+ //props is {maxLength:10}
+ if ($type(props.maxLength))
+ return FormValidator.getMsg('maxLength').substitute({maxLength:props.maxLength,length:element.get('value').length });
+ else return '';
+ },
+ test: function(element, props){
+ //if the value is <= than the maxLength value, element passes test
+ return (element.get('value').length <= $pick(props.maxLength, 10000));
+ }
+ }],
+
+ ['validate-integer', {
+ errorMsg: FormValidator.getMsg.pass('integer'),
+ test: function(element){
+ return FormValidator.getValidator('IsEmpty').test(element) || (/^(-?[1-9]\d*|0)$/).test(element.get('value'));
+ }
+ }],
+
+ ['validate-numeric', {
+ errorMsg: FormValidator.getMsg.pass('numeric'),
+ test: function(element){
+ return FormValidator.getValidator('IsEmpty').test(element) ||
+ (/^-?(?:0$0(?=\d*\.)|[1-9]|0)\d*(\.\d+)?$/).test(element.get('value'));
+ }
+ }],
+
+ ['validate-digits', {
+ errorMsg: FormValidator.getMsg.pass('digits'),
+ test: function(element){
+ return FormValidator.getValidator('IsEmpty').test(element) || (/^[\d() .:\-\+#]+$/.test(element.get('value')));
+ }
+ }],
+
+ ['validate-alpha', {
+ errorMsg: FormValidator.getMsg.pass('alpha'),
+ test: function(element){
+ return FormValidator.getValidator('IsEmpty').test(element) || (/^[a-zA-Z]+$/).test(element.get('value'));
+ }
+ }],
+
+ ['validate-alphanum', {
+ errorMsg: FormValidator.getMsg.pass('alphanum'),
+ test: function(element){
+ return FormValidator.getValidator('IsEmpty').test(element) || !(/\W/).test(element.get('value'));
+ }
+ }],
+
+ ['validate-date', {
+ errorMsg: function(element, props){
+ if (Date.parse){
+ var format = props.dateFormat || '%x';
+ return FormValidator.getMsg('dateSuchAs').substitute({date: new Date().format(format)});
+ } else {
+ return FormValidator.getMsg('dateInFormatMDY');
+ }
+ },
+ test: function(element, props){
+ if (FormValidator.getValidator('IsEmpty').test(element)) return true;
+ var d;
+ if (Date.parse){
+ var format = props.dateFormat || '%x';
+ d = Date.parse(element.get('value'));
+ var formatted = d.format(format);
+ if (formatted != 'invalid date') element.set('value', formatted);
+ return !isNaN(d);
+ } else {
+ var regex = /^(\d{2})\/(\d{2})\/(\d{4})$/;
+ if (!regex.test(element.get('value'))) return false;
+ d = new Date(element.get('value').replace(regex, '$1/$2/$3'));
+ return (parseInt(RegExp.$1, 10) == (1 + d.getMonth())) &&
+ (parseInt(RegExp.$2, 10) == d.getDate()) &&
+ (parseInt(RegExp.$3, 10) == d.getFullYear());
+ }
+ }
+ }],
+
+ ['validate-email', {
+ errorMsg: FormValidator.getMsg.pass('email'),
+ test: function(element){
+ return FormValidator.getValidator('IsEmpty').test(element) || (/^[A-Z0-9._%+-]+(a)[A-Z0-9.-]+\.[A-Z]{2,4}$/i).test(element.get('value'));
+ }
+ }],
+
+ ['validate-url', {
+ errorMsg: FormValidator.getMsg.pass('url'),
+ test: function(element){
+ return FormValidator.getValidator('IsEmpty').test(element) || (/^(https?|ftp|rmtp|mms):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i).test(element.get('value'));
+ }
+ }],
+
+ ['validate-currency-dollar', {
+ errorMsg: FormValidator.getMsg.pass('currencyDollar'),
+ test: function(element){
+ // [$]1[##][,###]+[.##]
+ // [$]1###+[.##]
+ // [$]0.##
+ // [$].##
+ return FormValidator.getValidator('IsEmpty').test(element) || (/^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/).test(element.get('value'));
+ }
+ }],
+
+ ['validate-one-required', {
+ errorMsg: FormValidator.getMsg.pass('oneRequired'),
+ test: function(element, props){
+ var p = document.id(props['validate-one-required']) || element.parentNode;
+ return p.getElements('input').some(function(el){
+ if (['checkbox', 'radio'].contains(el.get('type'))) return el.get('checked');
+ return el.get('value');
+ });
+ }
+ }]
+
+]);
+
+Element.Properties.validator = {
+
+ set: function(options){
+ var validator = this.retrieve('validator');
+ if (validator) validator.setOptions(options);
+ return this.store('validator:options');
+ },
+
+ get: function(options){
+ if (options || !this.retrieve('validator')){
+ if (options || !this.retrieve('validator:options')) this.set('validator', options);
+ this.store('validator', new FormValidator(this, this.retrieve('validator:options')));
+ }
+ return this.retrieve('validator');
+ }
+
+};
+
+Element.implement({
+
+ validate: function(options){
+ this.set('validator', options);
+ return this.get('validator', options).validate();
+ }
+
+});
+
+/*
+Script: Fx.Elements.js
+ Effect to change any number of CSS properties of any number of Elements.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Valerio Proietti
+*/
+
+Fx.Elements = new Class({
+
+ Extends: Fx.CSS,
+
+ initialize: function(elements, options){
+ this.elements = this.subject = $$(elements);
+ this.parent(options);
+ },
+
+ compute: function(from, to, delta){
+ var now = {};
+ for (var i in from){
+ var iFrom = from[i], iTo = to[i], iNow = now[i] = {};
+ for (var p in iFrom) iNow[p] = this.parent(iFrom[p], iTo[p], delta);
+ }
+ return now;
+ },
+
+ set: function(now){
+ for (var i in now){
+ var iNow = now[i];
+ for (var p in iNow) this.render(this.elements[i], p, iNow[p], this.options.unit);
+ }
+ return this;
+ },
+
+ start: function(obj){
+ if (!this.check(obj)) return this;
+ var from = {}, to = {};
+ for (var i in obj){
+ var iProps = obj[i], iFrom = from[i] = {}, iTo = to[i] = {};
+ for (var p in iProps){
+ var parsed = this.prepare(this.elements[i], p, iProps[p]);
+ iFrom[p] = parsed.from;
+ iTo[p] = parsed.to;
+ }
+ }
+ return this.parent(from, to);
+ }
+
+});
+
+/*
+Script: Fx.Accordion.js
+ An Fx.Elements extension which allows you to easily create accordion type controls.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Valerio Proietti
+*/
+
+var Accordion = Fx.Accordion = new Class({
+
+ Extends: Fx.Elements,
+
+ options: {/*
+ onActive: $empty(toggler, section),
+ onBackground: $empty(toggler, section),*/
+ display: 0,
+ show: false,
+ height: true,
+ width: false,
+ opacity: true,
+ fixedHeight: false,
+ fixedWidth: false,
+ wait: false,
+ alwaysHide: false,
+ trigger: 'click',
+ initialDisplayFx: true
+ },
+
+ initialize: function(){
+ var params = Array.link(arguments, {'container': Element.type, 'options': Object.type, 'togglers': $defined, 'elements': $defined});
+ this.parent(params.elements, params.options);
+ this.togglers = $$(params.togglers);
+ this.container = document.id(params.container);
+ this.previous = -1;
+ if (this.options.alwaysHide) this.options.wait = true;
+ if ($chk(this.options.show)){
+ this.options.display = false;
+ this.previous = this.options.show;
+ }
+ if (this.options.start){
+ this.options.display = false;
+ this.options.show = false;
+ }
+ this.effects = {};
+ if (this.options.opacity) this.effects.opacity = 'fullOpacity';
+ if (this.options.width) this.effects.width = this.options.fixedWidth ? 'fullWidth' : 'offsetWidth';
+ if (this.options.height) this.effects.height = this.options.fixedHeight ? 'fullHeight' : 'scrollHeight';
+ for (var i = 0, l = this.togglers.length; i < l; i++) this.addSection(this.togglers[i], this.elements[i]);
+ this.elements.each(function(el, i){
+ if (this.options.show === i){
+ this.fireEvent('active', [this.togglers[i], el]);
+ } else {
+ for (var fx in this.effects) el.setStyle(fx, 0);
+ }
+ }, this);
+ if ($chk(this.options.display)) this.display(this.options.display, this.options.initialDisplayFx);
+ },
+
+ addSection: function(toggler, element){
+ toggler = document.id(toggler);
+ element = document.id(element);
+ var test = this.togglers.contains(toggler);
+ this.togglers.include(toggler);
+ this.elements.include(element);
+ var idx = this.togglers.indexOf(toggler);
+ toggler.addEvent(this.options.trigger, this.display.bind(this, idx));
+ if (this.options.height) element.setStyles({'padding-top': 0, 'border-top': 'none', 'padding-bottom': 0, 'border-bottom': 'none'});
+ if (this.options.width) element.setStyles({'padding-left': 0, 'border-left': 'none', 'padding-right': 0, 'border-right': 'none'});
+ element.fullOpacity = 1;
+ if (this.options.fixedWidth) element.fullWidth = this.options.fixedWidth;
+ if (this.options.fixedHeight) element.fullHeight = this.options.fixedHeight;
+ element.setStyle('overflow', 'hidden');
+ if (!test){
+ for (var fx in this.effects) element.setStyle(fx, 0);
+ }
+ return this;
+ },
+
+ display: function(index, useFx){
+ useFx = $pick(useFx, true);
+ index = ($type(index) == 'element') ? this.elements.indexOf(index) : index;
+ if ((this.timer && this.options.wait) || (index === this.previous && !this.options.alwaysHide)) return this;
+ this.previous = index;
+ var obj = {};
+ this.elements.each(function(el, i){
+ obj[i] = {};
+ var hide = (i != index) || (this.options.alwaysHide && (el.offsetHeight > 0));
+ this.fireEvent(hide ? 'background' : 'active', [this.togglers[i], el]);
+ for (var fx in this.effects) obj[i][fx] = hide ? 0 : el[this.effects[fx]];
+ }, this);
+ return useFx ? this.start(obj) : this.set(obj);
+ }
+
+});
+
+/*
+Script: Fx.Move.js
+ Defines Fx.Move, a class that works with Element.Position.js to transition an element from one location to another.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Aaron Newton
+
+*/
+
+Fx.Move = new Class({
+
+ Extends: Fx.Morph,
+
+ options: {
+ relativeTo: document.body,
+ position: 'center',
+ edge: false,
+ offset: {x: 0, y: 0}
+ },
+
+ start: function(destination){
+ return this.parent(this.element.position($merge(this.options, destination, {returnPos: true})));
+ }
+
+});
+
+Element.Properties.move = {
+
+ set: function(options){
+ var morph = this.retrieve('move');
+ if (morph) morph.cancel();
+ return this.eliminate('move').store('move:options', $extend({link: 'cancel'}, options));
+ },
+
+ get: function(options){
+ if (options || !this.retrieve('move')){
+ if (options || !this.retrieve('move:options')) this.set('move', options);
+ this.store('move', new Fx.Move(this, this.retrieve('move:options')));
+ }
+ return this.retrieve('move');
+ }
+
+};
+
+Element.implement({
+
+ move: function(options){
+ this.get('move').start(options);
+ return this;
+ }
+
+});
+
+
+/*
+Script: Fx.Reveal.js
+ Defines Fx.Reveal, a class that shows and hides elements with a transition.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Aaron Newton
+
+*/
+
+Fx.Reveal = new Class({
+
+ Extends: Fx.Morph,
+
+ options: {/*
+ onShow: $empty(thisElement),
+ onHide: $empty(thisElement),
+ onComplete: $empty(thisElement),
+ heightOverride: null,
+ widthOverride: null, */
+ styles: ['padding', 'border', 'margin'],
+ transitionOpacity: !Browser.Engine.trident4,
+ mode: 'vertical',
+ display: 'block',
+ hideInputs: Browser.Engine.trident ? 'select, input, textarea, object, embed' : false
+ },
+
+ dissolve: function(){
+ try {
+ if (!this.hiding && !this.showing){
+ if (this.element.getStyle('display') != 'none'){
+ this.hiding = true;
+ this.showing = false;
+ this.hidden = true;
+ var startStyles = this.element.getComputedSize({
+ styles: this.options.styles,
+ mode: this.options.mode
+ });
+ var setToAuto = (this.element.style.height === ''||this.element.style.height == 'auto');
+ this.element.setStyle('display', 'block');
+ if (this.options.transitionOpacity) startStyles.opacity = 1;
+ var zero = {};
+ $each(startStyles, function(style, name){
+ zero[name] = [style, 0];
+ }, this);
+ var overflowBefore = this.element.getStyle('overflow');
+ this.element.setStyle('overflow', 'hidden');
+ var hideThese = this.options.hideInputs ? this.element.getElements(this.options.hideInputs) : null;
+ this.$chain.unshift(function(){
+ if (this.hidden){
+ this.hiding = false;
+ $each(startStyles, function(style, name){
+ startStyles[name] = style;
+ }, this);
+ this.element.setStyles($merge({display: 'none', overflow: overflowBefore}, startStyles));
+ if (setToAuto){
+ if (['vertical', 'both'].contains(this.options.mode)) this.element.style.height = '';
+ if (['width', 'both'].contains(this.options.mode)) this.element.style.width = '';
+ }
+ if (hideThese) hideThese.setStyle('visibility', 'visible');
+ }
+ this.fireEvent('hide', this.element);
+ this.callChain();
+ }.bind(this));
+ if (hideThese) hideThese.setStyle('visibility', 'hidden');
+ this.start(zero);
+ } else {
+ this.callChain.delay(10, this);
+ this.fireEvent('complete', this.element);
+ this.fireEvent('hide', this.element);
+ }
+ } else if (this.options.link == 'chain'){
+ this.chain(this.dissolve.bind(this));
+ } else if (this.options.link == 'cancel' && !this.hiding){
+ this.cancel();
+ this.dissolve();
+ }
+ } catch(e){
+ this.hiding = false;
+ this.element.setStyle('display', 'none');
+ this.callChain.delay(10, this);
+ this.fireEvent('complete', this.element);
+ this.fireEvent('hide', this.element);
+ }
+ return this;
+ },
+
+ reveal: function(){
+ try {
+ if (!this.showing && !this.hiding){
+ if (this.element.getStyle('display') == 'none' ||
+ this.element.getStyle('visiblity') == 'hidden' ||
+ this.element.getStyle('opacity') == 0){
+ this.showing = true;
+ this.hiding = false;
+ this.hidden = false;
+ var setToAuto, startStyles;
+ //toggle display, but hide it
+ this.element.measure(function(){
+ setToAuto = (this.element.style.height === '' || this.element.style.height == 'auto');
+ //create the styles for the opened/visible state
+ startStyles = this.element.getComputedSize({
+ styles: this.options.styles,
+ mode: this.options.mode
+ });
+ }.bind(this));
+ $each(startStyles, function(style, name){
+ startStyles[name] = style;
+ });
+ //if we're overridding height/width
+ if ($chk(this.options.heightOverride)) startStyles.height = this.options.heightOverride.toInt();
+ if ($chk(this.options.widthOverride)) startStyles.width = this.options.widthOverride.toInt();
+ if (this.options.transitionOpacity) {
+ this.element.setStyle('opacity', 0);
+ startStyles.opacity = 1;
+ }
+ //create the zero state for the beginning of the transition
+ var zero = {
+ height: 0,
+ display: this.options.display
+ };
+ $each(startStyles, function(style, name){ zero[name] = 0; });
+ var overflowBefore = this.element.getStyle('overflow');
+ //set to zero
+ this.element.setStyles($merge(zero, {overflow: 'hidden'}));
+ //hide inputs
+ var hideThese = this.options.hideInputs ? this.element.getElements(this.options.hideInputs) : null;
+ if (hideThese) hideThese.setStyle('visibility', 'hidden');
+ //start the effect
+ this.start(startStyles);
+ this.$chain.unshift(function(){
+ this.element.setStyle('overflow', overflowBefore);
+ if (!this.options.heightOverride && setToAuto){
+ if (['vertical', 'both'].contains(this.options.mode)) this.element.style.height = '';
+ if (['width', 'both'].contains(this.options.mode)) this.element.style.width = '';
+ }
+ if (!this.hidden) this.showing = false;
+ if (hideThese) hideThese.setStyle('visibility', 'visible');
+ this.callChain();
+ this.fireEvent('show', this.element);
+ }.bind(this));
+ } else {
+ this.callChain();
+ this.fireEvent('complete', this.element);
+ this.fireEvent('show', this.element);
+ }
+ } else if (this.options.link == 'chain'){
+ this.chain(this.reveal.bind(this));
+ } else if (this.options.link == 'cancel' && !this.showing){
+ this.cancel();
+ this.reveal();
+ }
+ } catch(e){
+ this.element.setStyles({
+ display: this.options.display,
+ visiblity: 'visible',
+ opacity: 1
+ });
+ this.showing = false;
+ this.callChain.delay(10, this);
+ this.fireEvent('complete', this.element);
+ this.fireEvent('show', this.element);
+ }
+ return this;
+ },
+
+ toggle: function(){
+ if (this.element.getStyle('display') == 'none' ||
+ this.element.getStyle('visiblity') == 'hidden' ||
+ this.element.getStyle('opacity') == 0){
+ this.reveal();
+ } else {
+ this.dissolve();
+ }
+ return this;
+ }
+
+});
+
+Element.Properties.reveal = {
+
+ set: function(options){
+ var reveal = this.retrieve('reveal');
+ if (reveal) reveal.cancel();
+ return this.eliminate('reveal').store('reveal:options', $extend({link: 'cancel'}, options));
+ },
+
+ get: function(options){
+ if (options || !this.retrieve('reveal')){
+ if (options || !this.retrieve('reveal:options')) this.set('reveal', options);
+ this.store('reveal', new Fx.Reveal(this, this.retrieve('reveal:options')));
+ }
+ return this.retrieve('reveal');
+ }
+
+};
+
+Element.Properties.dissolve = Element.Properties.reveal;
+
+Element.implement({
+
+ reveal: function(options){
+ this.get('reveal', options).reveal();
+ return this;
+ },
+
+ dissolve: function(options){
+ this.get('reveal', options).dissolve();
+ return this;
+ },
+
+ nix: function(){
+ var params = Array.link(arguments, {destroy: Boolean.type, options: Object.type});
+ this.get('reveal', params.options).dissolve().chain(function(){
+ this[params.destroy ? 'destroy' : 'dispose']();
+ }.bind(this));
+ return this;
+ },
+
+ wink: function(){
+ var params = Array.link(arguments, {duration: Number.type, options: Object.type});
+ var reveal = this.get('reveal', params.options);
+ reveal.reveal().chain(function(){
+ (function(){
+ reveal.dissolve();
+ }).delay(params.duration || 2000);
+ });
+ }
+
+
+});
+
+/*
+Script: Fx.Scroll.js
+ Effect to smoothly scroll any element, including the window.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Valerio Proietti
+*/
+
+Fx.Scroll = new Class({
+
+ Extends: Fx,
+
+ options: {
+ offset: {x: 0, y: 0},
+ wheelStops: true
+ },
+
+ initialize: function(element, options){
+ this.element = this.subject = document.id(element);
+ this.parent(options);
+ var cancel = this.cancel.bind(this, false);
+
+ if ($type(this.element) != 'element') this.element = document.id(this.element.getDocument().body);
+
+ var stopper = this.element;
+
+ if (this.options.wheelStops){
+ this.addEvent('start', function(){
+ stopper.addEvent('mousewheel', cancel);
+ }, true);
+ this.addEvent('complete', function(){
+ stopper.removeEvent('mousewheel', cancel);
+ }, true);
+ }
+ },
+
+ set: function(){
+ var now = Array.flatten(arguments);
+ this.element.scrollTo(now[0], now[1]);
+ },
+
+ compute: function(from, to, delta){
+ return [0, 1].map(function(i){
+ return Fx.compute(from[i], to[i], delta);
+ });
+ },
+
+ start: function(x, y){
+ if (!this.check(x, y)) return this;
+ var offsetSize = this.element.getSize(), scrollSize = this.element.getScrollSize();
+ var scroll = this.element.getScroll(), values = {x: x, y: y};
+ for (var z in values){
+ var max = scrollSize[z] - offsetSize[z];
+ if ($chk(values[z])) values[z] = ($type(values[z]) == 'number') ? values[z].limit(0, max) : max;
+ else values[z] = scroll[z];
+ values[z] += this.options.offset[z];
+ }
+ return this.parent([scroll.x, scroll.y], [values.x, values.y]);
+ },
+
+ toTop: function(){
+ return this.start(false, 0);
+ },
+
+ toLeft: function(){
+ return this.start(0, false);
+ },
+
+ toRight: function(){
+ return this.start('right', false);
+ },
+
+ toBottom: function(){
+ return this.start(false, 'bottom');
+ },
+
+ toElement: function(el){
+ var position = document.id(el).getPosition(this.element);
+ return this.start(position.x, position.y);
+ },
+
+ scrollIntoView: function(el, axes, offset){
+ axes = axes ? $splat(axes) : ['x','y'];
+ var to = {};
+ el = document.id(el);
+ var pos = el.getPosition(this.element);
+ var size = el.getSize();
+ var scroll = this.element.getScroll();
+ var containerSize = this.element.getSize();
+ var edge = {
+ x: pos.x + size.x,
+ y: pos.y + size.y
+ };
+ ['x','y'].each(function(axis) {
+ if (axes.contains(axis)) {
+ if (edge[axis] > scroll[axis] + containerSize[axis]) to[axis] = edge[axis] - containerSize[axis];
+ if (pos[axis] < scroll[axis]) to[axis] = pos[axis];
+ }
+ if (to[axis] == null) to[axis] = scroll[axis];
+ if (offset && offset[axis]) to[axis] = to[axis] + offset[axis];
+ }, this);
+ if (to.x != scroll.x || to.y != scroll.y) this.start(to.x, to.y);
+ return this;
+ }
+
+});
+
+
+/*
+Script: Fx.Slide.js
+ Effect to slide an element in and out of view.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Valerio Proietti
+*/
+
+Fx.Slide = new Class({
+
+ Extends: Fx,
+
+ options: {
+ mode: 'vertical'
+ },
+
+ initialize: function(element, options){
+ this.addEvent('complete', function(){
+ this.open = (this.wrapper['offset' + this.layout.capitalize()] != 0);
+ if (this.open && Browser.Engine.webkit419) this.element.dispose().inject(this.wrapper);
+ }, true);
+ this.element = this.subject = document.id(element);
+ this.parent(options);
+ var wrapper = this.element.retrieve('wrapper');
+ this.wrapper = wrapper || new Element('div', {
+ styles: $extend(this.element.getStyles('margin', 'position'), {overflow: 'hidden'})
+ }).wraps(this.element);
+ this.element.store('wrapper', this.wrapper).setStyle('margin', 0);
+ this.now = [];
+ this.open = true;
+ },
+
+ vertical: function(){
+ this.margin = 'margin-top';
+ this.layout = 'height';
+ this.offset = this.element.offsetHeight;
+ },
+
+ horizontal: function(){
+ this.margin = 'margin-left';
+ this.layout = 'width';
+ this.offset = this.element.offsetWidth;
+ },
+
+ set: function(now){
+ this.element.setStyle(this.margin, now[0]);
+ this.wrapper.setStyle(this.layout, now[1]);
+ return this;
+ },
+
+ compute: function(from, to, delta){
+ return [0, 1].map(function(i){
+ return Fx.compute(from[i], to[i], delta);
+ });
+ },
+
+ start: function(how, mode){
+ if (!this.check(how, mode)) return this;
+ this[mode || this.options.mode]();
+ var margin = this.element.getStyle(this.margin).toInt();
+ var layout = this.wrapper.getStyle(this.layout).toInt();
+ var caseIn = [[margin, layout], [0, this.offset]];
+ var caseOut = [[margin, layout], [-this.offset, 0]];
+ var start;
+ switch (how){
+ case 'in': start = caseIn; break;
+ case 'out': start = caseOut; break;
+ case 'toggle': start = (layout == 0) ? caseIn : caseOut;
+ }
+ return this.parent(start[0], start[1]);
+ },
+
+ slideIn: function(mode){
+ return this.start('in', mode);
+ },
+
+ slideOut: function(mode){
+ return this.start('out', mode);
+ },
+
+ hide: function(mode){
+ this[mode || this.options.mode]();
+ this.open = false;
+ return this.set([-this.offset, 0]);
+ },
+
+ show: function(mode){
+ this[mode || this.options.mode]();
+ this.open = true;
+ return this.set([0, this.offset]);
+ },
+
+ toggle: function(mode){
+ return this.start('toggle', mode);
+ }
+
+});
+
+Element.Properties.slide = {
+
+ set: function(options){
+ var slide = this.retrieve('slide');
+ if (slide) slide.cancel();
+ return this.eliminate('slide').store('slide:options', $extend({link: 'cancel'}, options));
+ },
+
+ get: function(options){
+ if (options || !this.retrieve('slide')){
+ if (options || !this.retrieve('slide:options')) this.set('slide', options);
+ this.store('slide', new Fx.Slide(this, this.retrieve('slide:options')));
+ }
+ return this.retrieve('slide');
+ }
+
+};
+
+Element.implement({
+
+ slide: function(how, mode){
+ how = how || 'toggle';
+ var slide = this.get('slide'), toggle;
+ switch (how){
+ case 'hide': slide.hide(mode); break;
+ case 'show': slide.show(mode); break;
+ case 'toggle':
+ var flag = this.retrieve('slide:flag', slide.open);
+ slide[flag ? 'slideOut' : 'slideIn'](mode);
+ this.store('slide:flag', !flag);
+ toggle = true;
+ break;
+ default: slide.start(how, mode);
+ }
+ if (!toggle) this.eliminate('slide:flag');
+ return this;
+ }
+
+});
+
+
+/*
+Script: Fx.SmoothScroll.js
+ Class for creating a smooth scrolling effect to all internal links on the page.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Valerio Proietti
+*/
+
+var SmoothScroll = Fx.SmoothScroll = new Class({
+
+ Extends: Fx.Scroll,
+
+ initialize: function(options, context){
+ context = context || document;
+ this.doc = context.getDocument();
+ var win = context.getWindow();
+ this.parent(this.doc, options);
+ this.links = this.options.links ? $$(this.options.links) : $$(this.doc.links);
+ var location = win.location.href.match(/^[^#]*/)[0] + '#';
+ this.links.each(function(link){
+ if (link.href.indexOf(location) != 0) {return;}
+ var anchor = link.href.substr(location.length);
+ if (anchor) this.useLink(link, anchor);
+ }, this);
+ if (!Browser.Engine.webkit419) {
+ this.addEvent('complete', function(){
+ win.location.hash = this.anchor;
+ }, true);
+ }
+ },
+
+ useLink: function(link, anchor){
+ var el;
+ link.addEvent('click', function(event){
+ if (el !== false && !el) el = document.id(anchor) || this.doc.getElement('a[name=' + anchor + ']');
+ if (el) {
+ event.preventDefault();
+ this.anchor = anchor;
+ this.toElement(el);
+ link.blur();
+ }
+ }.bind(this));
+ }
+
+});
+
+/*
+Script: Drag.js
+ The base Drag Class. Can be used to drag and resize Elements using mouse events.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Valerio Proietti
+ Tom Occhinno
+ Jan Kassens
+*/
+
+var Drag = new Class({
+
+ Implements: [Events, Options],
+
+ options: {/*
+ onBeforeStart: $empty(thisElement),
+ onStart: $empty(thisElement, event),
+ onSnap: $empty(thisElement)
+ onDrag: $empty(thisElement, event),
+ onCancel: $empty(thisElement),
+ onComplete: $empty(thisElement, event),*/
+ snap: 6,
+ unit: 'px',
+ grid: false,
+ style: true,
+ limit: false,
+ handle: false,
+ invert: false,
+ preventDefault: false,
+ modifiers: {x: 'left', y: 'top'}
+ },
+
+ initialize: function(){
+ var params = Array.link(arguments, {'options': Object.type, 'element': $defined});
+ this.element = document.id(params.element);
+ this.document = this.element.getDocument();
+ this.setOptions(params.options || {});
+ var htype = $type(this.options.handle);
+ this.handles = ((htype == 'array' || htype == 'collection') ? $$(this.options.handle) : document.id(this.options.handle)) || this.element;
+ this.mouse = {'now': {}, 'pos': {}};
+ this.value = {'start': {}, 'now': {}};
+
+ this.selection = (Browser.Engine.trident) ? 'selectstart' : 'mousedown';
+
+ this.bound = {
+ start: this.start.bind(this),
+ check: this.check.bind(this),
+ drag: this.drag.bind(this),
+ stop: this.stop.bind(this),
+ cancel: this.cancel.bind(this),
+ eventStop: $lambda(false)
+ };
+ this.attach();
+ },
+
+ attach: function(){
+ this.handles.addEvent('mousedown', this.bound.start);
+ return this;
+ },
+
+ detach: function(){
+ this.handles.removeEvent('mousedown', this.bound.start);
+ return this;
+ },
+
+ start: function(event){
+ if (this.options.preventDefault) event.preventDefault();
+ this.mouse.start = event.page;
+ this.fireEvent('beforeStart', this.element);
+ var limit = this.options.limit;
+ this.limit = {x: [], y: []};
+ for (var z in this.options.modifiers){
+ if (!this.options.modifiers[z]) continue;
+ if (this.options.style) this.value.now[z] = this.element.getStyle(this.options.modifiers[z]).toInt();
+ else this.value.now[z] = this.element[this.options.modifiers[z]];
+ if (this.options.invert) this.value.now[z] *= -1;
+ this.mouse.pos[z] = event.page[z] - this.value.now[z];
+ if (limit && limit[z]){
+ for (var i = 2; i--; i){
+ if ($chk(limit[z][i])) this.limit[z][i] = $lambda(limit[z][i])();
+ }
+ }
+ }
+ if ($type(this.options.grid) == 'number') this.options.grid = {x: this.options.grid, y: this.options.grid};
+ this.document.addEvents({mousemove: this.bound.check, mouseup: this.bound.cancel});
+ this.document.addEvent(this.selection, this.bound.eventStop);
+ },
+
+ check: function(event){
+ if (this.options.preventDefault) event.preventDefault();
+ var distance = Math.round(Math.sqrt(Math.pow(event.page.x - this.mouse.start.x, 2) + Math.pow(event.page.y - this.mouse.start.y, 2)));
+ if (distance > this.options.snap){
+ this.cancel();
+ this.document.addEvents({
+ mousemove: this.bound.drag,
+ mouseup: this.bound.stop
+ });
+ this.fireEvent('start', [this.element, event]).fireEvent('snap', this.element);
+ }
+ },
+
+ drag: function(event){
+ if (this.options.preventDefault) event.preventDefault();
+ this.mouse.now = event.page;
+ for (var z in this.options.modifiers){
+ if (!this.options.modifiers[z]) continue;
+ this.value.now[z] = this.mouse.now[z] - this.mouse.pos[z];
+ if (this.options.invert) this.value.now[z] *= -1;
+ if (this.options.limit && this.limit[z]){
+ if ($chk(this.limit[z][1]) && (this.value.now[z] > this.limit[z][1])){
+ this.value.now[z] = this.limit[z][1];
+ } else if ($chk(this.limit[z][0]) && (this.value.now[z] < this.limit[z][0])){
+ this.value.now[z] = this.limit[z][0];
+ }
+ }
+ if (this.options.grid[z]) this.value.now[z] -= ((this.value.now[z] - (this.limit[z][0]||0)) % this.options.grid[z]);
+ if (this.options.style) this.element.setStyle(this.options.modifiers[z], this.value.now[z] + this.options.unit);
+ else this.element[this.options.modifiers[z]] = this.value.now[z];
+ }
+ this.fireEvent('drag', [this.element, event]);
+ },
+
+ cancel: function(event){
+ this.document.removeEvent('mousemove', this.bound.check);
+ this.document.removeEvent('mouseup', this.bound.cancel);
+ if (event){
+ this.document.removeEvent(this.selection, this.bound.eventStop);
+ this.fireEvent('cancel', this.element);
+ }
+ },
+
+ stop: function(event){
+ this.document.removeEvent(this.selection, this.bound.eventStop);
+ this.document.removeEvent('mousemove', this.bound.drag);
+ this.document.removeEvent('mouseup', this.bound.stop);
+ if (event) this.fireEvent('complete', [this.element, event]);
+ }
+
+});
+
+Element.implement({
+
+ makeResizable: function(options){
+ var drag = new Drag(this, $merge({modifiers: {x: 'width', y: 'height'}}, options));
+ this.store('resizer', drag);
+ return drag.addEvent('drag', function(){
+ this.fireEvent('resize', drag);
+ }.bind(this));
+ }
+
+});
+
+
+/*
+Script: Slider.js
+ Class for creating horizontal and vertical slider controls.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Valerio Proietti
+*/
+
+var Slider = new Class({
+
+ Implements: [Events, Options],
+
+ Binds: ['clickedElement', 'draggedKnob', 'scrolledElement'],
+
+ options: {
+ onTick: function(position){
+ if (this.options.snap) position = this.toPosition(this.step);
+ this.knob.setStyle(this.property, position);
+ },
+ snap: false,
+ offset: 0,
+ range: false,
+ wheel: false,
+ steps: 100,
+ mode: 'horizontal'
+ },
+
+ initialize: function(element, knob, options){
+ this.setOptions(options);
+ this.element = document.id(element);
+ this.knob = document.id(knob);
+ this.previousChange = this.previousEnd = this.step = -1;
+ var offset, limit = {}, modifiers = {'x': false, 'y': false};
+ switch (this.options.mode){
+ case 'vertical':
+ this.axis = 'y';
+ this.property = 'top';
+ offset = 'offsetHeight';
+ break;
+ case 'horizontal':
+ this.axis = 'x';
+ this.property = 'left';
+ offset = 'offsetWidth';
+ }
+ this.half = this.knob[offset] / 2;
+ this.full = this.element[offset] - this.knob[offset] + (this.options.offset * 2);
+ this.min = $chk(this.options.range[0]) ? this.options.range[0] : 0;
+ this.max = $chk(this.options.range[1]) ? this.options.range[1] : this.options.steps;
+ this.range = this.max - this.min;
+ this.steps = this.options.steps || this.full;
+ this.stepSize = Math.abs(this.range) / this.steps;
+ this.stepWidth = this.stepSize * this.full / Math.abs(this.range) ;
+
+ this.knob.setStyle('position', 'relative').setStyle(this.property, - this.options.offset);
+ modifiers[this.axis] = this.property;
+ limit[this.axis] = [- this.options.offset, this.full - this.options.offset];
+
+ this.bound = {
+ clickedElement: this.clickedElement.bind(this),
+ scrolledElement: this.scrolledElement.bindWithEvent(this),
+ draggedKnob: this.draggedKnob.bind(this)
+ };
+
+ var dragOptions = {
+ snap: 0,
+ limit: limit,
+ modifiers: modifiers,
+ onDrag: this.bound.draggedKnob,
+ onStart: this.bound.draggedKnob,
+ onBeforeStart: (function(){
+ this.isDragging = true;
+ }).bind(this),
+ onComplete: function(){
+ this.isDragging = false;
+ this.draggedKnob();
+ this.end();
+ }.bind(this)
+ };
+ if (this.options.snap){
+ dragOptions.grid = Math.ceil(this.stepWidth);
+ dragOptions.limit[this.axis][1] = this.full;
+ }
+
+ this.drag = new Drag(this.knob, dragOptions);
+ this.attach();
+ },
+
+ attach: function(){
+ this.element.addEvent('mousedown', this.bound.clickedElement);
+
+ // keep track from firing the 'mousedown' event if the knob has been hovored
+ this.knob.addEvent('mouseenter',function(){
+ this.element.removeEvents('mousedown');
+ }.bind(this));
+ this.knob.addEvent('mouseleave',function(){
+ this.element.addEvent('mousedown', this.clickedElement.bind(this));
+ }.bind(this));
+
+ if (this.options.wheel) this.element.addEvent('mousewheel', this.bound.scrolledElement);
+ this.drag.attach();
+ return this;
+ },
+
+ detach: function(){
+ this.element.removeEvent('mousedown', this.bound.clickedElement);
+ this.element.removeEvent('mousewheel', this.bound.scrolledElement);
+ this.drag.detach();
+ return this;
+ },
+
+ set: function(step, check){
+ if (arguments.length == 1)
+ check = true;
+ if (!((this.range > 0) ^ (step < this.min))) step = this.min;
+ if (!((this.range > 0) ^ (step > this.max))) step = this.max;
+
+ this.step = Math.round(step);
+ if (check)
+ this.checkStep();
+ this.fireEvent('tick', this.toPosition(this.step));
+ this.end();
+ return this;
+ },
+
+ clickedElement: function(event){
+ if (this.isDragging || event.target == this.knob) return;
+
+ var dir = this.range < 0 ? -1 : 1;
+ var position = event.page[this.axis] - this.element.getPosition()[this.axis] - this.half;
+ position = position.limit(-this.options.offset, this.full -this.options.offset);
+
+ this.step = Math.round(this.min + dir * this.toStep(position));
+ this.checkStep();
+ this.fireEvent('tick', position);
+ this.end();
+ },
+
+ scrolledElement: function(event){
+ var mode = (this.options.mode == 'horizontal') ? (event.wheel < 0) : (event.wheel > 0);
+ this.set(mode ? this.step - this.stepSize : this.step + this.stepSize);
+ event.stop();
+ },
+
+ draggedKnob: function(){
+ var dir = this.range < 0 ? -1 : 1;
+ var position = this.drag.value.now[this.axis];
+ position = position.limit(-this.options.offset, this.full -this.options.offset);
+ this.step = Math.round(this.min + dir * this.toStep(position));
+ this.checkStep();
+ },
+
+ checkStep: function(){
+ if (this.previousChange != this.step){
+ this.previousChange = this.step;
+ this.fireEvent('change', this.step);
+ }
+ },
+
+ end: function(){
+ if (this.previousEnd !== this.step){
+ this.previousEnd = this.step;
+ this.fireEvent('complete', this.step + '');
+ }
+ },
+
+ toStep: function(position){
+ var step = (position + this.options.offset) * this.stepSize / this.full * this.steps;
+ return this.options.steps ? Math.round(step -= step % this.stepSize) : step;
+ },
+
+ toPosition: function(step){
+ return (this.full * Math.abs(this.min - step)) / (this.steps * this.stepSize) - this.options.offset;
+ }
+
+});
+
+/*
+Script: Tips.js
+ Class for creating nice tips that follow the mouse cursor when hovering an element.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Valerio Proietti
+ Christoph Pojer
+*/
+
+var Tips = new Class({
+
+ Implements: [Events, Options],
+
+ options: {
+ onShow: function(tip){
+ tip.setStyle('visibility', 'visible');
+ },
+ onHide: function(tip){
+ tip.setStyle('visibility', 'hidden');
+ },
+ title: 'title',
+ text: function(el){
+ return el.get('rel') || el.get('href');
+ },
+ showDelay: 100,
+ hideDelay: 100,
+ className: null,
+ offset: {x: 16, y: 16},
+ fixed: false
+ },
+
+ initialize: function(){
+ var params = Array.link(arguments, {options: Object.type, elements: $defined});
+ if (params.options && params.options.offsets) params.options.offset = params.options.offsets;
+ this.setOptions(params.options);
+ this.container = new Element('div', {'class': 'tip'});
+ this.tip = this.getTip();
+
+ if (params.elements) this.attach(params.elements);
+ },
+
+ getTip: function(){
+ return new Element('div', {
+ 'class': this.options.className,
+ styles: {
+ visibility: 'hidden',
+ display: 'none',
+ position: 'absolute',
+ top: 0,
+ left: 0
+ }
+ }).adopt(
+ new Element('div', {'class': 'tip-top'}),
+ this.container,
+ new Element('div', {'class': 'tip-bottom'})
+ ).inject(document.body);
+ },
+
+ attach: function(elements){
+ var read = function(option, element){
+ if (option == null) return '';
+ return $type(option) == 'function' ? option(element) : element.get(option);
+ };
+ $$(elements).each(function(element){
+ var title = read(this.options.title, element);
+ element.erase('title').store('tip:native', title).retrieve('tip:title', title);
+ element.retrieve('tip:text', read(this.options.text, element));
+
+ var events = ['enter', 'leave'];
+ if (!this.options.fixed) events.push('move');
+
+ events.each(function(value){
+ element.addEvent('mouse' + value, element.retrieve('tip:' + value, this['element' + value.capitalize()].bindWithEvent(this, element)));
+ }, this);
+ }, this);
+
+ return this;
+ },
+
+ detach: function(elements){
+ $$(elements).each(function(element){
+ ['enter', 'leave', 'move'].each(function(value){
+ element.removeEvent('mouse' + value, element.retrieve('tip:' + value) || $empty);
+ });
+
+ element.eliminate('tip:enter').eliminate('tip:leave').eliminate('tip:move');
+
+ if ($type(this.options.title) == 'string' && this.options.title == 'title'){
+ var original = element.retrieve('tip:native');
+ if (original) element.set('title', original);
+ }
+ }, this);
+
+ return this;
+ },
+
+ elementEnter: function(event, element){
+ $A(this.container.childNodes).each(Element.dispose);
+
+ ['title', 'text'].each(function(value){
+ var content = element.retrieve('tip:' + value);
+ if (!content) return;
+
+ this[value + 'Element'] = new Element('div', {'class': 'tip-' + value}).inject(this.container);
+ this.fill(this[value + 'Element'], content);
+ }, this);
+
+ this.timer = $clear(this.timer);
+ this.timer = this.show.delay(this.options.showDelay, this, element);
+ this.tip.setStyle('display', 'block');
+ this.position((!this.options.fixed) ? event : {page: element.getPosition()});
+ },
+
+ elementLeave: function(event, element){
+ $clear(this.timer);
+ this.tip.setStyle('display', 'none');
+ this.timer = this.hide.delay(this.options.hideDelay, this, element);
+ },
+
+ elementMove: function(event){
+ this.position(event);
+ },
+
+ position: function(event){
+ var size = window.getSize(), scroll = window.getScroll(),
+ tip = {x: this.tip.offsetWidth, y: this.tip.offsetHeight},
+ props = {x: 'left', y: 'top'},
+ obj = {};
+
+ for (var z in props){
+ obj[props[z]] = event.page[z] + this.options.offset[z];
+ if ((obj[props[z]] + tip[z] - scroll[z]) > size[z]) obj[props[z]] = event.page[z] - this.options.offset[z] - tip[z];
+ }
+
+ this.tip.setStyles(obj);
+ },
+
+ fill: function(element, contents){
+ if(typeof contents == 'string') element.set('html', contents);
+ else element.adopt(contents);
+ },
+
+ show: function(el){
+ this.fireEvent('show', [this.tip, el]);
+ },
+
+ hide: function(el){
+ this.fireEvent('hide', [this.tip, el]);
+ }
+
+});
+
+/*
+Script: Date.English.US.js
+ Date messages for US English.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Aaron Newton
+
+*/
+
+MooTools.lang.set('en-US', 'Date', {
+
+ months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+ days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
+ //culture's date order: MM/DD/YYYY
+ dateOrder: ['month', 'date', 'year'],
+ shortDate: '%m/%d/%Y',
+ shortTime: '%I:%M%p',
+ AM: 'AM',
+ PM: 'PM',
+
+ /* Date.Extras */
+ ordinal: function(dayOfMonth){
+ //1st, 2nd, 3rd, etc.
+ return (dayOfMonth > 3 && dayOfMonth < 21) ? 'th' : ['th', 'st', 'nd', 'rd', 'th'][Math.min(dayOfMonth % 10, 4)];
+ },
+
+ lessThanMinuteAgo: 'less than a minute ago',
+ minuteAgo: 'about a minute ago',
+ minutesAgo: '{delta} minutes ago',
+ hourAgo: 'about an hour ago',
+ hoursAgo: 'about {delta} hours ago',
+ dayAgo: '1 day ago',
+ daysAgo: '{delta} days ago',
+ lessThanMinuteUntil: 'less than a minute from now',
+ minuteUntil: 'about a minute from now',
+ minutesUntil: '{delta} minutes from now',
+ hourUntil: 'about an hour from now',
+ hoursUntil: 'about {delta} hours from now',
+ dayUntil: '1 day from now',
+ daysUntil: '{delta} days from now'
+
+});
+
+/*
+Script: FormValidator.English.js
+ Date messages for English.
+
+ License:
+ MIT-style license.
+
+ Authors:
+ Aaron Newton
+
+*/
+
+MooTools.lang.set('en-US', 'FormValidator', {
+
+ required:'This field is required.',
+ minLength:'Please enter at least {minLength} characters (you entered {length} characters).',
+ maxLength:'Please enter no more than {maxLength} characters (you entered {length} characters).',
+ integer:'Please enter an integer in this field. Numbers with decimals (e.g. 1.25) are not permitted.',
+ numeric:'Please enter only numeric values in this field (i.e. "1" or "1.1" or "-1" or "-1.1").',
+ digits:'Please use numbers and punctuation only in this field (for example, a phone number with dashes or dots is permitted).',
+ alpha:'Please use letters only (a-z) with in this field. No spaces or other characters are allowed.',
+ alphanum:'Please use only letters (a-z) or numbers (0-9) only in this field. No spaces or other characters are allowed.',
+ dateSuchAs:'Please enter a valid date such as {date}',
+ dateInFormatMDY:'Please enter a valid date such as MM/DD/YYYY (i.e. "12/31/1999")',
+ email:'Please enter a valid email address. For example "fred(a)domain.com".',
+ url:'Please enter a valid URL such as http://www.google.com.',
+ currencyDollar:'Please enter a valid $ amount. For example $100.00 .',
+ oneRequired:'Please enter something for at least one of these inputs.',
+ errorPrefix: 'Error: ',
+ warningPrefix: 'Warning: ',
+
+ //FormValidator.Extras
+
+ noSpace: 'There can be no spaces in this input.',
+ reqChkByNode: 'No items are selected.',
+ requiredChk: 'This field is required.',
+ reqChkByName: 'Please select a {label}.',
+ match: 'This field needs to match the {matchName} field',
+ startDate: 'the start date',
+ endDate: 'the end date',
+ currendDate: 'the current date',
+ afterDate: 'The date should be the same or after {label}.',
+ beforeDate: 'The date should be the same or before {label}.',
+ startMonth: 'Please select a start month',
+ sameMonth: 'These two dates must be in the same month - you must change one or the other.'
+
});
\ No newline at end of file
15 years, 2 months
rhmessaging commits: r3678 - store/trunk/java/bdbstore/src/tools/java/org/apache/qpid/server/store/berkeleydb.
by rhmessaging-commits@lists.jboss.org
Author: ritchiem
Date: 2009-10-22 10:27:01 -0400 (Thu, 22 Oct 2009)
New Revision: 3678
Modified:
store/trunk/java/bdbstore/src/tools/java/org/apache/qpid/server/store/berkeleydb/BDBStoreUpgrade.java
Log:
Set the CurrentActor to allow the VirtualHost to be created
Modified: store/trunk/java/bdbstore/src/tools/java/org/apache/qpid/server/store/berkeleydb/BDBStoreUpgrade.java
===================================================================
--- store/trunk/java/bdbstore/src/tools/java/org/apache/qpid/server/store/berkeleydb/BDBStoreUpgrade.java 2009-10-22 13:41:28 UTC (rev 3677)
+++ store/trunk/java/bdbstore/src/tools/java/org/apache/qpid/server/store/berkeleydb/BDBStoreUpgrade.java 2009-10-22 14:27:01 UTC (rev 3678)
@@ -27,6 +27,9 @@
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.BrokerActor;
+import org.apache.qpid.server.logging.NullRootMessageLogger;
import org.apache.qpid.AMQException;
import org.apache.qpid.util.FileUtils;
import org.apache.commons.cli.PosixParser;
@@ -328,6 +331,8 @@
}
}
+ CurrentActor.set(new BrokerActor(new NullRootMessageLogger()));
+
// Note the name of the Vhosts is not important, the store doesnot record the name of the vhost.
_newVirtualHost = new VirtualHost(new VirtualHostConfiguration("Upgraded", new PropertiesConfiguration()), new MemoryMessageStore());
_oldVirtualHost = new VirtualHost(new VirtualHostConfiguration("Old", new PropertiesConfiguration()), new MemoryMessageStore());
@@ -745,6 +750,7 @@
}
catch (Exception e)
{
+ e.printStackTrace();
_logger.error("Upgrade Failed: " + e.getMessage());
}
}
@@ -761,4 +767,5 @@
help();
System.exit(0);
}
+
}
15 years, 2 months
rhmessaging commits: r3677 - mgmt/trunk/cumin/python/cumin/messaging.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2009-10-22 09:41:28 -0400 (Thu, 22 Oct 2009)
New Revision: 3677
Modified:
mgmt/trunk/cumin/python/cumin/messaging/broker.py
Log:
Moved import of BrokerGroupInputSet
Modified: mgmt/trunk/cumin/python/cumin/messaging/broker.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/broker.py 2009-10-22 00:17:56 UTC (rev 3676)
+++ mgmt/trunk/cumin/python/cumin/messaging/broker.py 2009-10-22 13:41:28 UTC (rev 3677)
@@ -14,7 +14,6 @@
from connection import *
from brokerlink import LinkSet
-from brokergroup import BrokerGroupInputSet
strings = StringCatalog(__file__)
@@ -323,6 +322,7 @@
return fmt_link(href, name, class_)
+from brokergroup import BrokerGroupInputSet
class BrokerSetEngroupForm(CuminTaskForm):
def __init__(self, app, name, task):
super(BrokerSetEngroupForm, self).__init__(app, name, task)
15 years, 2 months