rhmessaging commits: r3944 - in mgmt/newdata/cumin/python/cumin: messaging and 1 other directory.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2010-04-30 12:47:11 -0400 (Fri, 30 Apr 2010)
New Revision: 3944
Modified:
mgmt/newdata/cumin/python/cumin/messaging/binding.py
mgmt/newdata/cumin/python/cumin/messaging/binding.strings
mgmt/newdata/cumin/python/cumin/messaging/exchange.py
mgmt/newdata/cumin/python/cumin/messaging/queue.py
mgmt/newdata/cumin/python/cumin/messaging/queue.strings
mgmt/newdata/cumin/python/cumin/widgets.py
mgmt/newdata/cumin/python/cumin/widgets.strings
Log:
Simplified the add binding form.
Added 'Add Binding' task to queue and exchange
Moved common classes to Widgets
Modified: mgmt/newdata/cumin/python/cumin/messaging/binding.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/binding.py 2010-04-29 19:08:54 UTC (rev 3943)
+++ mgmt/newdata/cumin/python/cumin/messaging/binding.py 2010-04-30 16:47:11 UTC (rev 3944)
@@ -360,183 +360,197 @@
return self.get(session) == "c"
class ExchangeKeysField(FormField):
- def __init__(self, app, name, vhost, title="Initial bindings:"):
+ def __init__(self, app, name, exchange):
super(ExchangeKeysField, self).__init__(app, name)
- assert vhost
+ self.title = "Initial bindings"
+ self.exchange = exchange
- self.vhost = vhost
+ name = StringParameter(app, "name")
+ self.names = ListParameter(app, "names", name)
+ self.add_parameter(self.names)
- self.dict_param = DictParameter(app, "exchange")
- self.add_parameter(self.dict_param)
+ value = StringParameter(app, "value")
+ self.values = ListParameter(app, "values", value)
+ self.add_parameter(self.values)
- self.direct_input = DirectExchangeInput(app, "direct")
- self.add_child(self.direct_input)
+ self.count = IntegerParameter(app, "count")
+ self.count.default = 3
+ self.add_parameter(self.count)
- self.topic_input = TopicExchangeInput(app, "topic")
- self.add_child(self.topic_input)
+ self.inputs_container_tmpl = WidgetTemplate(self, "input_container_html")
+ self.inputs_tmpl = WidgetTemplate(self, "inputs_html")
- self.fanout_input = FanoutExchangeInput(app, "fanout")
- self.add_child(self.fanout_input)
+ def init(self):
+ """ we added parameters directly to the FormField instead
+ of adding FormInputs. XXX should this logic be moved up to FormField? """
+ super(ExchangeKeysField, self).init()
+ for param in self.parameters:
+ self.form.form_params.add(param)
- self.xml_input = XMLExchangeInput(app, "xml")
- self.add_child(self.xml_input)
+ def render_title(self, session):
+ return self.title
- self.headers_input = HeadersExchangeInput(app, "headers")
- self.add_child(self.headers_input)
+ def render_input_fields(self, session, *args):
+ count = self.count.get(session)
+ writer = Writer()
+ for i in range(count):
+ self.inputs_tmpl.render(writer, session, i)
+ return writer.to_string()
- self.title = title
+ def render_inputs(self, session, *args):
+ writer = Writer()
+ self.inputs_container_tmpl.render(writer, session, *args)
+ return writer.to_string()
- self.binding_errors = self.Errors(self, "binding_errors")
- self.add_attribute(self.binding_errors)
+ def render_n_name(self, session, i):
+ return self.names.path
- self.state = ExchangeState(app, "phase")
- self.add_child(self.state)
+ def render_v_name(self, session, i):
+ return self.values.path
- class Errors(Attribute):
- def get_default(self, session):
- return dict()
+ def render_n_value(self, session, i):
+ names = self.names.get(session)
+ return len(names) > i and names[i] or ""
- def render_title(self, session):
- return self.title
+ def render_v_value(self, session, i):
+ values = self.values.get(session)
+ return len(values) > i and values[i] or ""
- def render_exchanges(self, session):
- vhost = self.vhost.get(session)
- cls = self.app.rosemary.org_apache_qpid_broker.Exchange
+ def get_exchange(self, session):
+ exchange_string = self.exchange.get(session)
+ if exchange_string:
+ obj = self.form.object.get(session)
+ cls = self.app.rosemary.org_apache_qpid_broker.Exchange
+ vhostid = obj._class._name == "Vhost" and obj._id or obj._vhostRef_id
+ exchanges = cls.get_selection(session.cursor, name=exchange_string, _vhostRef_id=vhostid)
+ if len(exchanges):
+ return exchanges[0]
+ return None
- exchanges = cls.get_selection(session.cursor, _vhostRef_id=vhost._id)
+ def get(self, session):
+ ret_dict = dict()
+ exchange = self.get_exchange(session)
+ if exchange:
+ if exchange.type == "headers" or exchange.type == "xml":
+ names = self.names.get(session)
+ values = self.values.get(session)
- # render each exchange we support
- writer = Writer()
+ for name, value in zip(names, values):
+ if name:
+ ret_dict[name] = value
+ return ret_dict
- for exchange in exchanges:
- if not ExchangeInfo.is_builtin(exchange):
- continue
+ def validate(self, session):
+ exchange = self.get_exchange(session)
+ names = self.names.get(session)
+ values = self.values.get(session)
- if exchange._qmf_delete_time:
- continue
+ if exchange:
+ if exchange.type == "headers":
+ if not "x-match" in names:
+ error = FormError("x-match argument is required for this exchange")
+ self.form.errors.add(session, error)
- # if self.state.is_active(session) and not is_active(exchange):
- # continue
+ for i in range(len(names)):
+ if names[i]:
+ if names[i] == "x-match":
+ if not values[i] == "all" and not values[i] == "any":
+ error = FormError("Argument name x-match must have a value of <i>all</i> or <i>any</i>")
+ self.form.errors.add(session, error)
+ else:
+ if not values[i]:
+ error = FormError("Missing argument value for name: %s" % names[i])
+ self.form.errors.add(session, error)
- if exchange.name == "qpid.management":
- continue
+ for i in range(len(values)):
+ if values[i]:
+ if not names[i]:
+ error = FormError("Missing argument name for value: %s" % values[i])
+ self.form.errors.add(session, error)
- # XXX
- # if ExchangeInfo.is_builtin(exchange) or \
- # (not exchange._qmf_delete_time and \
- # not (self.state.is_active(session) and not is_active(exchange))):
+ elif exchange.type == "xml":
+ if not "xquery" in names:
+ error = FormError("xquery argument is required for this exchange")
+ self.form.errors.add(session, error)
- # instance_key gives us a unique path for each exchange
- # we will be rendering
+class BindingAddForm(ObjectTaskForm):
+ def __init__(self, app, name, task):
+ super(BindingAddForm, self).__init__(app, name, task)
- instance_key = self.dict_param.get_instance_key(str(exchange._id))
+ self.queue = Parameter(app, "queue")
+ self.add_parameter(self.queue)
+ self.q_field = QueueBindingField(app, "q_field", self.queue)
+ self.add_field(self.q_field)
- if exchange.type == "direct" and exchange.name:
- self.direct_input.set_instance_data(exchange, instance_key)
- writer.write(self.direct_input.render(session, exchange))
- elif exchange.type == "topic":
- self.topic_input.set_instance_data(exchange, instance_key)
- writer.write(self.topic_input.render(session, exchange))
- elif exchange.type == "fanout":
- self.fanout_input.set_instance_data(exchange, instance_key)
- writer.write(self.fanout_input.render(session, exchange))
- elif exchange.type == "xml":
- self.xml_input.set_instance_data(exchange, instance_key)
- writer.write(self.xml_input.render(session, exchange))
- elif exchange.type == "headers":
- self.headers_input.set_instance_data(exchange, instance_key)
- writer.write(self.headers_input.render(session, exchange))
+ self.exchange = Parameter(app, "exchange")
+ self.add_parameter(self.exchange)
+ self.x_field = ExchangeBindingField(app, "x_field", self.exchange)
+ self.add_field(self.x_field)
- return writer.to_string()
+ self.key = self.KeyField(app, "key")
+ self.add_field(self.key)
- def get_binding_errors(self, session, queue_name):
- form_binding_info = self.process_binding_info(session, queue_name)
- binding_info = self.dict_param.get(session)
- berrs = self.binding_errors.get(session)
+ self.bindings = self.ExchangeBindings(app, "bindings", self.exchange)
+ self.add_field(self.bindings)
- for exchange in form_binding_info:
- type = form_binding_info[exchange]["type"]
- if (type == "topic") or (type == "direct"):
- try:
- val = form_binding_info[exchange]["key"]
- if not val:
- raise KeyError
- except KeyError:
- name = form_binding_info[exchange]["name"]
- errs = berrs.setdefault(name, list())
- errs.append("A binding key is required")
- elif type == "headers":
- try:
- val = form_binding_info[exchange]["key"]
- if not val:
- raise KeyError
- except KeyError:
- name = form_binding_info[exchange]["name"]
- errs = berrs.setdefault(name, dict())
- errs["key"] = ["A binding key is required"]
- for key_num in ("1", "2", "3"):
- mkey = "mkey."+key_num
- mkeynv = mkey+".nv"
- if mkeynv in binding_info[exchange] and binding_info[exchange][mkeynv]:
- try:
- val = binding_info[exchange][mkey]
- if not val:
- raise KeyError
- except KeyError:
- name = binding_info[exchange]["name"]
- if not name in berrs:
- berrs.setdefault(name, dict())
- berrs[name][mkey] = ["Missing key"]
- elif type == "xml":
- try:
- val = form_binding_info[exchange]["key"]
- if not val:
- raise KeyError
- except KeyError:
- name = form_binding_info[exchange]["name"]
- errs = berrs.setdefault(name, dict())
- errs["key"] = ["A binding key is required"]
- try:
- val = binding_info[exchange]["xquery"]
- if not val:
- raise KeyError
- except KeyError:
- name = binding_info[exchange]["name"]
- if not name in berrs:
- berrs.setdefault(name, dict())
- berrs[name]["xquery"] = ["Missing xquery"]
+ def init(self):
+ super(BindingAddForm, self).init()
+ self.form_params.add(self.queue)
+ self.form_params.add(self.exchange)
- return (len(berrs), form_binding_info)
+ def render_title(self, session):
+ return self.task.get_description(session)
- def process_binding_info(self, session, queue_name):
- """ Processes the raw binding_info from the DictParameter into
- a "form_binding_info" dictionary that contains four keys:
- name, key, arguments, and type
- """
- binding_info = self.dict_param.get(session)
- form_binding_info = dict()
- for this_exchange in binding_info:
- # if the exchange checkbox is checked
- if "name" in binding_info[this_exchange]:
- type = binding_info[this_exchange]["type"]
- #if type == "direct":
- # binding_info[this_exchange]["key"] = queue_name
+ def render_key_id(self, session):
+ return self.key.path
- form_binding_info[this_exchange] = dict()
- form_binding_info[this_exchange]["name"] = binding_info[this_exchange]["name"]
- if "key" in binding_info[this_exchange] and binding_info[this_exchange]["key"]:
- form_binding_info[this_exchange]["key"] = binding_info[this_exchange]["key"]
- form_binding_info[this_exchange]["type"] = type
+ def validate(self, session):
+ super(BindingAddForm, self).validate(session)
- arguments = dict()
- if type == "headers":
- self.headers_input.process_input(binding_info[this_exchange], arguments)
- elif type == "xml":
- self.xml_input.process_input(binding_info[this_exchange], arguments)
- #direct, topic and fanout exchanges don't have aditional arguments
- form_binding_info[this_exchange]["arguments"] = arguments
+ queue = self.queue.get(session)
+ exchange = self.bindings.get_exchange(session)
+ key = self.key.get(session)
- return form_binding_info
+ if not queue:
+ error = FormError("A valid queue name is required")
+ self.errors.add(session, error)
+ if not exchange:
+ error = FormError("A valid exchange name is required")
+ self.errors.add(session, error)
+ else:
+ if not exchange.type == "fanout":
+ if not key:
+ error = MissingValueError(self.key)
+ self.errors.add(session, error)
-from exchange import ExchangeInfo
+ def process_submit(self, session):
+ self.validate(session)
+ if not self.errors.get(session):
+ queue = self.queue.get(session)
+ exchange = self.exchange.get(session)
+ key = self.key.get(session)
+ arguments = self.bindings.get(session)
+ obj = self.object.get(session)
+
+ self.task.invoke(session, obj, queue, exchange, key, arguments)
+ self.task.exit_with_redirect(session)
+
+ class KeyField(StringField):
+ def render_row_id(self, session):
+ return "id='%s'" % self.path
+
+ def render_title(self, session):
+ return "Binding Key"
+
+ class ExchangeBindings(ExchangeKeysField):
+ def render_id(self, session, *args):
+ s = fmt_bytes(1)
+ cls = "ExchangeHiddenRow"
+ exchange = self.exchange.get(session)
+ if exchange and exchange.type == 'headers':
+ cls = ""
+ return cls and "%s\" class=\"%s" % (self.path, cls) or self.path
+
+ def render_title(self, session):
+ return "Arguments"
Modified: mgmt/newdata/cumin/python/cumin/messaging/binding.strings
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/binding.strings 2010-04-29 19:08:54 UTC (rev 3943)
+++ mgmt/newdata/cumin/python/cumin/messaging/binding.strings 2010-04-30 16:47:11 UTC (rev 3944)
@@ -16,172 +16,25 @@
left outer join binding_stats as c on c.id = b.stats_curr_id
{sql_where}
-[ExchangeInput.name_html]
-<td>
- <input type="checkbox" id="{id}.{exchange_id}" name="{name_path}"
- value="{exchange_name}" size="15" tabindex="100" {exchange_checked}
- {onclick} />
- <input type="hidden" name="{exchange_type_path}" value="{exchange_type}" />
-</td>
-<td><label class="exchange_name" for="{id}.{exchange_id}">{exchange_fmt_name}</label></td>
-<td class="exchange_type">{exchange_type}</td>
-
-[ExchangeInput.key_html]
-<td>
- <input type="text" name="{key_path}" id="{exchange_name}"
- value="{key_value}" size="32" maxlength="256" tabindex="100" />
- {key_error}
-</td>
-
-[DirectExchangeInput.html]
-<tr>
- {exchange_name_input}
- {exchange_key_input}
-</tr>
-
-[TopicExchangeInput.html]
-<tr>
- {exchange_name_input}
- {exchange_key_input}
-</tr>
-
-[FanoutExchangeInput.html]
-<tr>
- {exchange_name_input}
- <td> </td>
-</tr>
-
-[XMLExchangeInput.html]
-<tr>
- {exchange_name_input}
- {exchange_key_input}
-</tr>
-<tr id="{xml_extra}" class="{headers_class}">
- <td colspan="4"><table>
- <tr>
- <td>XQuery:</td>
- <td colspan="3"><textarea name="{xquery_path}" id="{exchange_name}" tabindex="100" rows="4" cols="40">{xquery_value}</textarea>{xquery_error}</td>
- </tr>
- </table></td>
-</tr>
-
-[HeadersExchangeInput.html]
-<tr>
- {exchange_name_input}
- {exchange_key_input}
-</tr>
-<tr id="{headers_extra}" class="{headers_class}">
- <td colspan="4"><table>
- <tr>
- <td> </td>
- <td>x-match Type:</td>
- <td colspan="2">
- <input type="radio" id="headers.x-match.all" name="{x_match_path}" value="all" {all_checked}/>
- <label for="headers.x-match.all">All</label>
- <input type="radio" id="headers.x-match.any" name="{x_match_path}" value="any" {any_checked}/>
- <label for="headers.x-match.any">Any</label>
- </td>
- </tr>
- <tr>
- <td> </td>
- <td>Match Keys:</td>
- <td colspan="2">
- <table class="xmlExchange">
- <thead>
- <tr>
- <th>Key</th><th>type, value</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><input type="text" name="{mkey_path}.1" value="{mkey1_value}" tabindex="100" />{mkey1_error}</td>
- <td><input type="text" name="{mkey_path}.1.nv" value="{mnv1_value}" tabindex="100" /></td>
- </tr>
- <tr>
- <td><input type="text" name="{mkey_path}.2" value="{mkey2_value}" tabindex="100" />{mkey2_error}</td>
- <td><input type="text" name="{mkey_path}.2.nv" value="{mnv2_value}" tabindex="100" /></td>
- </tr>
- <tr>
- <td><input type="text" name="{mkey_path}.3" value="{mkey3_value}" tabindex="100" />{mkey3_error}</td>
- <td><input type="text" name="{mkey_path}.3.nv" value="{mnv3_value}" tabindex="100" /></td>
- </tr>
- </tbody>
- </table>
- </td>
- </tr>
-</table></td></tr>
-
[ExchangeKeysField.css]
-table.FormFieldSet div.inputs {
- position: relative;
- left: -4em;
-}
-
-td.exchange_type {
- font-style: italic;
-}
-
-table.mobjects tr#headers_extra {
- border-top: 0px;
-}
-
-table.mobjects tr.initial_header_state {
- display:none;
-}
-
-table.xmlExchange {
- border-collapse: collapse;
- border: 1px dotted #ccc;
- margin: 0;
-}
-
-table.xmlExchange tr {
- border-top: 0px solid #fff;
-}
-
-table.mobjects label.exchange_name {
+table th.NameHeader {
+ color: red;
+ font-size: 0.8em;
font-weight: bold;
+ text-align: left;
}
-table.mobjects td.exchange_type, table.mobjects th.exchange_type {
- font-style: italic;
-}
+[ExchangeKeysField.input_container_html]
+<table>
+ <tr>
+ <th class="NameHeader">Name</th>
+ <th class="NameHeader">Value</th>
+ </tr>
+ {input_fields}
+</table>
-[ExchangeKeysField.javascript]
-function toggle_row(chk, row_id) {
- var display = "none";
- var headers_extra = document.getElementById(row_id);
-
- if (chk.checked) {
- display = "table-row";
- }
-
- headers_extra.style.display = display;
-}
-
-[ExchangeKeysField.html]
+[ExchangeKeysField.inputs_html]
<tr>
- <th>
- <div class="title">{title}</div>
- <div class="help">{help}</div>
- </th>
- <td>
- <div class="rfloat">{phase}</div>
- <div class="rclear"> </div>
-
- <div class="inputs">
- <table class="mobjects" id="exchange_types">
- <thead>
- <tr>
- <th colspan="2"><label class="exchange_name">Exchange Name</label></th>
- <th class="exchange_type">Exchange Type</th>
- <th>Binding Key</th>
- </tr>
- </thead>
- <tbody>
- {exchanges}
- </tbody>
- </table>
- </div>
- </td>
+ <td><input class="NameInput" type="text" size="15" name="{n_name}" value="{n_value}" tabindex="100"/> = </td>
+ <td><input class="ValueInput" type="text" size="15" name="{v_name}" value="{v_value}" tabindex="100"/></td>
</tr>
Modified: mgmt/newdata/cumin/python/cumin/messaging/exchange.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/exchange.py 2010-04-29 19:08:54 UTC (rev 3943)
+++ mgmt/newdata/cumin/python/cumin/messaging/exchange.py 2010-04-30 16:47:11 UTC (rev 3944)
@@ -33,6 +33,7 @@
self.view.add_tab(self.bindings)
self.remove = ExchangeRemove(app, self)
+ self.add_binding = ExchangeBindingAdd(app, self)
def get_title(self, session):
title = super(ExchangeFrame, self).get_title(session)
@@ -56,6 +57,18 @@
invoc.end()
+class ExchangeBindingAdd(BindingAddTask):
+ def __init__(self, app, frame):
+ super(ExchangeBindingAdd, self).__init__(app, frame)
+
+ self.form = ExchangeBindingAddForm(app, self.name, self)
+
+class ExchangeBindingAddForm(BindingAddForm):
+ def __init__(self, app, name, task):
+ super(ExchangeBindingAddForm, self).__init__(app, name, task)
+
+ self.x_field.input.disabled = True
+
class ExchangeSelector(ObjectSelector):
def __init__(self, app, name, vhost):
cls = app.rosemary.org_apache_qpid_broker.Exchange
Modified: mgmt/newdata/cumin/python/cumin/messaging/queue.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/queue.py 2010-04-29 19:08:54 UTC (rev 3943)
+++ mgmt/newdata/cumin/python/cumin/messaging/queue.py 2010-04-30 16:47:11 UTC (rev 3944)
@@ -15,7 +15,7 @@
from cumin.widgets import *
from binding import *
-from exchange import *
+
from subscription import *
strings = StringCatalog(__file__)
@@ -45,6 +45,7 @@
self.remove = QueueRemove(app, self)
self.purge = QueuePurge(app, self)
self.move_messages = MoveQueueMessages(app, self)
+ self.add_binding = QueueBindingAdd(app, self)
class QueueRemove(ObjectTask):
def get_title(self, session):
@@ -119,6 +120,15 @@
def get_title(self, session):
return "Add queue"
+ def do_invoke(self, invoc, queue, name, durable, args):
+ session = self.app.model.get_session_by_object(queue)
+ session.queue_declare(queue=name,
+ durable=durable,
+ arguments=args)
+ session.sync()
+
+ invoc.end()
+
class QueueAddForm(ObjectTaskForm):
def __init__(self, app, name, task):
super(QueueAddForm, self).__init__(app, name, task)
@@ -126,12 +136,6 @@
self.namef = NameField(app, "name")
self.add_field(self.namef)
- self.more = self.AdvancedOptions(app, "more")
- self.add_field(self.more)
-
- self.bindings = ExchangeKeysField(app, "bindings", self.object)
- self.add_field(self.bindings)
-
self.durable = self.QueueDurabilityField(app, "durable")
self.add_extra_field(self.durable)
@@ -320,63 +324,30 @@
self.validate(session)
errors = self.errors.get(session)
-
- binding_errors, binding_info = self.bindings.get_binding_errors \
- (session, name)
-
if not errors:
- errors = binding_errors
+ args = dict()
- if not errors:
- invoc = self.task.start(session, vhost)
+ if durable:
+ args["qpid.file_count"] = self.file_count.get(session)
+ args["qpid.file_size"] = self.file_size.get(session)
- try:
- args = dict()
+ if policy != "none":
+ args["qpid.policy_type"] = policy
+ args["qpid.max_size"] = self.q_size.get(session)
+ args["qpid.max_count"] = self.q_count.get(session)
- if durable:
- args["qpid.file_count"] = self.file_count.get(session)
- args["qpid.file_size"] = self.file_size.get(session)
+ args["qpid.persist_last_node"] = \
+ self.cluster_durable.get(session) == "yes"
- if policy != "none":
- args["qpid.policy_type"] = policy
- args["qpid.max_size"] = self.q_size.get(session)
- args["qpid.max_count"] = self.q_count.get(session)
+ args["qpid.last_value_queue"] = \
+ self.lvq.get(session) == "enable"
- args["qpid.persist_last_node"] = \
- self.cluster_durable.get(session) == "yes"
+ args["qpid.optimistic_consume"] = \
+ self.optimistic.get(session) == "yes"
- args["qpid.last_value_queue"] = \
- self.lvq.get(session) == "enable"
+ self.task.invoke(session, vhost, name, durable, args)
+ self.task.exit_with_redirect(session)
- args["qpid.optimistic_consume"] = \
- self.optimistic.get(session) == "yes"
-
- qsession = self.app.model.get_session_by_object(vhost)
-
- qsession.queue_declare(queue=name,
- durable=durable,
- arguments=args)
-
- for exchange in binding_info:
- if "key" in binding_info[exchange]:
- binding_key = binding_info[exchange]["key"]
- else:
- binding_key = None
-
- ename = binding_info[exchange]["name"]
- eargs = binding_info[exchange]["arguments"]
-
- qsession.exchange_bind(queue=name,
- exchange=ename,
- binding_key=binding_key,
- arguments=eargs)
-
- invoc.end()
- except Exception, e:
- self.task.exception(invoc, e)
-
- self.process_return(session)
-
class QueuePurge(ObjectTask):
def __init__(self, app, frame):
super(QueuePurge, self).__init__(app, frame)
@@ -416,71 +387,18 @@
self.task.invoke(session, queue, count)
self.task.exit_with_redirect(session)
-class BindSummaryPropertiesField(FormField):
- def __init__(self, app, name, queue):
- super(BindSummaryPropertiesField, self).__init__(app, name)
+class QueueBindingAdd(BindingAddTask):
+ def __init__(self, app, frame):
+ super(QueueBindingAdd, self).__init__(app, frame)
- self.sum_props = self.SummaryProperties(app, "properties", queue)
- self.add_child(self.sum_props)
+ self.form = QueueBindingAddForm(app, self.name, self)
- self.prop_tmpl = WidgetTemplate(self, "properties_html")
-
- class SummaryProperties(CuminProperties):
- def do_get_items(self, session):
- queue = self.object.get(session)
-
- return [("Name", queue.name),
- ("Durable", queue.durable),
- ("Exclusive", queue.exclusive),
- ("Auto-Delete", queue.autoDelete)]
-
- def render_inputs(self, session):
- writer = Writer()
- self.prop_tmpl.render(writer, session)
- return writer.to_string()
-
- def render_prop_items(self, session):
- return self.sum_props.render_items(session)
-
-class BindingAddForm(ObjectTaskForm):
+class QueueBindingAddForm(BindingAddForm):
def __init__(self, app, name, task):
- super(BindingAddForm, self).__init__(app, name, task)
+ super(QueueBindingAddForm, self).__init__(app, name, task)
- self.vhost = self.VhostAttribute(app, "vhost")
- self.add_attribute(self.vhost)
+ self.q_field.input.disabled = True
- self.props = BindSummaryPropertiesField(app, "props", self.object)
- self.add_field(self.props)
-
- self.bindings = self.ExchangeBindings(app, "bindings", self.vhost)
- self.add_field(self.bindings)
-
- class ExchangeBindings(ExchangeKeysField):
- def render_title(self, session):
- return "Exchange Bindings"
-
- class VhostAttribute(Attribute):
- def get(self, session):
- return self.widget.object.get(session).vhost
-
- def process_submit(self, session):
- queue = self.object.get(session)
-
- errors, form_binding_info = self.bindings.get_binding_errors \
- (session, queue.name)
-
- if not len(form_binding_info):
- # no exchanges were selected is not an error that
- # ExchangeKeysField looks for
- error = FormError("At least one exchange must be selected")
- self.errors.add(session, error)
-
- if not self.errors.get(session):
- print "XXX queue binding add", queue, form_binding_info
-
- #self.task.invoke(session, queue, args)
- self.task.exit_with_redirect(session)
-
class QueueOverview(RadioModeSet):
def __init__(self, app, name, queue):
super(QueueOverview, self).__init__(app, name)
@@ -634,10 +552,10 @@
return "Transactional messages enqueued and dequeued"
class QueueSelectField(FormField):
- def __init__(self, app, name, form):
+ def __init__(self, app, name, form, param):
super(QueueSelectField, self).__init__(app, name)
- self.param = self.QueueSearchInputSet(app, "queue_set")
+ self.param = self.QueueSearchInputSet(app, "queue_set", param)
self.add_child(self.param)
def get(self, session):
@@ -673,6 +591,9 @@
def render_item_content(self, session, queue):
return queue.name or "<em>Default</em>"
+ def render_item_value(self, session, queue):
+ return queue._id
+
class MoveMessagesBase(ObjectTask):
def get_title(self, session):
return "Move messages"
@@ -706,7 +627,8 @@
self.src_queue = src_queue
self.add_field(src_queue)
- self.dest_queue = self.QueueDestField(app, "dest", self)
+ queue = QueueParameter(app, "dqueue")
+ self.dest_queue = self.QueueDestField(app, "dest", self, queue)
self.dest_queue.required = True
self.add_field(self.dest_queue)
@@ -743,7 +665,8 @@
class MoveMessagesForm(MoveMessagesFormBase):
def __init__(self, app, name, task):
- src_queue = self.QueueSrctField(app, "src", self)
+ queue = QueueParameter(app, "queue")
+ src_queue = self.QueueSrctField(app, "src", self, queue)
src_queue.required = True
super(MoveMessagesForm, self).__init__(app, name, task, src_queue)
Modified: mgmt/newdata/cumin/python/cumin/messaging/queue.strings
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/queue.strings 2010-04-29 19:08:54 UTC (rev 3943)
+++ mgmt/newdata/cumin/python/cumin/messaging/queue.strings 2010-04-30 16:47:11 UTC (rev 3944)
@@ -81,12 +81,3 @@
</tr>
</tbody>
</table>
-
-[BindSummaryPropertiesField.properties_html]
-<div class="properties" style="width:80%">
- <table class="PropertySet">
- <tbody>
- {prop_items}
- </tbody>
- </table>
-</div>
Modified: mgmt/newdata/cumin/python/cumin/widgets.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/widgets.py 2010-04-29 19:08:54 UTC (rev 3943)
+++ mgmt/newdata/cumin/python/cumin/widgets.py 2010-04-30 16:47:11 UTC (rev 3944)
@@ -1441,12 +1441,103 @@
writer.write("</data>")
class IncrementalSearchInput(StringInput, ItemSet):
+ def __init__(self, app, name, field_param):
+ super(IncrementalSearchInput, self).__init__(app, name)
+
+ self.disabled_tmpl = WidgetTemplate(self, "disabled_html")
+ self.field = field_param
+
def do_get_items(self, session):
return ()
- def render_item_class(self, session, item):
- return "list_item"
+ def render_name(self, session):
+ return self.field.path
+ def do_render(self, session, *args):
+ if self.disabled:
+ writer = Writer()
+
+ self.disabled_tmpl.render(writer, session, *args)
+
+ return writer.to_string()
+ else:
+ return super(IncrementalSearchInput, self).do_render(session, *args)
+
+class BaseBindingInput(IncrementalSearchInput):
+ def __init__(self, app, name, field_param):
+ super(BaseBindingInput, self).__init__(app, name, field_param)
+
+ def render_item_content(self, session, field):
+ return field.name or "Default"
+
+ def render_value(self, session):
+ if self.disabled:
+ field = self.form.object.get(session)
+ return fmt_shorten(field.name, pre=36, post=4)
+ else:
+ input_value = self.param.get(session)
+ return input_value and input_value or ""
+
+ def base_get_items(self, session, objects):
+ obj_list = []
+ if not self.disabled:
+ obj_list_full = sorted_by(list(objects))
+
+ delta = timedelta(minutes=10)
+ for _obj in obj_list_full:
+ if (_obj._qmf_update_time > (datetime.now() - delta)):
+ obj_list.append(_obj)
+
+ return obj_list
+
+class BindingAddTask(ObjectTask):
+ def get_title(self, session):
+ return "Add Binding"
+
+ def do_invoke(self, invoc, obj, queue, exchange, key, args):
+ session = self.app.model.get_session_by_object(obj)
+ session.exchange_bind(queue=queue, exchange=exchange,
+ binding_key=key, arguments=args)
+ session.sync()
+
+ invoc.end()
+
+class QueueBindingField(ScalarField):
+ def __init__(self, app, name, queue):
+ super(QueueBindingField, self).__init__(app, name, None)
+
+ self.input = QueueInput(app, "input", queue)
+ self.add_child(self.input)
+
+ def render_title(self, session):
+ return "Queue"
+
+class ExchangeBindingField(ScalarField):
+ def __init__(self, app, name, exchange):
+ super(ExchangeBindingField, self).__init__(app, name, None)
+
+ self.input = ExchangeInput(app, "input", exchange)
+ self.add_child(self.input)
+
+ def render_title(self, session):
+ return "Exchange"
+
+class QueueInput(BaseBindingInput):
+ def do_get_items(self, session):
+ cls = self.app.rosemary.org_apache_qpid_broker.Queue
+ queue = self.form.object.get(session)
+ vhostid = queue._vhostRef_id
+ queues = cls.get_selection(session.cursor, _vhostRef_id=vhostid)
+ return self.base_get_items(session, queues)
+
+class ExchangeInput(BaseBindingInput):
+ def do_get_items(self, session):
+ cls = self.app.rosemary.org_apache_qpid_broker.Exchange
+ obj = self.form.object.get(session)
+ vhostid = obj._class._name == "Vhost" and obj._id or obj._vhostRef_id
+ exchanges = cls.get_selection(session.cursor, _vhostRef_id=vhostid)
+ return self.base_get_items(session, exchanges)
+
class TopTable(DataTable):
def __init__(self, app, name, adapter):
super(TopTable, self).__init__(app, name, adapter)
Modified: mgmt/newdata/cumin/python/cumin/widgets.strings
===================================================================
--- mgmt/newdata/cumin/python/cumin/widgets.strings 2010-04-29 19:08:54 UTC (rev 3943)
+++ mgmt/newdata/cumin/python/cumin/widgets.strings 2010-04-30 16:47:11 UTC (rev 3944)
@@ -804,20 +804,55 @@
background-color: #fff;
}
+[IncrementalSearchInput.javascript]
+addJavascript('resource?name=incrementalSearch.js', 'head');
+
[IncrementalSearchInput.css]
-div.IncrementalSearchInput ul {
+div.IncrementalSearchInput select {
display: none;
}
+div.IncrementalSearchInput input.disabled {
+ background:white;
+ color:black;
+ border: 0px solid white;
+ cursor:default;
+}
[IncrementalSearchInput.html]
<div class="IncrementalSearchInput">
-<input id="{id}" type="text" name="{name}" value="{value}" tabindex="{tab_index}" {disabled_attr} size="{size}" autocomplete="off"/>
-<ul id="{id}.list">{items}</ul>
+ <input id="{id}" type="text" name="{name}" value="{value}" tabindex="{tab_index}" size="{size}" autocomplete="off"/>
+ <select id="{id}.list">{items}</select>
</div>
<script type="text/javascript">
//<![CDATA[
-window.addEvent("domready", function () {
- new IncrementalSearch($("{id}"), Inc_CIBeginning, "autocomplete", "{id}.list", 8); });
+window.addEvent("domready",
+ function () {
+ new IncrementalSearch($("{id}"), Inc_CIBeginning, "autocomplete", "{id}.list", 8);
+ }
+);
//]]>
</script>
+[IncrementalSearchInput.item_html]
+<option value="{item_value}">{item_content}</option>
+
+[IncrementalSearchInput.disabled_html]
+<div class="IncrementalSearchInput">
+<input class="disabled" id="{name}" name="{name}" value="{value}" tabindex="{tab_index}" size="{size}" />
+</div>
+<script type="text/javascript">
+//<![CDATA[
+// Using input attribute disabled="disabled' has the unfortunate side effect of not sending the input value
+// when the form is submitted. So we just leave it enabled and filter out keyboard input with javascript.
+window.addEvent("domready",
+ function () {
+ $("{name}").addEvent("keypress",
+ function (e) {
+ if (!(e.key in {tab:1, left:1, right:1}))
+ if (! (e.key == 'c' && e.control) )
+ new Event(e).stop();
+ } )
+ }
+);
+//]]>
+</script>
14 years, 8 months
rhmessaging commits: r3943 - store/trunk/cpp/tools.
by rhmessaging-commits@lists.jboss.org
Author: kpvdr
Date: 2010-04-29 15:08:54 -0400 (Thu, 29 Apr 2010)
New Revision: 3943
Modified:
store/trunk/cpp/tools/Makefile.am
Log:
Added missing SCRIPTS to Makefile.am
Modified: store/trunk/cpp/tools/Makefile.am
===================================================================
--- store/trunk/cpp/tools/Makefile.am 2010-04-28 13:25:26 UTC (rev 3942)
+++ store/trunk/cpp/tools/Makefile.am 2010-04-29 19:08:54 UTC (rev 3943)
@@ -20,7 +20,7 @@
# The GNU Lesser General Public License is available in the file COPYING.
qpidexecdir = $(libexecdir)/qpid
-qpidexec_SCRIPTS = jrnl.py resize store_chk
+qpidexec_SCRIPTS = jerr.py jrnl.py janal.py resize store_chk
EXTRA_DIST = \
jerr.py \
14 years, 8 months
rhmessaging commits: r3942 - in store/trunk/cpp: tests and 1 other directory.
by rhmessaging-commits@lists.jboss.org
Author: kpvdr
Date: 2010-04-28 09:25:26 -0400 (Wed, 28 Apr 2010)
New Revision: 3942
Modified:
store/trunk/cpp/lib/MessageStoreImpl.cpp
store/trunk/cpp/tests/system_test.sh
Log:
Updated PYTHONPATH in one of the old python tests to point to new qmf location
Modified: store/trunk/cpp/lib/MessageStoreImpl.cpp
===================================================================
--- store/trunk/cpp/lib/MessageStoreImpl.cpp 2010-04-26 20:26:08 UTC (rev 3941)
+++ store/trunk/cpp/lib/MessageStoreImpl.cpp 2010-04-28 13:25:26 UTC (rev 3942)
@@ -1368,7 +1368,7 @@
u_int64_t queueId (queue.getPersistenceId());
u_int64_t messageId (msg->getPersistenceId());
if (messageId == 0) {
- THROW_STORE_EXCEPTION("Error dequeing message, persistence id not set");
+ THROW_STORE_EXCEPTION("Error dequeuing message, persistence id not set");
}
if (queueId == 0) {
THROW_STORE_EXCEPTION("Queue not created: " + queue.getName());
Modified: store/trunk/cpp/tests/system_test.sh
===================================================================
--- store/trunk/cpp/tests/system_test.sh 2010-04-26 20:26:08 UTC (rev 3941)
+++ store/trunk/cpp/tests/system_test.sh 2010-04-28 13:25:26 UTC (rev 3942)
@@ -32,7 +32,7 @@
xml_spec=$QPID_DIR/specs/amqp.0-10-qpid-errata.xml
test -f $xml_spec || error "$xml_spec not found: invalid \$QPID_DIR ?"
-export PYTHONPATH=$QPID_DIR/python
+export PYTHONPATH=$QPID_DIR/python:$QPID_DIR/extras/qmf/src/py
echo "Using directory $TMP_DATA_DIR"
14 years, 8 months
rhmessaging commits: r3941 - mgmt/newdata/cumin/python/cumin.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2010-04-26 16:26:08 -0400 (Mon, 26 Apr 2010)
New Revision: 3941
Modified:
mgmt/newdata/cumin/python/cumin/widgets.py
Log:
Added missing import of objectselector
Modified: mgmt/newdata/cumin/python/cumin/widgets.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/widgets.py 2010-04-26 20:22:26 UTC (rev 3940)
+++ mgmt/newdata/cumin/python/cumin/widgets.py 2010-04-26 20:26:08 UTC (rev 3941)
@@ -9,6 +9,7 @@
from mint.schema import *
from objecttask import *
+from objectselector import *
from parameters import *
from widgets import *
from charts import *
14 years, 8 months
rhmessaging commits: r3940 - mgmt/newdata/wooly/resources.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2010-04-26 16:22:26 -0400 (Mon, 26 Apr 2010)
New Revision: 3940
Removed:
mgmt/newdata/wooly/resources/mootools-more.js
Log:
Comsolidated mootools into 1 file
Deleted: mgmt/newdata/wooly/resources/mootools-more.js
===================================================================
--- mgmt/newdata/wooly/resources/mootools-more.js 2010-04-26 20:18:43 UTC (rev 3939)
+++ mgmt/newdata/wooly/resources/mootools-more.js 2010-04-26 20:22:26 UTC (rev 3940)
@@ -1,3005 +0,0 @@
-//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
14 years, 8 months
rhmessaging commits: r3939 - mgmt/newdata/cumin/resources.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2010-04-26 16:18:43 -0400 (Mon, 26 Apr 2010)
New Revision: 3939
Modified:
mgmt/newdata/cumin/resources/app.css
Log:
Make the incremental search dropdown the same size as the associated edit field
Modified: mgmt/newdata/cumin/resources/app.css
===================================================================
--- mgmt/newdata/cumin/resources/app.css 2010-04-26 20:18:07 UTC (rev 3938)
+++ mgmt/newdata/cumin/resources/app.css 2010-04-26 20:18:43 UTC (rev 3939)
@@ -621,8 +621,8 @@
border-top: none;
background: #fff;
z-index: 2;
- padding: 0 0.25em;
}
+.autocomplete div { padding: 0 0.2em; }
.autocomplete .normal{border-top: 1px solid #fefefe;}
.autocomplete .selected{background: #ddf;}
.autocomplete .highlited{font-weight: bold; color: #008;}
14 years, 8 months
rhmessaging commits: r3938 - mgmt/newdata/cumin/python/cumin/inventory.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2010-04-26 16:18:07 -0400 (Mon, 26 Apr 2010)
New Revision: 3938
Modified:
mgmt/newdata/cumin/python/cumin/inventory/system.py
Log:
TopQueue, TopSystems, TopSubmissions
Modified: mgmt/newdata/cumin/python/cumin/inventory/system.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/inventory/system.py 2010-04-26 20:17:25 UTC (rev 3937)
+++ mgmt/newdata/cumin/python/cumin/inventory/system.py 2010-04-26 20:18:07 UTC (rev 3938)
@@ -41,38 +41,6 @@
overview = SystemStats(app, "overview", self.object)
self.view.add_tab(overview)
-
-class TopSystemSet(TopTable):
- def __init__(self, app, name):
- super(TopSystemSet, self).__init__(app, name)
-
- col = self.NameColumn(app, "name")
- col.width = "60%"
- self.add_column(col)
-
- self.set_default_column(col)
-
- col = self.LoadColumn(app, "load")
- col.width = "35%"
- col.align = "right"
- self.add_column(col)
-
- class NameColumn(TopTableColumn):
- def render_title(self, session):
- return "Name"
-
- def render_content(self, session, data):
- system = Identifiable(data["id"])
- href = self.page.main.inventory.system.get_href(session, system)
- return fmt_link(href, data["name"], link_title=data["name"])
-
- class LoadColumn(TopTableColumn):
- def render_title(self, session):
- return "Load Average"
-
- def render_content(self, session, data):
- return "%0.3f" % data["load_avg"]
-
class SystemGeneralStatSet(StatSet):
def __init__(self, app, name, object):
super(SystemGeneralStatSet, self).__init__(app, name, object)
14 years, 8 months
rhmessaging commits: r3937 - mgmt/newdata/cumin/python/cumin/messaging.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2010-04-26 16:17:25 -0400 (Mon, 26 Apr 2010)
New Revision: 3937
Modified:
mgmt/newdata/cumin/python/cumin/messaging/broker.py
Log:
Broker Engroup
Modified: mgmt/newdata/cumin/python/cumin/messaging/broker.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/broker.py 2010-04-26 20:16:39 UTC (rev 3936)
+++ mgmt/newdata/cumin/python/cumin/messaging/broker.py 2010-04-26 20:17:25 UTC (rev 3937)
@@ -70,8 +70,6 @@
self.add_attribute_column(broker.port)
self.add_attribute_column(cluster.clusterName)
- #self.add_selection_task(app.messaging.BrokerEngroup)
-
def get_data_values(self, session):
values = super(BrokerSelector, self).get_data_values(session)
@@ -129,7 +127,10 @@
self.exchange_add = ExchangeAdd(app, self)
self.brokerlink_add = BrokerLinkAdd(app, self)
self.move_messages = MoveMessages(app, self)
+ self.engroup = BrokerEngroup(app, self)
+ #self.add_selection_task(app.messaging.BrokerEngroup)
+
def get_object(self, session, id):
# self.object is Vhost, and we stick Broker in self.broker
@@ -147,54 +148,8 @@
def get_title(self, session):
obj = self.broker.get(session)
-
return "%s '%s'" % (obj._class._title, obj.get_title())
-class MoveMessages(ObjectTask):
- def __init__(self, app, frame):
- super(MoveMessages, self).__init__(app, frame)
-
- self.form = MoveMessagesForm(app, self.name, self)
-
- def get_title(self, session):
- return "Move messages"
-
- def do_invoke(self, invoc, vhost, src, dst, count):
- self.qmf_call(invoc, vhost, src, dst, count)
-
-class MoveMessagesForm(ObjectTaskForm):
- def __init__(self, app, name, task):
- super(MoveMessagesForm, self).__init__(app, name, task)
-
- self.queue = QueueParameter(app, "queue")
- self.add_parameter(self.queue)
-
- self.dest_queue = QueueSelectField(app, "dest", self)
- self.add_field(self.dest_queue)
-
- self.count = MultiplicityField(app, "count")
- self.add_field(self.count)
-
- def process_submit(self, session):
- self.validate(session)
-
- if not self.errors.get(session):
- queue = self.queue.get(session)
- dest_queue = self.dest_queue.get(session)
- scount = self.count.get(session)
-
- if scount == "all":
- count = 0
- elif scount == "top":
- count = 1
- elif scount == "N":
- count = self.count.top_n.get_n_value(session)
- else:
- raise Exception("Wrong Value")
-
- self.task.invoke(session, queue, dest_queue, count)
- self.task.exit_with_redirect(session)
-
class ModuleNotEnabled(Widget):
def do_render(self, session):
return "This module is not enabled"
@@ -393,3 +348,77 @@
reg = Identifiable(data["id"])
href = self.page.main.messaging.broker.get_href(session, reg)
return fmt_link(href, fmt_shorten(data["name"]))
+
+class BrokerEngroupTaskForm(ObjectTaskForm):
+ def __init__(self, app, name, task):
+ super(BrokerEngroupTaskForm, self).__init__(app, name, task)
+
+ group = NewBrokerGroupParameter(app, "group")
+ self.groups = self.Groups(app, "groups", group)
+ self.add_field(self.groups)
+
+ def do_process(self, session):
+ super(BrokerEngroupTaskForm, self).do_process(session)
+
+ vhost = self.object.get(session)
+
+ cls = self.app.rosemary.com_redhat_cumin.BrokerGroupMapping
+ mappings = cls.get_selection(session.cursor, _broker_id=vhost._brokerRef_id)
+ checked_groups = [x._group_id for x in mappings]
+ self.groups.inputs.set(session, checked_groups)
+
+ def process_submit(self, session):
+ vhost = self.object.get(session)
+ cls = self.app.rosemary.org_apache_qpid_broker.Broker
+ broker = cls.get_object(session.cursor, vhost._brokerRef_id)
+ groups = self.groups.get(session)
+
+ self.task.invoke(session, broker, groups)
+ self.task.exit_with_redirect(session)
+
+ class Groups(CheckboxItemSetField):
+ def render_title(self, session):
+ return "Groups"
+
+ def do_get_items(self, session):
+ cls = self.app.rosemary.com_redhat_cumin.BrokerGroup
+ groups = cls.get_selection(session.cursor)
+ return (FormInputItem(x._id, title=x.name) for x in groups)
+
+class BrokerEngroup(ObjectTask):
+ def __init__(self, app, selector):
+ super(BrokerEngroup, self).__init__(app, selector)
+
+ self.form = BrokerEngroupTaskForm(app, "engroup", self)
+
+ def get_title(self, session):
+ return "Add to groups"
+
+ def do_invoke(self, invoc, broker, groups):
+ conn = self.app.model.get_sql_connection()
+ cursor = conn.cursor()
+
+ cls = self.app.rosemary.com_redhat_cumin.BrokerGroup
+ all_groups = cls.get_selection(cursor)
+ selected_ids = [x._id for x in groups]
+
+ cls = self.app.rosemary.com_redhat_cumin.BrokerGroupMapping
+ try:
+ for group in all_groups:
+ existing_mapping = cls.get_selection(cursor, _broker_id=broker._id, _group_id=group._id)
+ if not group._id in selected_ids:
+ if len(existing_mapping) > 0:
+ existing_mapping[0].delete(cursor)
+ else:
+ if len(existing_mapping) == 0:
+ new_mapping = cls.create_object(cursor)
+ new_mapping._broker_id = broker._id
+ new_mapping._group_id = group._id
+ new_mapping.fake_qmf_values()
+ new_mapping.save(cursor)
+ finally:
+ cursor.close()
+
+ conn.commit()
+
+ invoc.end()
14 years, 8 months
rhmessaging commits: r3936 - mgmt/newdata/cumin/resources.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2010-04-26 16:16:39 -0400 (Mon, 26 Apr 2010)
New Revision: 3936
Modified:
mgmt/newdata/cumin/resources/incrementalSearch.js
Log:
Make the incremental search dropdown the same size as the associated edit field
Modified: mgmt/newdata/cumin/resources/incrementalSearch.js
===================================================================
--- mgmt/newdata/cumin/resources/incrementalSearch.js 2010-04-26 20:16:10 UTC (rev 3935)
+++ mgmt/newdata/cumin/resources/incrementalSearch.js 2010-04-26 20:16:39 UTC (rev 3936)
@@ -37,7 +37,7 @@
p.hide = function(){
var thisObject = this, d = document, s = (thisObject.c && thisObject.c.parentNode.removeChild(thisObject.c),
thisObject.c = d.body.appendChild(d.createElement("div"))).style;
- //thisObject.c.width = thisObject.input.offsetwidth + "px";
+ thisObject.c.style.width = thisObject.input.offsetWidth + "px";
thisObject.l = [], thisObject.i = -1, thisObject.c.className = thisObject.className, s.position = "absolute", s.display = "none";
thisObject._old = null, thisObject.visible && (thisObject._callEvent("onhide"), --thisObject.visible);
};
14 years, 8 months
rhmessaging commits: r3935 - in mgmt/newdata/cumin/python/cumin: grid and 1 other directories.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2010-04-26 16:16:10 -0400 (Mon, 26 Apr 2010)
New Revision: 3935
Modified:
mgmt/newdata/cumin/python/cumin/grid/negotiator.py
mgmt/newdata/cumin/python/cumin/grid/submission.py
mgmt/newdata/cumin/python/cumin/main.py
mgmt/newdata/cumin/python/cumin/messaging/queue.py
mgmt/newdata/cumin/python/cumin/widgets.py
mgmt/newdata/cumin/python/cumin/widgets.strings
Log:
TopQueue, TopSystems, TopSubmissions
Modified: mgmt/newdata/cumin/python/cumin/grid/negotiator.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/negotiator.py 2010-04-26 20:11:31 UTC (rev 3934)
+++ mgmt/newdata/cumin/python/cumin/grid/negotiator.py 2010-04-26 20:16:10 UTC (rev 3935)
@@ -63,7 +63,7 @@
def __init__(self, app, name, getter, negotiator, task):
super(QmfGroupColumn, self).__init__(app, name)
- self.header_class = TopTableColumnHeader
+ self.header_class = ItemTableColumnHeader
self.title = None
self.getter = getter
@@ -125,7 +125,7 @@
self.buttons.add_child(button)
col = self.ExpandColumn(app, "expand_col")
- col.header_class = TopTableColumnHeader
+ col.header_class = ItemTableColumnHeader
self.add_column(col)
col = self.GroupColumn(app, "group")
Modified: mgmt/newdata/cumin/python/cumin/grid/submission.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/submission.py 2010-04-26 20:11:31 UTC (rev 3934)
+++ mgmt/newdata/cumin/python/cumin/grid/submission.py 2010-04-26 20:16:10 UTC (rev 3935)
@@ -256,40 +256,3 @@
class AttributesField(MultilineStringField):
def render_title(self, session):
return "Extra attributes"
-
-class TopSubmissionSet(TopTable):
- def __init__(self, app, name):
- super(TopSubmissionSet, self).__init__(app, name)
-
- col = self.NameColumn(app, "name")
- col.width = "60%"
- self.add_column(col)
-
- self.set_default_column(col)
-
- col = self.DurationColumn(app, "name")
- col.width = "35%"
- col.align = "right"
- self.add_column(col)
-
- class NameColumn(TopTableColumn):
- def render_title(self, session):
- return "Name"
-
- def render_content(self, session, data):
- pool = Identifiable(data["pool"])
- submission = Identifiable(data["id"])
-
- branch = session.branch()
- self.page.main.grid.pool.object.set(session, pool)
- self.page.main.grid.pool.submission.object.set(session, submission)
- self.page.main.grid.pool.submission.show(session)
- return fmt_link(branch.marshal(), data["name"], link_title=data["name"])
-
- class DurationColumn(TopTableColumn):
- def render_title(self, session):
- return "Duration"
-
- def render_content(self, session, data):
- since = data["qmf_create_time"]
- return fmt_duration(time() - secs(since))
Modified: mgmt/newdata/cumin/python/cumin/main.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/main.py 2010-04-26 20:11:31 UTC (rev 3934)
+++ mgmt/newdata/cumin/python/cumin/main.py 2010-04-26 20:16:10 UTC (rev 3935)
@@ -171,6 +171,12 @@
queues = TopQueueTable(app, "queues")
self.add_child(queues)
+ systems = TopSystemTable(app, "systems")
+ self.add_child(systems)
+
+ submissions = TopSubmissionTable(app, "submissions")
+ self.add_child(submissions)
+
# XXX
#queues = messaging.queue.TopQueueSet(app, "queues")
@@ -197,26 +203,6 @@
super(TopQueueAdapter, self).__init__(app, cls.sql_table)
self.cls = cls
- """
-select
- "Queue"."name",
- ((sum("Queue"."msgTotalEnqueues") -
- sum(s."msgTotalEnqueues")) / (count(1)-1)) / 30 as avg_60,
- "Vhost"."_brokerRef_id",
- "Queue"."_id"
-from "org.apache.qpid.broker"."Queue"
-inner join (
- select
- "Queue_samples"."_parent_id",
- "Queue_samples"."msgTotalEnqueues"
- from "org.apache.qpid.broker"."Queue_samples"
- where "Queue_samples"."_qmf_update_time" >= now() - interval '60 seconds') as s on "Queue"."_id" = s._parent_id
-inner join "org.apache.qpid.broker"."Vhost" on "Queue"."_vhostRef_id" = "Vhost"."_id"
-group by "Queue".name, "Queue"._id, "Vhost"."_brokerRef_id" having count(1) > 1
-order by avg_60 desc
-limit 5 offset 0
- """
-
def init(self):
super(TopQueueAdapter, self).init()
@@ -274,7 +260,7 @@
def get_sql_options(self, options):
return options
-class TopQueueTable(DataTable, Form):
+class TopQueueTable(TopTable):
def __init__(self, app, name):
cls = app.rosemary.org_apache_qpid_broker.Queue
adapter = TopQueueAdapter(app, cls)
@@ -288,26 +274,6 @@
cls.msgTotalEnqueues)
self.add_column(col)
- self.header = TopTableHeader(app, "header")
- self.replace_child(self.header)
-
- self.footer = TopTableFooter(app, "footer")
- self.replace_child(self.footer)
-
- self.update_enabled = True
-
- def get_data_options(self, session):
- options = SqlQueryOptions()
-
- options.limit = 5
- options.offset = 0
-
- return options
-
- def get_count(self, session):
- # avoid extra sql call since we don't show the record count
- return 0
-
class MsgEnqueuesColumn(DataTableColumn):
def render_header_content(self, session):
return "Recent Enqueues / sec"
@@ -334,14 +300,62 @@
def render_cell_content(self, session, record):
return record[0]
-class TopTableHeader(TableHeader):
+class TopSystemTable(TopObjectTable):
def __init__(self, app, name):
- super(TopTableHeader, self).__init__(app, name)
+ cls = app.rosemary.com_redhat_sesame.Sysimage
- self.font = Attribute(app, "font")
- self.font.default = 0.9
- self.add_attribute(self.font)
+ super(TopSystemTable, self).__init__(app, name, cls)
-class TopTableFooter(Widget):
- def render(self, session):
- return ""
+ frame = "main.inventory.system"
+ col = ObjectLinkColumn(app, "name", cls.nodeName, cls._id, frame)
+ self.add_column(col)
+
+ self.add_attribute_column(cls.loadAverage1Min)
+ self.sort_col = cls.loadAverage1Min.name
+
+ self.header = TopTableHeader(app, "header")
+ self.replace_child(self.header)
+
+class TopSubmissionTable(TopObjectTable):
+ def __init__(self, app, name):
+ cls = app.rosemary.mrg_grid.Submission
+
+ super(TopSubmissionTable, self).__init__(app, name, cls)
+
+ col = self.NameColumn(app, cls.Name.name, cls.Name, cls._id, None)
+ self.add_column(col)
+
+ col = self.DurationColumn(app, cls._qmf_create_time.name, cls._qmf_create_time)
+ self.add_column(col)
+ self.sort_col = cls._qmf_create_time.name
+
+ running_col = self.adapter.table._columns_by_name["Running"]
+ SqlComparisonFilter(self.adapter.query,
+ running_col, "0", ">")
+
+ update_col = self.adapter.table._columns_by_name["_qmf_update_time"]
+ SqlComparisonFilter(self.adapter.query,
+ update_col, "now() - interval '60 seconds'", ">=")
+
+ class NameColumn(ObjectLinkColumn):
+ def render_cell_href(self, session, record):
+ # XXX fix this when submission has collector ref
+ pool = 1
+ submission = record[0]
+
+ branch = session.branch()
+ self.page.main.grid.pool.id.set(session, pool)
+ self.page.main.grid.pool.submission.id.set(session, submission)
+ self.page.main.grid.pool.submission.view.show(session)
+ return branch.marshal()
+
+ class DurationColumn(ObjectAttributeColumn):
+ def render_header_content(self, session):
+ return "Duration"
+
+ def render_cell_content(self, session, record):
+ created = self.field.get_content(session, record)
+ return fmt_duration(time() - secs(created))
+
+ def render_text_align(self, session):
+ return "right"
Modified: mgmt/newdata/cumin/python/cumin/messaging/queue.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/queue.py 2010-04-26 20:11:31 UTC (rev 3934)
+++ mgmt/newdata/cumin/python/cumin/messaging/queue.py 2010-04-26 20:16:10 UTC (rev 3935)
@@ -44,6 +44,7 @@
self.remove = QueueRemove(app, self)
self.purge = QueuePurge(app, self)
+ self.move_messages = MoveQueueMessages(app, self)
class QueueRemove(ObjectTask):
def get_title(self, session):
@@ -636,47 +637,139 @@
def __init__(self, app, name, form):
super(QueueSelectField, self).__init__(app, name)
- self.queue_set = self.QueueSearchInputSet(app, "queue_set")
- self.add_child(self.queue_set)
+ self.param = self.QueueSearchInputSet(app, "queue_set")
+ self.add_child(self.param)
- self.param = self.QueueStringParameter(app, "param", self.queue_set)
- self.add_parameter(self.param)
-
def get(self, session):
return self.param.get(session)
def render_title(self, session):
- return "Select the destination queue"
+ return "Queue"
def render_inputs(self, session):
- return self.queue_set.render(session)
+ return self.param.render(session)
+ def validate(self, session):
+ if self.required:
+ val = self.get(session)
+ if not val:
+ error = FormError("The %s is required" % self.render_title(session))
+ self.form.errors.add(session, error)
+
class QueueSearchInputSet(IncrementalSearchInput):
def do_get_items(self, session):
- queue = self.form.queue.get(session) # XXX
- queue_list_full = sorted_by(list(queue.vhost.queues))
+ cls = self.app.rosemary.org_apache_qpid_broker.Queue
+ vhost = self.form.get_object(session)
+ vhostid = vhost._id
+ queues = cls.get_selection(session.cursor, _vhostRef_id=vhostid)
+ queue_list_full = sorted_by(list(queues))
delta = timedelta(minutes=10)
queue_list = []
for _queue in queue_list_full:
- if (_queue.qmfUpdateTime > (datetime.now() - delta)) \
- and (_queue.name != queue.name):
+ if _queue._qmf_update_time > (datetime.now() - delta):
queue_list.append(_queue)
return queue_list
def render_item_content(self, session, queue):
return queue.name or "<em>Default</em>"
- class QueueStringParameter(Parameter):
- def __init__(self, app, name, queue_string):
- super(QueueSelectField.QueueStringParameter, self).__init__(app, name)
+class MoveMessagesBase(ObjectTask):
+ def get_title(self, session):
+ return "Move messages"
- self.queue_string = queue_string
+ def do_invoke(self, invoc, vhost, src, dst, count):
+ cls = self.app.rosemary.org_apache_qpid_broker.Broker
+ conn = self.app.model.get_sql_connection()
+ cursor = conn.cursor()
+ try:
+ broker = cls.get_object(cursor, vhost._brokerRef_id)
+ finally:
+ cursor.close()
+ self.qmf_call(invoc, broker, "queueMoveMessages", src, dst, count)
+class MoveQueueMessages(MoveMessagesBase):
+ def __init__(self, app, frame):
+ super(MoveQueueMessages, self).__init__(app, frame)
+
+ self.form = MoveQueueMessagesForm(app, self.name, self)
+
+class MoveMessages(MoveMessagesBase):
+ def __init__(self, app, frame):
+ super(MoveMessages, self).__init__(app, frame)
+
+ self.form = MoveMessagesForm(app, self.name, self)
+
+class MoveMessagesFormBase(ObjectTaskForm):
+ def __init__(self, app, name, task, src_queue):
+ super(MoveMessagesFormBase, self).__init__(app, name, task)
+
+ self.src_queue = src_queue
+ self.add_field(src_queue)
+
+ self.dest_queue = self.QueueDestField(app, "dest", self)
+ self.dest_queue.required = True
+ self.add_field(self.dest_queue)
+
+ self.count = MultiplicityField(app, "count")
+ self.add_field(self.count)
+
+ def process_submit(self, session):
+ self.validate(session)
+
+ if not self.errors.get(session):
+ src_queue = self.src_queue.get(session)
+ dest_queue = self.dest_queue.get(session)
+ object = self.get_object(session)
+ scount = self.count.get(session)
+
+ if scount == "all":
+ count = 0
+ elif scount == "top":
+ count = 1
+ elif scount == "N":
+ count = self.count.top_n.get_n_value(session)
+ else:
+ raise Exception("Wrong Value")
+
+ self.task.invoke(session, object, src_queue, dest_queue, count)
+ self.task.exit_with_redirect(session)
+
+ def get_object(self, session):
+ return self.object.get(session)
+
+ class QueueDestField(QueueSelectField):
+ def render_title(self, session):
+ return "Destination Queue"
+
+class MoveMessagesForm(MoveMessagesFormBase):
+ def __init__(self, app, name, task):
+ src_queue = self.QueueSrctField(app, "src", self)
+ src_queue.required = True
+ super(MoveMessagesForm, self).__init__(app, name, task, src_queue)
+
+ class QueueSrctField(QueueSelectField):
+ def render_title(self, session):
+ return "Source Queue"
+
+class MoveQueueMessagesForm(MoveMessagesFormBase):
+ def __init__(self, app, name, task):
+ src_queue = self.QueueSrcField(app, "src")
+ super(MoveQueueMessagesForm, self).__init__(app, name, task, src_queue)
+
+ def get_object(self, session):
+ # task expects a vhost object
+ queue = self.object.get(session)
+ cls = self.app.rosemary.org_apache_qpid_broker.Vhost
+ vhost = cls.get_object(session.cursor, queue._vhostRef_id)
+ return vhost
+
+ class QueueSrcField(FormField):
+ def render_title(self, session):
+ return "Source Queue"
+
+ def render_inputs(self, session):
+ return self.get(session)
+
def get(self, session):
- queue_string = self.queue_string.get(session)
- queue_where = "name = '%s'" % queue_string
- try:
- return Queue.select(queue_where)[0]
- except IndexError:
- return None
-
+ queue = self.form.object.get(session)
+ return queue.name
Modified: mgmt/newdata/cumin/python/cumin/widgets.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/widgets.py 2010-04-26 20:11:31 UTC (rev 3934)
+++ mgmt/newdata/cumin/python/cumin/widgets.py 2010-04-26 20:16:10 UTC (rev 3935)
@@ -730,41 +730,6 @@
return fmt_link("", title, class_, link_title=hover, bm=bm, click=click)
-class TopTableColumn(SqlTableColumn):
- def __init__(self, app, name):
- super(TopTableColumn, self).__init__(app, name)
-
- self.header_class = TopTableColumnHeader
-
-class TopTableColumnHeader(ItemTableColumnHeader):
- pass
-
-class TopTable(SqlTable):
- def __init__(self, app, name):
- super(TopTable, self).__init__(app, name)
-
- self.html_class = TopTable.__name__
-
- col = self.CountColumn(app, "name")
- col.width = "5%"
- col.align = "right"
- self.add_column(col)
-
- self.update_enabled = True
-
- self.count = Attribute(app, "count")
- self.count.default = 1
- self.add_attribute(self.count)
-
- def get_connection(self, session):
- return self.app.model.get_sql_connection()
-
- class CountColumn(TopTableColumn):
- def render_content(self, session, data):
- count = self.parent.count.get(session)
- self.parent.count.set(session, count + 1)
- return count
-
class CuminItemTable(ItemTable):
def __init__(self, app, name):
super(CuminItemTable, self).__init__(app, name)
@@ -1480,3 +1445,85 @@
def render_item_class(self, session, item):
return "list_item"
+
+class TopTable(DataTable):
+ def __init__(self, app, name, adapter):
+ super(TopTable, self).__init__(app, name, adapter)
+
+ self.header = TopTableHeader(app, "header")
+ self.replace_child(self.header)
+
+ self.footer = TopTableFooter(app, "footer")
+ self.replace_child(self.footer)
+
+ self.update_enabled = True
+
+ def get_count(self, session):
+ # avoid extra sql call since we don't show the record count
+ return 0
+
+ def get_data_options(self, session):
+ options = SqlQueryOptions()
+
+ options.limit = 5
+ options.offset = 0
+
+ return options
+
+class TopObjectTable(ObjectTable):
+ def __init__(self, app, name, cls):
+ super(TopObjectTable, self).__init__(app, name, cls)
+
+ col = ObjectAttributeColumn(app, cls._id.name, cls._id)
+ col.visible = False
+ self.add_column(col)
+
+ self.header = TopTableHeader(app, "header")
+ self.replace_child(self.header)
+
+ self.footer = TopTableFooter(app, "footer")
+ self.replace_child(self.footer)
+
+ self.sort_col = None
+
+ def get_count(self, session):
+ # avoid extra sql call since we don't show the record count
+ return 0
+
+ def get_data_options(self, session):
+ sort_col = self.sort_col or self.cls._id.name
+ self.sort.set(session, sort_col)
+ self.ascending.set(session, False)
+ return super(TopObjectTable, self).get_data_options(session)
+
+class TopTableHeader(TableHeader):
+ def __init__(self, app, name):
+ super(TopTableHeader, self).__init__(app, name)
+
+ self.font = Attribute(app, "font")
+ self.font.default = 0.9
+ self.add_attribute(self.font)
+
+ self.limit = Attribute(app, "limit")
+ self.limit.default = 5
+ self.add_attribute(self.limit)
+
+ self.offset = Attribute(app, "offset")
+ self.offset.default = 0
+ self.add_attribute(self.offset)
+
+ def init(self):
+ super(TopTableHeader, self).init()
+
+ for column in self.table.columns:
+ column.header = TopTableColumnHeader(self.app, "header")
+ column.replace_child(column.header)
+ column.header.init()
+
+class TopTableColumnHeader(TableColumnHeader):
+ def render_class(self, session):
+ return self.parent.name
+
+class TopTableFooter(Widget):
+ def render(self, session):
+ return ""
Modified: mgmt/newdata/cumin/python/cumin/widgets.strings
===================================================================
--- mgmt/newdata/cumin/python/cumin/widgets.strings 2010-04-26 20:11:31 UTC (rev 3934)
+++ mgmt/newdata/cumin/python/cumin/widgets.strings 2010-04-26 20:16:10 UTC (rev 3935)
@@ -465,47 +465,8 @@
[EditablePropertyRenderer.orig_html]
<input type="hidden" name="{porig_name}" value="{porig_value}"/>
-[TopTable.css]
-table.TopTable {
- width: 100%;
- border-collapse: collapse;
- margin: 0;
- table-layout: fixed;
-}
-
-table.TopTable tr {
- border-top: 1px dotted #ccc;
- vertical-align: top;
-}
-
-table.TopTable td {
- padding: 0.35em 0.5em;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-table.TopTable th {
- padding: 0.35em 0.5em;
- text-align: left;
- font-weight: normal;
- font-style: italic;
- color: #444;
- font-size: 0.9em;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-[TopTable.html]
-<table id="{id}" class="{class}">
- {columns}
- <thead><tr>{headers}</tr></thead>
- <tbody>{items}</tbody>
-</table>
-
[TopTableColumnHeader.html]
-<th {attrs}>{content}</th>
+<th class="{class}">{content}</th>
[CuminTable.css]
div.CuminTable table,
14 years, 8 months